Home | History | Annotate | Download | only in os
      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
     87     public static boolean getFileStatus(String path, FileStatus status) {
     88         StrictMode.noteDiskRead();
     89         return getFileStatusNative(path, status);
     90     }
     91 
     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 
     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
    103     public static native int getPermissions(String file, int[] outPermissions);
    104 
    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      */
    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      */
    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
    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      */
    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      */
    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      */
    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      */
    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      */
    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