Java文本Gz文件操作工具类

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.util.PrintWriterPrinter;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class FileUtils {
    
    
    private static final String TAG = FileUtils.class.getSimpleName();

    // Compress a text file into a gz file.
    public static boolean compressionSingleFile(@NonNull String inPath, @NonNull String outPath) {
    
    
        File inFile = new File(inPath);
        File outFile = new File(outPath);
        return compressionSingleFile(inFile, outFile);
    }

    // Compress a text file into a gz file.
    public static boolean compressionSingleFile(@NonNull File inFile, @NonNull File outFile) {
    
    
        if (!deleteFileOrDir(outFile)) {
    
    
            Log.w(TAG, "Can not delete existing file: " + outFile.getAbsolutePath());
            return false;
        }
        if (inFile.isFile()) {
    
    
            try (FileInputStream fin = new FileInputStream(inFile);
                 FileOutputStream fout = new FileOutputStream(outFile);
                 GZIPOutputStream gos = new GZIPOutputStream(fout);
            ) {
    
    
                int len = 1024;
                byte[] buffer = new byte[len];
                int count;
                while ((count = fin.read(buffer, 0, len)) != -1) {
    
    
                    gos.write(buffer, 0, count);
                }
                gos.finish();
                gos.flush();
                return true;
            } catch (IOException e) {
    
    
                Log.e(TAG, "compressionSingleFile failed !", e);
            }
        }
        deleteFileOrDir(outFile);
        return false;
    }

    // Write a text string into a text file.
    public static boolean writeTextToTextFile(@NonNull String text, @NonNull File textFile) {
    
    
        return writeTextToTextFile(text, textFile, false);
    }

    public static boolean writeTextToTextFile(@NonNull String text, @NonNull File textFile,
            boolean append) {
    
    
        if (TextUtils.isEmpty(text)) {
    
    
            Log.w(TAG, "writeTextToTextFile: text is null or emtpy!");
            return false;
        }
        if (!append && !deleteFileOrDir(textFile)) {
    
    
            Log.w(TAG, "Can not delete existing file: " + textFile.getAbsolutePath());
            return false;
        }
        try (StringReader sr = new StringReader(text);
             FileOutputStream fout = new FileOutputStream(textFile, append);
             OutputStreamWriter osw = new OutputStreamWriter(fout);
        ) {
    
    
            int len = 1024;
            char[] buffer = new char[len];
            int count;
            while ((count = sr.read(buffer, 0, len)) != -1) {
    
    
                osw.write(buffer, 0, count);
            }
            osw.flush();
            return true;
        } catch (IOException e) {
    
    
            Log.e(TAG, "writeTextToTextFile failed !", e);
        }
        if (!append) {
    
    
            deleteFileOrDir(textFile);
        }
        return false;
    }

    // Write a text string into a gz file.
    public static boolean writeTextToGzFile(@NonNull String text, @NonNull File gzFile) {
    
    
        return writeTextToGzFile(text, gzFile, false);
    }

    public static boolean writeTextToGzFile(@NonNull String text, @NonNull File gzFile,
            boolean append) {
    
    
        if (TextUtils.isEmpty(text)) {
    
    
            Log.w(TAG, "writeTextToGzFile: text is null or emtpy!");
            return false;
        }
        if (!append && !deleteFileOrDir(gzFile)) {
    
    
            Log.w(TAG, "Can not delete existing file: " + gzFile.getAbsolutePath());
            return false;
        }
        try (StringReader sr = new StringReader(text);
             FileOutputStream fout = new FileOutputStream(gzFile, append);
             GZIPOutputStream gos = new GZIPOutputStream(fout);
             OutputStreamWriter osw = new OutputStreamWriter(gos);
        ) {
    
    
            int len = 1024;
            char[] buffer = new char[len];
            int count;
            while ((count = sr.read(buffer, 0, len)) != -1) {
    
    
                osw.write(buffer, 0, count);
            }
            osw.flush();
            return true;
        } catch (IOException e) {
    
    
            Log.e(TAG, "writeTextToGzFile failed !", e);
        }
        if (!append) {
    
    
            deleteFileOrDir(gzFile);
        }
        return false;
    }

    // Extract a text file from a gz file.
    public static boolean decompressionSingleFile(@NonNull String inPath, @NonNull String outPath) {
    
    
        File inFile = new File(inPath);
        File outFile = new File(outPath);
        return decompressionSingleFile(inFile, outFile);
    }

    // Extract a text file from a gz file.
    public static boolean decompressionSingleFile(@NonNull File inFile, @NonNull File outFile) {
    
    
        if (!deleteFileOrDir(outFile)) {
    
    
            Log.w(TAG, "Can not delete existing file: " + outFile.getAbsolutePath());
            return false;
        }
        if (inFile.isFile()) {
    
    
            try (FileInputStream fin = new FileInputStream(inFile);
                 GZIPInputStream gin = new GZIPInputStream(fin);
                 FileOutputStream fout = new FileOutputStream(outFile)
            ) {
    
    
                int len = 1024;
                byte[] buffer = new byte[len];
                int count;
                while ((count = gin.read(buffer, 0, len)) != -1) {
    
    
                    fout.write(buffer, 0, count);
                }
                fout.flush();
                return true;
            } catch (IOException e) {
    
    
                Log.e(TAG, "decompressionSingleFile failed !", e);
            }
        }
        deleteFileOrDir(outFile);
        return false;
    }

    // Get the result of the first matching line from a gz file.
    public static Matcher getFirstMatchingResultFromGzFile(@NonNull File gzFile, Pattern pattern) {
    
    
        if (gzFile.isFile()) {
    
    
            try (FileInputStream fin = new FileInputStream(gzFile);
                 GZIPInputStream gin = new GZIPInputStream(fin);
                 InputStreamReader isr = new InputStreamReader(gin);
                 BufferedReader br = new BufferedReader(isr);
            ) {
    
    
                String line = null;
                while ((line = br.readLine()) != null) {
    
    
                    Matcher matcher = pattern.matcher(line);
                    if (matcher.matches()) {
    
    
                        return matcher;
                    }
                }
            } catch (IOException e) {
    
    
                Log.e(TAG, "getFirstMatchingResultFromGzFile failed !", e);
            }
        }
        return null;
    }

    public static boolean isEmptyDirectory(@NonNull File dir) {
    
    
        if (!dir.isDirectory()) {
    
    
            return false;
        }
        File[] subFiles = dir.listFiles();
        if (subFiles == null || subFiles.length == 0) {
    
    
            return true;
        }
        boolean subEmpty = true;
        for (File subFile : subFiles) {
    
    
            subEmpty &= !subFile.exists() || isEmptyDirectory(subFile);
        }
        return subEmpty;
    }

    public static boolean deleteEmptySubDir(@NonNull File parent) {
    
    
        return deleteEmptySubDir(parent, null);
    }

    public static boolean deleteEmptySubDir(@NonNull File parent, @Nullable FilenameFilter filter) {
    
    
        if (!parent.exists()) {
    
    
            return true;
        }
        if (!parent.isDirectory()) {
    
    
            Log.w(TAG, "deleteEmptySubDir: " + parent + " is not a directory!");
            return false;
        }
        File[] subFiles = parent.listFiles(filter);
        if (subFiles == null || subFiles.length == 0) {
    
    
            return true;
        }
        boolean subDeleted = true;
        for (File subFile : subFiles) {
    
    
            if (isEmptyDirectory(subFile) && !subFile.delete()) {
    
    
                subDeleted = false;
                Log.w(TAG, "deleteEmptySubDir delete " + subFile + " failed!");
            }
        }
        return subDeleted;
    }

    public static boolean deleteEmptySubDirRecursive(@NonNull File parent) {
    
    
        return deleteEmptySubDirRecursive(parent, false);
    }

    public static boolean deleteEmptySubDirRecursive(@NonNull File parent, boolean deleteSelf) {
    
    
        if (!parent.exists()) {
    
    
            return true;
        }
        if (!parent.isDirectory()) {
    
    
            return false;
        }
        File[] subFiles = parent.listFiles();
        if (subFiles == null || subFiles.length == 0) {
    
    
            return !deleteSelf || parent.delete();
        }
        boolean subEmpty = true;
        for (File subFile : subFiles) {
    
    
            subEmpty &= deleteEmptySubDirRecursive(subFile, true);
        }
        if (subEmpty) {
    
    
            return !deleteSelf || parent.delete();
        }
        return false;
    }

    public static boolean deleteFileOrDir(@NonNull File file) {
    
    
        if (!file.exists()) {
    
    
            return true;
        }
        if (file.isFile()) {
    
    
            return file.delete();
        }
        // file.isDirectory()
        File[] subFiles = file.listFiles();
        boolean subDeleted = true;
        if (subFiles != null) {
    
    
            for (File subFile : subFiles) {
    
    
                subDeleted &= deleteFileOrDir(subFile);
            }
        }
        return subDeleted ? file.delete() : false;
    }

    /**
     * @return true if dir exists or dir is created successfully.
     */
    public static boolean ensureDirExists(@NonNull File dir) {
    
    
        if (dir.isDirectory()) {
    
    
            return true;
        }
        return deleteFileOrDir(dir) && dir.mkdirs();
    }

    public static boolean joinTextFile(@NonNull List<File> files, @NonNull File targetFile) {
    
    
        if (files.isEmpty()) {
    
    
            return false;
        }
        if (!deleteFileOrDir(targetFile)) {
    
    
            return false;
        }
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile))) {
    
    
            for (File file : files) {
    
    
                try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    
    
                    String line = null;
                    while ((line = br.readLine()) != null) {
    
    
                        bw.write(line);
                        bw.newLine();
                    }
                    bw.flush();
                }
            }
            return true;
        } catch (IOException e) {
    
    
            Log.e(TAG, "joinTextFile failed !", e);
        }
        deleteFileOrDir(targetFile);
        return false;
    }

    public static List<String> getLinesFromTextFile(@NonNull File file) {
    
    
        List<String> lines = new LinkedList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    
    
            String line = null;
            while ((line = br.readLine()) != null) {
    
    
                lines.add(line);
            }
        } catch (IOException e) {
    
    
            Log.e(TAG, "getLinesFromTextFile failed !", e);
        }
        return lines;
    }

    public static String getTextFromTextFile(@NonNull File file) {
    
    
        StringBuilder sb = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    
    
            String line = null;
            while ((line = br.readLine()) != null) {
    
    
                sb.append(line).append('\n');
            }
        } catch (IOException e) {
    
    
            Log.e(TAG, "getTextFromTextFile failed !", e);
        }
        return sb.toString();
    }

    public static class PatternFilenameFilter implements FilenameFilter {
    
    
        private final Pattern mPattern;

        public PatternFilenameFilter(Pattern pattern) {
    
    
            mPattern = pattern;
        }

        @Override
        public boolean accept(File dir, String name) {
    
    
            return mPattern.matcher(name).matches();
        }

        @Override
        public String toString() {
    
    
            return "PatternFilenameFilter:" + mPattern;
        }
    }

    public interface FileProcessor {
    
    
        void onFileProcess(File file, boolean selfFiltered, boolean parentFiltered);
    }

    public abstract static class ResultFileProcessor<R> implements FileProcessor {
    
    
        private R mResult;

        public ResultFileProcessor(R result) {
    
    
            setResult(result);
        }

        public final void setResult(R result) {
    
    
            mResult = result;
        }

        public final R getResult() {
    
    
            return mResult;
        }
    }

    public static boolean processFiles(File file, FileProcessor fileProcessor, boolean recursive) {
    
    
        return processFiles(file, fileProcessor, recursive, null);
    }

    public static boolean processFiles(File file, FileProcessor fileProcessor, boolean recursive,
            FilenameFilter filter) {
    
    
        boolean filtered = filter == null || filter.accept(file.getParentFile(), file.getName());
        return processFiles(file, fileProcessor, recursive, filter, filtered, false);
    }

    private static boolean processFiles(File file, FileProcessor fileProcessor, boolean recursive,
            FilenameFilter filter, boolean filtered, boolean parentFiltered) {
    
    
        if (file.isFile()) {
    
    
            if (filtered || parentFiltered) {
    
    
                fileProcessor.onFileProcess(file, filtered, parentFiltered);
                return true;
            }
            return false;
        }
        if (!file.isDirectory()) {
    
    
            return false;
        }
        boolean success = filtered;
        File[] subFiles = file.listFiles();
        if (subFiles != null) {
    
    
            Arrays.sort(subFiles);
            for (File subFile : subFiles) {
    
    
                boolean subFiltered = filter == null || filter.accept(file, subFile.getName());
                if (subFile.isFile()) {
    
    
                    if (subFiltered || filtered) {
    
    
                        success = true;
                        fileProcessor.onFileProcess(subFile, subFiltered, filtered);
                    }
                } else if (subFile.isDirectory()) {
    
    
                    if (subFiltered || filtered) {
    
    
                        success = true;
                        processFiles(subFile, fileProcessor, true, filter, subFiltered, filtered);
                    } else if (recursive) {
    
    
                        success |= processFiles(subFile, fileProcessor, true, filter, false, false);
                    } else if (!subFiltered && !filtered && !recursive) {
    
    
                        // Ignore
                    }
                }
            }
        }
        if (success) {
    
    
            fileProcessor.onFileProcess(file, filtered, parentFiltered);
        }
        return success;
    }

    public static long getFileOrDirSize(@NonNull File file) {
    
    
        return getFileOrDirSize(file, (FilenameFilter) null, true);
    }

    public static long getFileOrDirSize(@NonNull File file, @Nullable Pattern namePattern,
            boolean recursive) {
    
    
        FilenameFilter filter = (namePattern == null) ? null
                : new PatternFilenameFilter(namePattern);
        return getFileOrDirSize(file, filter, recursive);
    }

    public static long getFileOrDirSize(@NonNull File file, @Nullable FileFilter fileFilter,
            boolean recursive) {
    
    
        FilenameFilter filter = (fileFilter == null) ? null
                : (dir, name) -> fileFilter.accept(new File(dir, name));
        return getFileOrDirSize(file, filter, recursive);
    }

    public static long getFileOrDirSize(@NonNull File file, @Nullable FilenameFilter filter,
            boolean recursive) {
    
    
        ResultFileProcessor<Long> processor = new ResultFileProcessor<Long>(0L) {
    
    
            @Override
            public void onFileProcess(File file, boolean selfFiltered, boolean parentFiltered) {
    
    
                if (!Files.isSymbolicLink(Paths.get(file.getAbsolutePath()))) {
    
    
                    setResult(getResult() + file.length());
                }
            }
        };
        processFiles(file, processor, true, filter);
        return processor.getResult();
    }

    public static boolean deleteOldFiles(@NonNull String dirPath, @NonNull Pattern namePattern,
            long requiredBytes, boolean recursive) {
    
    
        return deleteOldFiles(dirPath, new PatternFilenameFilter(namePattern), requiredBytes,
                recursive);
    }

    public static boolean deleteOldFiles(@NonNull String dirPath,
            @NonNull FilenameFilter filenameFilter, long requiredBytes, boolean recursive) {
    
    
        File dir = new File(dirPath);
        if (!dir.isDirectory()) {
    
    
            Log.e(TAG, "deleteOldFiles dir " + dirPath + " does not exist!");
            return false;
        }
        ResultFileProcessor<Long> processor = new ResultFileProcessor<Long>(0L) {
    
    
            @Override
            public void onFileProcess(File file, boolean selfFiltered, boolean parentFiltered) {
    
    
                if (!selfFiltered && !parentFiltered) {
    
    
                    return;
                }
                long deletedBytes = getResult();
                if (deletedBytes <= requiredBytes) {
    
    
                    deletedBytes += getFileOrDirSize(file);
                    if (!deleteFileOrDir(file)) {
    
    
                        deletedBytes -= getFileOrDirSize(file);
                    }
                    setResult(deletedBytes);
                }
            }
        };
        processFiles(dir, processor, recursive, filenameFilter);
        long deletedBytes = processor.getResult();
        if (deletedBytes > requiredBytes) {
    
    
            Log.d(TAG, "deleteOldFiles success! deletedBytes is " + deletedBytes
                    + ", requiredBytes is " + requiredBytes);
            return true;
        }
        Log.e(TAG, "deleteOldFiles failed! deletedBytes is " + deletedBytes
                + ", but requiredBytes is " + requiredBytes);
        return false;
    }

    public static CloseablePrintWriterPrinter getGzFilePrinter(@NonNull File gzFile) {
    
    
        if (!deleteFileOrDir(gzFile)) {
    
    
            Log.w(TAG, "Can not delete existing file: " + gzFile.getAbsolutePath());
            return null;
        }
        try {
    
    
            FileOutputStream fout = new FileOutputStream(gzFile);
            GZIPOutputStream gos = new GZIPOutputStream(fout);
            PrintWriter pw = new PrintWriter(gos);
            CloseablePrintWriterPrinter pwp = new CloseablePrintWriterPrinter(pw);
            return pwp;
        } catch (IOException e) {
    
    
            Log.e(TAG, "getGzFilePrinter failed !", e);
            return null;
        }
    }

    public static class CloseablePrintWriterPrinter extends PrintWriterPrinter implements
            Closeable {
    
    
        private final PrintWriter mPW;

        public CloseablePrintWriterPrinter(PrintWriter pw) {
    
    
            super(pw);
            mPW = pw;
        }

        @Override
        public void close() {
    
    
            mPW.close();
        }
    }

    public static String[] splitFile(@NonNull String inPath, @NonNull String outDirPath,
            long fileByteLimit) {
    
    
        File[] files = splitFile(new File(inPath), new File(outDirPath), fileByteLimit);
        if (files == null) {
    
    
            return null;
        }
        int size = files.length;
        String[] paths = new String[size];
        for (int i = 0; i < size; i++) {
    
    
            paths[i] = files[i].getAbsolutePath();
        }
        return paths;
    }

    public static File[] splitFile(@NonNull File inFile, @NonNull File outDir, long fileByteLimit) {
    
    
        if (!inFile.isFile()) {
    
    
            Log.e(TAG, inFile + " does not exist or is not a file !");
            return null;
        }
        if (!outDir.isDirectory()) {
    
    
            Log.e(TAG, outDir + " does not exist or is not a directory !");
            return null;
        }
        String baseName = inFile.getName();
        long originBytes = inFile.length();
        int quotient = (int) ((double) originBytes / fileByteLimit);
        int digitNumber = 2;
        while (quotient >= 10) {
    
    
            quotient /= 10;
            digitNumber++;
        }
        String format = baseName + ".part%0" + digitNumber + "d";
        List<File> fileList = new ArrayList<>();

        try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(inFile))) {
    
    
            int len = 1024;
            byte[] buffer = new byte[len];
            int index = 1;

            outer:
            while (true) {
    
    
                String partName = String.format(format, index++);
                File partFile = new File(outDir, partName);
                fileList.add(partFile);

                try (FileOutputStream fout = new FileOutputStream(partFile);
                     BufferedOutputStream bos = new BufferedOutputStream(fout)) {
    
    
                    long partCount = 0;

                    while (true) {
    
    
                        int readCount = bin.read(buffer, 0, len);
                        if (readCount != -1) {
    
    
                            bos.write(buffer, 0, readCount);
                            partCount += readCount;
                            if (partCount + Math.min(bin.available(), len) > fileByteLimit) {
    
    
                                continue outer;
                            }
                        } else {
    
    
                            break outer;
                        }
                    }
                }
            }

            return fileList.toArray(new File[fileList.size()]);
        } catch (IOException e) {
    
    
            for (File file : fileList) {
    
    
                deleteFileOrDir(file);
            }
            Log.e(TAG, "splitFile failed !", e);
            return null;
        }
    }
}
``

猜你喜欢

转载自blog.csdn.net/hegan2010/article/details/104417564