FileDocCategorySizeDatePackage
FileUtils.javaAPI DocAndroid 5.1 API17568Thu Mar 12 22:22:10 GMT 2015android.os

FileUtils

public class FileUtils extends Object
Tools for managing files. Not for public consumption.
hide

Fields Summary
private static final String
TAG
public static final int
S_IRWXU
public static final int
S_IRUSR
public static final int
S_IWUSR
public static final int
S_IXUSR
public static final int
S_IRWXG
public static final int
S_IRGRP
public static final int
S_IWGRP
public static final int
S_IXGRP
public static final int
S_IRWXO
public static final int
S_IROTH
public static final int
S_IWOTH
public static final int
S_IXOTH
private static final Pattern
SAFE_FILENAME_PATTERN
Regular expression for safe filenames: no spaces or metacharacters
Constructors Summary
Methods Summary
public static java.lang.StringbuildValidExtFilename(java.lang.String name)
Mutate the given filename to make it valid for an ext4 filesystem, replacing any invalid characters with "_".

        if (TextUtils.isEmpty(name) || ".".equals(name) || "..".equals(name)) {
            return "(invalid)";
        }
        final StringBuilder res = new StringBuilder(name.length());
        for (int i = 0; i < name.length(); i++) {
            final char c = name.charAt(i);
            if (isValidExtFilenameChar(c)) {
                res.append(c);
            } else {
                res.append('_");
            }
        }
        return res.toString();
    
public static java.lang.StringbuildValidFatFilename(java.lang.String name)
Mutate the given filename to make it valid for a FAT filesystem, replacing any invalid characters with "_".

        if (TextUtils.isEmpty(name) || ".".equals(name) || "..".equals(name)) {
            return "(invalid)";
        }
        final StringBuilder res = new StringBuilder(name.length());
        for (int i = 0; i < name.length(); i++) {
            final char c = name.charAt(i);
            if (isValidFatFilenameChar(c)) {
                res.append(c);
            } else {
                res.append('_");
            }
        }
        return res.toString();
    
public static longchecksumCrc32(java.io.File file)
Computes the checksum of a file using the CRC32 checksum routine. The value of the checksum is returned.

param
file the file to checksum, must not be null
return
the checksum value or an exception is thrown.

        CRC32 checkSummer = new CRC32();
        CheckedInputStream cis = null;

        try {
            cis = new CheckedInputStream( new FileInputStream(file), checkSummer);
            byte[] buf = new byte[128];
            while(cis.read(buf) >= 0) {
                // Just read for checksum to get calculated.
            }
            return checkSummer.getValue();
        } finally {
            if (cis != null) {
                try {
                    cis.close();
                } catch (IOException e) {
                }
            }
        }
    
public static booleancontains(java.io.File dir, java.io.File file)
Test if a file lives under the given directory, either as a direct child or a distant grandchild.

Both files must have been resolved using {@link File#getCanonicalFile()} to avoid symlink or path traversal attacks.

        if (file == null) return false;

        String dirPath = dir.getAbsolutePath();
        String filePath = file.getAbsolutePath();

        if (dirPath.equals(filePath)) {
            return true;
        }

        if (!dirPath.endsWith("/")) {
            dirPath += "/";
        }
        return filePath.startsWith(dirPath);
    
public static booleancopyFile(java.io.File srcFile, java.io.File destFile)

        boolean result = false;
        try {
            InputStream in = new FileInputStream(srcFile);
            try {
                result = copyToFile(in, destFile);
            } finally  {
                in.close();
            }
        } catch (IOException e) {
            result = false;
        }
        return result;
    
public static booleancopyToFile(java.io.InputStream inputStream, java.io.File destFile)
Copy data from a source stream to destFile. Return true if succeed, return false if failed.

        try {
            if (destFile.exists()) {
                destFile.delete();
            }
            FileOutputStream out = new FileOutputStream(destFile);
            try {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) >= 0) {
                    out.write(buffer, 0, bytesRead);
                }
            } finally {
                out.flush();
                try {
                    out.getFD().sync();
                } catch (IOException e) {
                }
                out.close();
            }
            return true;
        } catch (IOException e) {
            return false;
        }
    
public static booleandeleteContents(java.io.File dir)

        File[] files = dir.listFiles();
        boolean success = true;
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    success &= deleteContents(file);
                }
                if (!file.delete()) {
                    Log.w(TAG, "Failed to delete " + file);
                    success = false;
                }
            }
        }
        return success;
    
