• 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.ByteArrayOutputStream;
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileNotFoundException;
23 import java.io.FileOutputStream;
24 import java.io.FileWriter;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.regex.Pattern;
28 import java.util.zip.CRC32;
29 import java.util.zip.CheckedInputStream;
30 
31 import libcore.io.Os;
32 import libcore.io.StructStat;
33 
34 /**
35  * Tools for managing files.  Not for public consumption.
36  * @hide
37  */
38 public class FileUtils {
39     public static final int S_IRWXU = 00700;
40     public static final int S_IRUSR = 00400;
41     public static final int S_IWUSR = 00200;
42     public static final int S_IXUSR = 00100;
43 
44     public static final int S_IRWXG = 00070;
45     public static final int S_IRGRP = 00040;
46     public static final int S_IWGRP = 00020;
47     public static final int S_IXGRP = 00010;
48 
49     public static final int S_IRWXO = 00007;
50     public static final int S_IROTH = 00004;
51     public static final int S_IWOTH = 00002;
52     public static final int S_IXOTH = 00001;
53 
54 
55     /**
56      * File status information. This class maps directly to the POSIX stat structure.
57      * @deprecated use {@link StructStat} instead.
58      * @hide
59      */
60     @Deprecated
61     public static final class FileStatus {
62         public int dev;
63         public int ino;
64         public int mode;
65         public int nlink;
66         public int uid;
67         public int gid;
68         public int rdev;
69         public long size;
70         public int blksize;
71         public long blocks;
72         public long atime;
73         public long mtime;
74         public long ctime;
75     }
76 
77     /**
78      * Get the status for the given path. This is equivalent to the POSIX stat(2) system call.
79      * @param path The path of the file to be stat'd.
80      * @param status Optional argument to fill in. It will only fill in the status if the file
81      * exists.
82      * @return true if the file exists and false if it does not exist. If you do not have
83      * permission to stat the file, then this method will return false.
84      * @deprecated use {@link Os#stat(String)} instead.
85      */
86     @Deprecated
getFileStatus(String path, FileStatus status)87     public static boolean getFileStatus(String path, FileStatus status) {
88         StrictMode.noteDiskRead();
89         return getFileStatusNative(path, status);
90     }
91 
getFileStatusNative(String path, FileStatus status)92     private static native boolean getFileStatusNative(String path, FileStatus status);
93 
94     /** Regular expression for safe filenames: no spaces or metacharacters */
95     private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
96 
setPermissions(String file, int mode, int uid, int gid)97     public static native int setPermissions(String file, int mode, int uid, int gid);
98 
99     /**
100      * @deprecated use {@link Os#stat(String)} instead.
101      */
102     @Deprecated
getPermissions(String file, int[] outPermissions)103     public static native int getPermissions(String file, int[] outPermissions);
104 
setUMask(int mask)105     public static native int setUMask(int mask);
106 
107     /** returns the FAT file system volume ID for the volume mounted
108      * at the given mount point, or -1 for failure
109      * @param mountPoint point for FAT volume
110      * @return volume ID or -1
111      */
getFatVolumeId(String mountPoint)112     public static native int getFatVolumeId(String mountPoint);
113 
114     /**
115      * Perform an fsync on the given FileOutputStream.  The stream at this
116      * point must be flushed but not yet closed.
117      */
sync(FileOutputStream stream)118     public static boolean sync(FileOutputStream stream) {
119         try {
120             if (stream != null) {
121                 stream.getFD().sync();
122             }
123             return true;
124         } catch (IOException e) {
125         }
126         return false;
127     }
128 
129     // copy a file from srcFile to destFile, return true if succeed, return
130     // false if fail
copyFile(File srcFile, File destFile)131     public static boolean copyFile(File srcFile, File destFile) {
132         boolean result = false;
133         try {
134             InputStream in = new FileInputStream(srcFile);
135             try {
136                 result = copyToFile(in, destFile);
137             } finally  {
138                 in.close();
139             }
140         } catch (IOException e) {
141             result = false;
142         }
143         return result;
144     }
145 
146     /**
147      * Copy data from a source stream to destFile.
148      * Return true if succeed, return false if failed.
149      */
copyToFile(InputStream inputStream, File destFile)150     public static boolean copyToFile(InputStream inputStream, File destFile) {
151         try {
152             if (destFile.exists()) {
153                 destFile.delete();
154             }
155             FileOutputStream out = new FileOutputStream(destFile);
156             try {
157                 byte[] buffer = new byte[4096];
158                 int bytesRead;
159                 while ((bytesRead = inputStream.read(buffer)) >= 0) {
160                     out.write(buffer, 0, bytesRead);
161                 }
162             } finally {
163                 out.flush();
164                 try {
165                     out.getFD().sync();
166                 } catch (IOException e) {
167                 }
168                 out.close();
169             }
170             return true;
171         } catch (IOException e) {
172             return false;
173         }
174     }
175 
176     /**
177      * Check if a filename is "safe" (no metacharacters or spaces).
178      * @param file  The file to check
179      */
isFilenameSafe(File file)180     public static boolean isFilenameSafe(File file) {
181         // Note, we check whether it matches what's known to be safe,
182         // rather than what's known to be unsafe.  Non-ASCII, control
183         // characters, etc. are all unsafe by default.
184         return SAFE_FILENAME_PATTERN.matcher(file.getPath()).matches();
185     }
186 
187     /**
188      * Read a text file into a String, optionally limiting the length.
189      * @param file to read (will not seek, so things like /proc files are OK)
190      * @param max length (positive for head, negative of tail, 0 for no limit)
191      * @param ellipsis to add of the file was truncated (can be null)
192      * @return the contents of the file, possibly truncated
193      * @throws IOException if something goes wrong reading the file
194      */
readTextFile(File file, int max, String ellipsis)195     public static String readTextFile(File file, int max, String ellipsis) throws IOException {
196         InputStream input = new FileInputStream(file);
197         try {
198             long size = file.length();
199             if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
200                 if (size > 0 && (max == 0 || size < max)) max = (int) size;
201                 byte[] data = new byte[max + 1];
202                 int length = input.read(data);
203                 if (length <= 0) return "";
204                 if (length <= max) return new String(data, 0, length);
205                 if (ellipsis == null) return new String(data, 0, max);
206                 return new String(data, 0, max) + ellipsis;
207             } else if (max < 0) {  // "tail" mode: keep the last N
208                 int len;
209                 boolean rolled = false;
210                 byte[] last = null, data = null;
211                 do {
212                     if (last != null) rolled = true;
213                     byte[] tmp = last; last = data; data = tmp;
214                     if (data == null) data = new byte[-max];
215                     len = input.read(data);
216                 } while (len == data.length);
217 
218                 if (last == null && len <= 0) return "";
219                 if (last == null) return new String(data, 0, len);
220                 if (len > 0) {
221                     rolled = true;
222                     System.arraycopy(last, len, last, 0, last.length - len);
223                     System.arraycopy(data, 0, last, last.length - len, len);
224                 }
225                 if (ellipsis == null || !rolled) return new String(last);
226                 return ellipsis + new String(last);
227             } else {  // "cat" mode: size unknown, read it all in streaming fashion
228                 ByteArrayOutputStream contents = new ByteArrayOutputStream();
229                 int len;
230                 byte[] data = new byte[1024];
231                 do {
232                     len = input.read(data);
233                     if (len > 0) contents.write(data, 0, len);
234                 } while (len == data.length);
235                 return contents.toString();
236             }
237         } finally {
238             input.close();
239         }
240     }
241 
242    /**
243      * Writes string to file. Basically same as "echo -n $string > $filename"
244      *
245      * @param filename
246      * @param string
247      * @throws IOException
248      */
stringToFile(String filename, String string)249     public static void stringToFile(String filename, String string) throws IOException {
250         FileWriter out = new FileWriter(filename);
251         try {
252             out.write(string);
253         } finally {
254             out.close();
255         }
256     }
257 
258     /**
259      * Computes the checksum of a file using the CRC32 checksum routine.
260      * The value of the checksum is returned.
261      *
262      * @param file  the file to checksum, must not be null
263      * @return the checksum value or an exception is thrown.
264      */
checksumCrc32(File file)265     public static long checksumCrc32(File file) throws FileNotFoundException, IOException {
266         CRC32 checkSummer = new CRC32();
267         CheckedInputStream cis = null;
268 
269         try {
270             cis = new CheckedInputStream( new FileInputStream(file), checkSummer);
271             byte[] buf = new byte[128];
272             while(cis.read(buf) >= 0) {
273                 // Just read for checksum to get calculated.
274             }
275             return checkSummer.getValue();
276         } finally {
277             if (cis != null) {
278                 try {
279                     cis.close();
280                 } catch (IOException e) {
281                 }
282             }
283         }
284     }
285 }
286