Exception 'java.lang.InterruptedException' is never thrown in the corresponding try block
package com.kotei.overseas.navi.update;
import android.util.Log;
import java.nio.channels.FileChannel;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
// zip4j 2.11.4 的新导入
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.progress.ProgressMonitor;
import net.lingala.zip4j.progress.PasswordVerificationStrategy;
// 假设 USBOfflineUpdater.ProgressCallback 接口定义如下(如未定义请补充)
public interface USBOfflineUpdater {
interface ProgressCallback {
void onProgress(int percentDone, int total);
}
}
public class FileUtilszwx {
private static final String TAG = "FileUtils";
// 动态缓冲区大小定义
public static final int MIN_BUFFER_SIZE = 8 * 1024 * 1024; // 8MB
public static final int MEDIUM_BUFFER_SIZE = 64 * 1024 * 1024; // 64MB
public static final int MAX_BUFFER_SIZE = 128 * 1024 * 1024; // 128MB
/**
* 带进度拷贝文件(零拷贝+动态缓冲区)
*/
public static boolean copyFileWithProgress(File src, File dest,
USBOfflineUpdater.ProgressCallback callback) {
long totalSize = src.length();
long copiedSize = 0;
long lastCallbackSize = 0;
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
copiedSize = zeroCopy(src, dest, callback, totalSize, lastCallbackSize);
} else {
copiedSize = dynamicBufferCopy(src, dest, callback, totalSize, lastCallbackSize);
}
return copiedSize == totalSize;
} catch (IOException | InterruptedException e) {
Log.e(TAG, "文件拷贝失败", e);
Thread.currentThread().interrupt(); // 重新设置中断状态
return false;
}
}
/**
* 零拷贝实现
*/
private static long zeroCopy(File src, File dest,
USBOfflineUpdater.ProgressCallback callback,
long totalSize, long lastCallbackSize) throws IOException, InterruptedException {
try (FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dest).getChannel()) {
long position = 0;
long remaining = totalSize;
while (remaining > 0 && !Thread.currentThread().isInterrupted()) {
long transferred = inChannel.transferTo(position, remaining, outChannel);
position += transferred;
remaining -= transferred;
// 百分比回调
long currentSize = totalSize - remaining;
if (currentSize * 1000 / totalSize > lastCallbackSize) {
if (callback != null) {
callback.onProgress((int) (currentSize * 100 / totalSize), 100);
}
lastCallbackSize = currentSize * 1000 / totalSize;
}
}
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("文件拷贝被中断");
}
return position;
}
}
/**
* 动态缓冲区拷贝
*/
private static long dynamicBufferCopy(File src, File dest,
USBOfflineUpdater.ProgressCallback callback,
long totalSize, long lastCallbackSize) throws IOException, InterruptedException {
int bufferSize = getBufferSize(totalSize);
byte[] buffer = new byte[bufferSize];
long copiedSize = 0;
try (InputStream in = new BufferedInputStream(new FileInputStream(src));
OutputStream out = new BufferedOutputStream(new FileOutputStream(dest))) {
int length;
while ((length = in.read(buffer)) > 0 && !Thread.currentThread().isInterrupted()) {
out.write(buffer, 0, length);
copiedSize += length;
// 百分比回调
if (copiedSize * 1000 / totalSize > lastCallbackSize) {
if (callback != null) {
callback.onProgress((int) (copiedSize * 100 / totalSize), 100);
}
lastCallbackSize = copiedSize * 1000 / totalSize;
}
}
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("文件拷贝被中断");
}
return copiedSize;
}
}
/**
* 动态缓冲区大小计算
*/
private static int getBufferSize(long fileSize) {
if (fileSize < 100 * 1024 * 1024) return MIN_BUFFER_SIZE;
if (fileSize < 2 * 1024 * 1024 * 1024L) return MEDIUM_BUFFER_SIZE;
return MAX_BUFFER_SIZE;
}
/**
* 带进度解压ZIP文件(使用zip4j 2.11.4)
*/
public static boolean extractZipWithProgress(File zipFile, File targetDir,
USBOfflineUpdater.ProgressCallback callback) {
try {
PasswordVerificationStrategy passwordStrategy = () -> null;
ZipFile zip = new ZipFile(zipFile, passwordStrategy);
if (callback != null) {
zip.addProgressMonitor(new ProgressMonitor() {
private long totalWork = 0;
private long lastUpdate = 0;
@Override
public void init(long totalWork) {
this.totalWork = totalWork;
lastUpdate = 0;
}
@Override
public void updateWork(long workCompleted) {
if (totalWork > 0) {
int percentDone = (int) ((workCompleted * 100) / totalWork);
if (percentDone > lastUpdate) {
callback.onProgress(percentDone, 100);
lastUpdate = percentDone;
}
}
}
@Override
public boolean isCancelRequested() {
return false;
}
});
}
zip.extractAll(targetDir.getAbsolutePath());
return true;
} catch (Exception e) {
Log.e(TAG, "zip4j 解压失败", e);
return false;
}
}
/**
* 带进度压缩目录(使用zip4j 2.11.4)
*/
public static boolean compressDirectoryWithProgress(File sourceDir, File outputFile,
USBOfflineUpdater.ProgressCallback callback) {
try {
ZipFile zipFile = new ZipFile(outputFile, (PasswordVerificationStrategy) null);
List<File> filesToAdd = new ArrayList<>();
collectFiles(sourceDir, filesToAdd);
if (callback != null) {
zipFile.setProgressMonitor(new ProgressMonitor() {
private long totalWork = 0;
private long lastUpdate = 0;
@Override
public void init(long totalWork) {
this.totalWork = totalWork;
lastUpdate = 0;
}
@Override
public void updateWork(long workCompleted) {
if (totalWork > 0) {
int percentDone = (int) ((workCompleted * 100) / totalWork);
if (percentDone > lastUpdate) {
callback.onProgress(percentDone, 100);
lastUpdate = percentDone;
}
}
}
@Override
public boolean isCancelRequested() {
return false;
}
});
}
ZipParameters parameters = new ZipParameters();
for (File file : filesToAdd) {
try {
zipFile.addFile(file, parameters);
} catch (InterruptedException e) {
Log.e(TAG, "文件压缩被中断: " + file.getName(), e);
Thread.currentThread().interrupt(); // 重新设置中断状态
return false;
}
}
return true;
} catch (Exception e) {
Log.e(TAG, "zip4j 压缩失败", e);
return false;
}
}
// 递归收集所有文件
private static void collectFiles(File dir, List<File> files) {
File[] children = dir.listFiles();
if (children != null) {
for (File child : children) {
if (child.isDirectory()) {
collectFiles(child, files);
} else {
files.add(child);
}
}
}
}
/**
* 解压ZIP文件(无进度)
*/
public static boolean extractZip(File zipFile, File targetDir) {
return extractZipWithProgress(zipFile, targetDir, null);
}
/**
* 计算目录大小
*/
public static long getDirectorySize(File directory) {
long size = 0;
if (directory == null || !directory.exists()) return 0;
if (directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
size += getDirectorySize(file);
}
}
} else {
size = directory.length();
}
return size;
}
/**
* 删除目录内容(保留目录本身)
*/
public static boolean deleteDirectoryContents(File directory) {
if (directory == null || !directory.exists() || !directory.isDirectory()) {
return false;
}
File[] files = directory.listFiles();
if (files == null) return true;
boolean success = true;
for (File file : files) {
if (file.isDirectory()) {
success &= deleteRecursive(file);
} else {
if (!file.delete()) {
Log.w(TAG, "删除文件失败: " + file.getAbsolutePath());
success = false;
}
}
}
return success;
}
/**
* 递归删除文件/目录
*/
public static boolean deleteRecursive(File file) {
boolean success = true;
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
success &= deleteRecursive(child);
}
}
}
if (!file.delete()) {
Log.w(TAG, "删除失败: " + file.getAbsolutePath());
success = false;
}
return success;
}
}
最新发布