public static booleandeleteOlderFiles(java.io.File dir, int minCount, long minAge)
Delete older files in a directory until only those matching the given constraints remain.

param
minCount Always keep at least this many files.
param
minAge Always keep files younger than this age.
return
if any files were deleted.

        if (minCount < 0 || minAge < 0) {
            throw new IllegalArgumentException("Constraints must be positive or 0");
        }

        final File[] files = dir.listFiles();
        if (files == null) return false;

        // Sort with newest files first
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File lhs, File rhs) {
                return (int) (rhs.lastModified() - lhs.lastModified());
            }
        });

        // Keep at least minCount files
        boolean deleted = false;
        for (int i = minCount; i < files.length; i++) {
            final File file = files[i];

            // Keep files newer than minAge
            final long age = System.currentTimeMillis() - file.lastModified();
            if (age > minAge) {
                if (file.delete()) {
                    Log.d(TAG, "Deleted old file " + file);
                    deleted = true;
                }
            }
        }
        return deleted;
    
public static intgetUid(java.lang.String path)
Return owning UID of given path, otherwise -1.

        try {
            return Os.stat(path).st_uid;
        } catch (ErrnoException e) {
            return -1;
        }
    
public static booleanisFilenameSafe(java.io.File file)
Check if a filename is "safe" (no metacharacters or spaces).

param
file The file to check

        // Note, we check whether it matches what's known to be safe,
        // rather than what's known to be unsafe.  Non-ASCII, control
        // characters, etc. are all unsafe by default.
        return SAFE_FILENAME_PATTERN.matcher(file.getPath()).matches();
    
public static booleanisValidExtFilename(java.lang.String name)
Check if given filename is valid for an ext4 filesystem.

        return (name != null) && name.equals(buildValidExtFilename(name));
    
private static booleanisValidExtFilenameChar(char c)

        switch (c) {
            case '\0":
            case '/":
                return false;
            default:
                return true;
        }
    
public static booleanisValidFatFilename(java.lang.String name)
Check if given filename is valid for a FAT filesystem.

        return (name != null) && name.equals(buildValidFatFilename(name));
    
private static booleanisValidFatFilenameChar(char c)

        if ((0x00 <= c && c <= 0x1f)) {
            return false;
        }
        switch (c) {
            case '"":
            case '*":
            case '/":
            case ':":
            case '<":
            case '>":
            case '?":
            case '\\":
            case '|":
            case 0x7F:
                return false;
            default:
                return true;
        }
    
public static java.lang.StringreadTextFile(java.io.File file, int max, java.lang.String ellipsis)
Read a text file into a String, optionally limiting the length.

param
file to read (will not seek, so things like /proc files are OK)
param
max length (positive for head, negative of tail, 0 for no limit)
param
ellipsis to add of the file was truncated (can be null)
return
the contents of the file, possibly truncated
throws
IOException if something goes wrong reading the file

        InputStream input = new FileInputStream(file);
        // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
        // input stream, bytes read not equal to buffer size is not necessarily the correct
        // indication for EOF; but it is true for BufferedInputStream due to its implementation.
        BufferedInputStream bis = new BufferedInputStream(input);
        try {
            long size = file.length();
            if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
                if (size > 0 && (max == 0 || size < max)) max = (int) size;
                byte[] data = new byte[max + 1];
                int length = bis.read(data);
                if (length <= 0) return "";
                if (length <= max) return new String(data, 0, length);
                if (ellipsis == null) return new String(data, 0, max);
                return new String(data, 0, max) + ellipsis;
            } else if (max < 0) {  // "tail" mode: keep the last N
                int len;
                boolean rolled = false;
                byte[] last = null;
                byte[] data = null;
                do {
                    if (last != null) rolled = true;
                    byte[] tmp = last; last = data; data = tmp;
                    if (data == null) data = new byte[-max];
                    len = bis.read(data);
                } while (len == data.length);

                if (last == null && len <= 0) return "";
                if (last == null) return new String(data, 0, len);
                if (len > 0) {
                    rolled = true;
                    System.arraycopy(last, len, last, 0, last.length - len);
                    System.arraycopy(data, 0, last, last.length - len, len);
                }
                if (ellipsis == null || !rolled) return new String(last);
                return ellipsis + new String(last);
            } else {  // "cat" mode: size unknown, read it all in streaming fashion
                ByteArrayOutputStream contents = new ByteArrayOutputStream();
                int len;
                byte[] data = new byte[1024];
                do {
                    len = bis.read(data);
                    if (len > 0) contents.write(data, 0, len);
                } while (len == data.length);
                return contents.toString();
            }
        } finally {
            bis.close();
            input.close();
        }
    
