• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import java.io.BufferedInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.regex.Pattern;
29 import java.util.zip.CRC32;
30 import java.util.zip.CheckedInputStream;
31 
32 /**
33  * Tools for managing files.  Not for public consumption.
34  * @hide
35  */
36 public class FileUtils {
37     public static final int S_IRWXU = 00700;
38     public static final int S_IRUSR = 00400;
39     public static final int S_IWUSR = 00200;
40     public static final int S_IXUSR = 00100;
41 
42     public static final int S_IRWXG = 00070;
43     public static final int S_IRGRP = 00040;
44     public static final int S_IWGRP = 00020;
45     public static final int S_IXGRP = 00010;
46 
47     public static final int S_IRWXO = 00007;
48     public static final int S_IROTH = 00004;
49     public static final int S_IWOTH = 00002;
50     public static final int S_IXOTH = 00001;
51 
52     /** Regular expression for safe filenames: no spaces or metacharacters */
53     private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
54 
setPermissions(String file, int mode, int uid, int gid)55     public static native int setPermissions(String file, int mode, int uid, int gid);
56 
57     /** returns the FAT file system volume ID for the volume mounted
58      * at the given mount point, or -1 for failure
59      * @param mountPoint point for FAT volume
60      * @return volume ID or -1
61      */
getFatVolumeId(String mountPoint)62     public static native int getFatVolumeId(String mountPoint);
63 
64     /**
65      * Perform an fsync on the given FileOutputStream.  The stream at this
66      * point must be flushed but not yet closed.
67      */
sync(FileOutputStream stream)68     public static boolean sync(FileOutputStream stream) {
69         try {
70             if (stream != null) {
71                 stream.getFD().sync();
72             }
73             return true;
74         } catch (IOException e) {
75         }
76         return false;
77     }
78 
79     // copy a file from srcFile to destFile, return true if succeed, return
80     // false if fail
copyFile(File srcFile, File destFile)81     public static boolean copyFile(File srcFile, File destFile) {
82         boolean result = false;
83         try {
84             InputStream in = new FileInputStream(srcFile);
85             try {
86                 result = copyToFile(in, destFile);
87             } finally  {
88                 in.close();
89             }
90         } catch (IOException e) {
91             result = false;
92         }
93         return result;
94     }
95 
96     /**
97      * Copy data from a source stream to destFile.
98      * Return true if succeed, return false if failed.
99      */
copyToFile(InputStream inputStream, File destFile)100     public static boolean copyToFile(InputStream inputStream, File destFile) {
101         try {
102             if (destFile.exists()) {
103                 destFile.delete();
104             }
105             FileOutputStream out = new FileOutputStream(destFile);
106             try {
107                 byte[] buffer = new byte[4096];
108                 int bytesRead;
109                 while ((bytesRead = inputStream.read(buffer)) >= 0) {
110                     out.write(buffer, 0, bytesRead);
111                 }
112             } finally {
113                 out.flush();
114                 try {
115                     out.getFD().sync();
116                 } catch (IOException e) {
117                 }
118                 out.close();
119             }
120             return true;
121         } catch (IOException e) {
122             return false;
123         }
124     }
125 
126     /**
127      * Check if a filename is "safe" (no metacharacters or spaces).
128      * @param file  The file to check
129      */
isFilenameSafe(File file)130     public static boolean isFilenameSafe(File file) {
131         // Note, we check whether it matches what's known to be safe,
132         // rather than what's known to be unsafe.  Non-ASCII, control
133         // characters, etc. are all unsafe by default.
134         return SAFE_FILENAME_PATTERN.matcher(file.getPath()).matches();
135     }
136 
137     /**
138      * Read a text file into a String, optionally limiting the length.
139      * @param file to read (will not seek, so things like /proc files are OK)
140      * @param max length (positive for head, negative of tail, 0 for no limit)
141      * @param ellipsis to add of the file was truncated (can be null)
142      * @return the contents of the file, possibly truncated
143      * @throws IOException if something goes wrong reading the file
144      */
readTextFile(File file, int max, String ellipsis)145     public static String readTextFile(File file, int max, String ellipsis) throws IOException {
146         InputStream input = new FileInputStream(file);
147         // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
148         // input stream, bytes read not equal to buffer size is not necessarily the correct
149         // indication for EOF; but it is true for BufferedInputStream due to its implementation.
150         BufferedInputStream bis = new BufferedInputStream(input);
151         try {
152             long size = file.length();
153             if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
154                 if (size > 0 && (max == 0 || size < max)) max = (int) size;
155                 byte[] data = new byte[max + 1];
156                 int length = bis.read(data);
157                 if (length <= 0) return "";
158                 if (length <= max) return new String(data, 0, length);
159                 if (ellipsis == null) return new String(data, 0, max);
160                 return new String(data, 0, max) + ellipsis;
161             } else if (max < 0) {  // "tail" mode: keep the last N
162                 int len;
163                 boolean rolled = false;
164                 byte[] last = null, data = null;
165                 do {
166                     if (last != null) rolled = true;
167                     byte[] tmp = last; last = data; data = tmp;
168                     if (data == null) data = new byte[-max];
169                     len = bis.read(data);
170                 } while (len == data.length);
171 
172                 if (last == null && len <= 0) return "";
173                 if (last == null) return new String(data, 0, len);
174                 if (len > 0) {
175                     rolled = true;
176                     System.arraycopy(last, len, last, 0, last.length - len);
177                     System.arraycopy(data, 0, last, last.length - len, len);
178                 }
179                 if (ellipsis == null || !rolled) return new String(last);
180                 return ellipsis + new String(last);
181             } else {  // "cat" mode: size unknown, read it all in streaming fashion
182                 ByteArrayOutputStream contents = new ByteArrayOutputStream();
183                 int len;
184                 byte[] data = new byte[1024];
185                 do {
186                     len = bis.read(data);
187                     if (len > 0) contents.write(data, 0, len);
188                 } while (len == data.length);
189                 return contents.toString();
190             }
191         } finally {
192             bis.close();
193             input.close();
194         }
195     }
196 
197    /**
198      * Writes string to file. Basically same as "echo -n $string > $filename"
199      *
200      * @param filename
201      * @param string
202      * @throws IOException
203      */
stringToFile(String filename, String string)204     public static void stringToFile(String filename, String string) throws IOException {
205         FileWriter out = new FileWriter(filename);
206         try {
207             out.write(string);
208         } finally {
209             out.close();
210         }
211     }
212 
213     /**
214      * Computes the checksum of a file using the CRC32 checksum routine.
215      * The value of the checksum is returned.
216      *
217      * @param file  the file to checksum, must not be null
218      * @return the checksum value or an exception is thrown.
219      */
checksumCrc32(File file)220     public static long checksumCrc32(File file) throws FileNotFoundException, IOException {
221         CRC32 checkSummer = new CRC32();
222         CheckedInputStream cis = null;
223 
224         try {
225             cis = new CheckedInputStream( new FileInputStream(file), checkSummer);
226             byte[] buf = new byte[128];
227             while(cis.read(buf) >= 0) {
228                 // Just read for checksum to get calculated.
229             }
230             return checkSummer.getValue();
231         } finally {
232             if (cis != null) {
233                 try {
234                     cis.close();
235                 } catch (IOException e) {
236                 }
237             }
238         }
239     }
240 }
241