FileUtils.java revision 053f61d6a6e23825e680dc49982e55c5b4299d61
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkeyimport android.util.Log; 20d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 2190619816d99154d504a14774c6f2d5f4254ff780Guang Zhuimport java.io.BufferedInputStream; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayOutputStream; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 256d25a990afffd5eb385aba3043d5dfad36f1539aWink Savilleimport java.io.FileNotFoundException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream; 27da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwoodimport java.io.FileWriter; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 30d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkeyimport java.util.Arrays; 31d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkeyimport java.util.Comparator; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern; 336d25a990afffd5eb385aba3043d5dfad36f1539aWink Savilleimport java.util.zip.CRC32; 346d25a990afffd5eb385aba3043d5dfad36f1539aWink Savilleimport java.util.zip.CheckedInputStream; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Tools for managing files. Not for public consumption. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 406d25a990afffd5eb385aba3043d5dfad36f1539aWink Savillepublic class FileUtils { 41d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey private static final String TAG = "FileUtils"; 42d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IRWXU = 00700; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IRUSR = 00400; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IWUSR = 00200; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IXUSR = 00100; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IRWXG = 00070; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IRGRP = 00040; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IWGRP = 00020; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IXGRP = 00010; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IRWXO = 00007; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IROTH = 00004; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IWOTH = 00002; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int S_IXOTH = 00001; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Regular expression for safe filenames: no spaces or metacharacters */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int setPermissions(String file, int mode, int uid, int gid); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63053f61d6a6e23825e680dc49982e55c5b4299d61Dianne Hackborn public static native int getUid(String file); 64053f61d6a6e23825e680dc49982e55c5b4299d61Dianne Hackborn 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** returns the FAT file system volume ID for the volume mounted 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at the given mount point, or -1 for failure 676d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville * @param mountPoint point for FAT volume 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return volume ID or -1 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int getFatVolumeId(String mountPoint); 718bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn 728bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn /** 738bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn * Perform an fsync on the given FileOutputStream. The stream at this 748bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn * point must be flushed but not yet closed. 758bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn */ 768bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn public static boolean sync(FileOutputStream stream) { 778bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn try { 788bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn if (stream != null) { 798bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn stream.getFD().sync(); 808bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn } 818bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn return true; 828bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn } catch (IOException e) { 838bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn } 848bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn return false; 858bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn } 868bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // copy a file from srcFile to destFile, return true if succeed, return 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // false if fail 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean copyFile(File srcFile, File destFile) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream in = new FileInputStream(srcFile); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = copyToFile(in, destFile); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.close(); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = false; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10390619816d99154d504a14774c6f2d5f4254ff780Guang Zhu 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copy data from a source stream to destFile. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return true if succeed, return false if failed. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean copyToFile(InputStream inputStream, File destFile) { 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1101afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn if (destFile.exists()) { 1111afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn destFile.delete(); 1121afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn } 1138bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn FileOutputStream out = new FileOutputStream(destFile); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] buffer = new byte[4096]; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bytesRead; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((bytesRead = inputStream.read(buffer)) >= 0) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.write(buffer, 0, bytesRead); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1218bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn out.flush(); 1228bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn try { 1238bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn out.getFD().sync(); 1248bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn } catch (IOException e) { 1258bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.close(); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check if a filename is "safe" (no metacharacters or spaces). 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param file The file to check 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isFilenameSafe(File file) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note, we check whether it matches what's known to be safe, 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // rather than what's known to be unsafe. Non-ASCII, control 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // characters, etc. are all unsafe by default. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SAFE_FILENAME_PATTERN.matcher(file.getPath()).matches(); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read a text file into a String, optionally limiting the length. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param file to read (will not seek, so things like /proc files are OK) 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param max length (positive for head, negative of tail, 0 for no limit) 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param ellipsis to add of the file was truncated (can be null) 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the contents of the file, possibly truncated 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException if something goes wrong reading the file 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String readTextFile(File file, int max, String ellipsis) throws IOException { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream input = new FileInputStream(file); 15590619816d99154d504a14774c6f2d5f4254ff780Guang Zhu // wrapping a BufferedInputStream around it because when reading /proc with unbuffered 15690619816d99154d504a14774c6f2d5f4254ff780Guang Zhu // input stream, bytes read not equal to buffer size is not necessarily the correct 15790619816d99154d504a14774c6f2d5f4254ff780Guang Zhu // indication for EOF; but it is true for BufferedInputStream due to its implementation. 15890619816d99154d504a14774c6f2d5f4254ff780Guang Zhu BufferedInputStream bis = new BufferedInputStream(input); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 16042471dd5552a346dd82a58a663159875ccc4fb79Dan Egnor long size = file.length(); 16142471dd5552a346dd82a58a663159875ccc4fb79Dan Egnor if (max > 0 || (size > 0 && max == 0)) { // "head" mode: read the first N bytes 16242471dd5552a346dd82a58a663159875ccc4fb79Dan Egnor if (size > 0 && (max == 0 || size < max)) max = (int) size; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = new byte[max + 1]; 16490619816d99154d504a14774c6f2d5f4254ff780Guang Zhu int length = bis.read(data); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length <= 0) return ""; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length <= max) return new String(data, 0, length); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ellipsis == null) return new String(data, 0, max); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new String(data, 0, max) + ellipsis; 16942471dd5552a346dd82a58a663159875ccc4fb79Dan Egnor } else if (max < 0) { // "tail" mode: keep the last N 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean rolled = false; 172d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey byte[] last = null; 173d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey byte[] data = null; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (last != null) rolled = true; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] tmp = last; last = data; data = tmp; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data == null) data = new byte[-max]; 17890619816d99154d504a14774c6f2d5f4254ff780Guang Zhu len = bis.read(data); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (len == data.length); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (last == null && len <= 0) return ""; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (last == null) return new String(data, 0, len); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rolled = true; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(last, len, last, 0, last.length - len); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(data, 0, last, last.length - len, len); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ellipsis == null || !rolled) return new String(last); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ellipsis + new String(last); 19042471dd5552a346dd82a58a663159875ccc4fb79Dan Egnor } else { // "cat" mode: size unknown, read it all in streaming fashion 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteArrayOutputStream contents = new ByteArrayOutputStream(); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = new byte[1024]; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 19590619816d99154d504a14774c6f2d5f4254ff780Guang Zhu len = bis.read(data); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len > 0) contents.write(data, 0, len); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (len == data.length); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return contents.toString(); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 20190619816d99154d504a14774c6f2d5f4254ff780Guang Zhu bis.close(); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project input.close(); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 205da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood 206da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood /** 207da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood * Writes string to file. Basically same as "echo -n $string > $filename" 208da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood * 209da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood * @param filename 210da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood * @param string 211da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood * @throws IOException 212da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood */ 213da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood public static void stringToFile(String filename, String string) throws IOException { 214da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood FileWriter out = new FileWriter(filename); 215da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood try { 216da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood out.write(string); 217da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood } finally { 218da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood out.close(); 219da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood } 220da8bb74b9d9ffcb095815db800d0816c411f1fbaMike Lockwood } 2211b9a6a6e58fd73b5d1b6a434d17f0a69806858ecWink Saville 2226d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville /** 2236d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville * Computes the checksum of a file using the CRC32 checksum routine. 2246d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville * The value of the checksum is returned. 2256d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville * 2266d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville * @param file the file to checksum, must not be null 2276d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville * @return the checksum value or an exception is thrown. 2286d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville */ 2296d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville public static long checksumCrc32(File file) throws FileNotFoundException, IOException { 2306d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville CRC32 checkSummer = new CRC32(); 2316d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville CheckedInputStream cis = null; 2326d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville 2336d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville try { 2346d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville cis = new CheckedInputStream( new FileInputStream(file), checkSummer); 2356d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville byte[] buf = new byte[128]; 2366d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville while(cis.read(buf) >= 0) { 2376d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville // Just read for checksum to get calculated. 2386d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } 2396d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville return checkSummer.getValue(); 2406d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } finally { 2416d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville if (cis != null) { 2426d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville try { 2436d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville cis.close(); 2446d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } catch (IOException e) { 2456d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } 2466d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } 2476d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } 2486d25a990afffd5eb385aba3043d5dfad36f1539aWink Saville } 249d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 250d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey /** 251d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey * Delete older files in a directory until only those matching the given 252d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey * constraints remain. 253d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey * 254d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey * @param minCount Always keep at least this many files. 255d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey * @param minAge Always keep files younger than this age. 256d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey */ 257d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey public static void deleteOlderFiles(File dir, int minCount, long minAge) { 258d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey if (minCount < 0 || minAge < 0) { 259d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey throw new IllegalArgumentException("Constraints must be positive or 0"); 260d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey } 261d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 262d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey final File[] files = dir.listFiles(); 263d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey if (files == null) return; 264d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 265d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey // Sort with newest files first 266d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey Arrays.sort(files, new Comparator<File>() { 267d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey @Override 268d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey public int compare(File lhs, File rhs) { 269d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey return (int) (rhs.lastModified() - lhs.lastModified()); 270d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey } 271d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey }); 272d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 273d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey // Keep at least minCount files 274d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey for (int i = minCount; i < files.length; i++) { 275d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey final File file = files[i]; 276d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey 277d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey // Keep files newer than minAge 278d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey final long age = System.currentTimeMillis() - file.lastModified(); 279d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey if (age > minAge) { 280d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey Log.d(TAG, "Deleting old file " + file); 281d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey file.delete(); 282d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey } 283d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey } 284d9526907d1a51ef0b35bfbbeee43fa209d8b5bbfJeff Sharkey } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 286