public static java.lang.StringrewriteAfterRename(java.io.File beforeDir, java.io.File afterDir, java.lang.String path)

        if (path == null) return null;
        final File result = rewriteAfterRename(beforeDir, afterDir, new File(path));
        return (result != null) ? result.getAbsolutePath() : null;
    
public static java.lang.String[]rewriteAfterRename(java.io.File beforeDir, java.io.File afterDir, java.lang.String[] paths)

        if (paths == null) return null;
        final String[] result = new String[paths.length];
        for (int i = 0; i < paths.length; i++) {
            result[i] = rewriteAfterRename(beforeDir, afterDir, paths[i]);
        }
        return result;
    
public static java.io.FilerewriteAfterRename(java.io.File beforeDir, java.io.File afterDir, java.io.File file)
Given a path under the "before" directory, rewrite it to live under the "after" directory. For example, {@code /before/foo/bar.txt} would become {@code /after/foo/bar.txt}.

        if (file == null) return null;
        if (contains(beforeDir, file)) {
            final String splice = file.getAbsolutePath().substring(
                    beforeDir.getAbsolutePath().length());
            return new File(afterDir, splice);
        }
        return null;
    
public static intsetPermissions(java.io.File path, int mode, int uid, int gid)
Set owner and mode of of given {@link File}.

param
mode to apply through {@code chmod}
param
uid to apply through {@code chown}, or -1 to leave unchanged
param
gid to apply through {@code chown}, or -1 to leave unchanged
return
0 on success, otherwise errno.


                                                       
               
        return setPermissions(path.getAbsolutePath(), mode, uid, gid);
    
public static intsetPermissions(java.lang.String path, int mode, int uid, int gid)
Set owner and mode of of given path.

param
mode to apply through {@code chmod}
param
uid to apply through {@code chown}, or -1 to leave unchanged
param
gid to apply through {@code chown}, or -1 to leave unchanged
return
0 on success, otherwise errno.

        try {
            Os.chmod(path, mode);
        } catch (ErrnoException e) {
            Slog.w(TAG, "Failed to chmod(" + path + "): " + e);
            return e.errno;
        }

        if (uid >= 0 || gid >= 0) {
            try {
                Os.chown(path, uid, gid);
            } catch (ErrnoException e) {
                Slog.w(TAG, "Failed to chown(" + path + "): " + e);
                return e.errno;
            }
        }

        return 0;
    
public static intsetPermissions(java.io.FileDescriptor fd, int mode, int uid, int gid)
Set owner and mode of of given {@link FileDescriptor}.

param
mode to apply through {@code chmod}
param
uid to apply through {@code chown}, or -1 to leave unchanged
param
gid to apply through {@code chown}, or -1 to leave unchanged
return
0 on success, otherwise errno.

        try {
            Os.fchmod(fd, mode);
        } catch (ErrnoException e) {
            Slog.w(TAG, "Failed to fchmod(): " + e);
            return e.errno;
        }

        if (uid >= 0 || gid >= 0) {
            try {
                Os.fchown(fd, uid, gid);
            } catch (ErrnoException e) {
                Slog.w(TAG, "Failed to fchown(): " + e);
                return e.errno;
            }
        }

        return 0;
    
public static voidstringToFile(java.lang.String filename, java.lang.String string)
Writes string to file. Basically same as "echo -n $string > $filename"

param
filename
param
string
throws
IOException

        FileWriter out = new FileWriter(filename);
        try {
            out.write(string);
        } finally {
            out.close();
        }
    
public static booleansync(java.io.FileOutputStream stream)
Perform an fsync on the given FileOutputStream. The stream at this point must be flushed but not yet closed.

        try {
            if (stream != null) {
                stream.getFD().sync();
            }
            return true;
        } catch (IOException e) {
        }
        return false;