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;
}
}
}
``
Java文本Gz文件操作工具类
猜你喜欢
转载自blog.csdn.net/hegan2010/article/details/104417564
今日推荐
周排行