SupremeWord进度33.1%

哦,差不多到1/3了.
=== 单线程复制开始 === Starting copy, total size: 8.62 GB [= ] 5.0% (444.7 MB/8.62 GB) | Speed: 33.5 MB/s | ETA: 4m 10s单线程进度: 50% [= ] 6.0% (530.1 MB/8.62 GB) | Speed: 53.1 MB/s | ETA: 2m 36s单线程进度: 60% [= ] 7.0% (623.0 MB/8.62 GB) | Speed: 64.0 MB/s | ETA: 2m 8s单线程进度: 70% [= ] 8.0% (706.4 MB/8.62 GB) | Speed: 32.0 MB/s | ETA: 4m 13s单线程进度: 80% [== ] 10.5% (926.9 MB/8.62 GB) | Speed: 46.0 MB/s | ETA: 2m 51s单线程进度: 105% [== ] 14.5% (1.25 GB/8.62 GB) | Speed: 52.5 MB/s | ETA: 2m 23s单线程进度: 145% [=== ] 17.0% (1.46 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 1s单线程进度: 170% [=== ] 17.5% (1.51 GB/8.62 GB) | Speed: 65.6 MB/s | ETA: 1m 50s单线程进度: 175% [=== ] 18.0% (1.56 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 1s单线程进度: 180% [=== ] 18.5% (1.59 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 1s单线程进度: 185% [==== ] 20.0% (1.72 GB/8.62 GB) | Speed: 12.7 MB/s | ETA: 9m 14s单线程进度: 200% [==== ] 20.5% (1.77 GB/8.62 GB) | Speed: 65.1 MB/s | ETA: 1m 47s单线程进度: 205% [==== ] 21.0% (1.81 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 1s单线程进度: 210% [==== ] 21.5% (1.85 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 1s单线程进度: 215% [==== ] 22.0% (1.90 GB/8.62 GB) | Speed: 35.6 MB/s | ETA: 3m 13s单线程进度: 220% [==== ] 22.5% (1.94 GB/8.62 GB) | Speed: 22.7 MB/s | ETA: 5m 1s单线程进度: 225% [==== ] 24.5% (2.11 GB/8.62 GB) | Speed: 164.3 MB/s | ETA: 40s单线程进度: 245% [===== ] 25.0% (2.15 GB/8.62 GB) | Speed: 285.8 MB/s | ETA: 23s单线程进度: 250% [===== ] 27.0% (2.33 GB/8.62 GB) | Speed: 183.5 MB/s | ETA: 35s单线程进度: 270% [===== ] 27.5% (2.37 GB/8.62 GB) | Speed: 95.7 MB/s | ETA: 1m 6s单线程进度: 275% [===== ] 28.0% (2.42 GB/8.62 GB) | Speed: 104.2 MB/s | ETA: 1m 0s单线程进度: 280% [===== ] 29.0% (2.51 GB/8.62 GB) | Speed: 65.9 MB/s | ETA: 1m 34s单线程进度: 290% [===== ] 29.5% (2.54 GB/8.62 GB) | Speed: 99.4 MB/s | ETA: 1m 2s单线程进度: 295% [====== ] 31.5% (2.72 GB/8.62 GB) | Speed: 49.0 MB/s | ETA: 2m 3s单线程进度: 315% [====== ] 32.0% (2.76 GB/8.62 GB) | Speed: 41.3 MB/s | ETA: 2m 25s单线程进度: 320% [====== ] 32.5% (2.80 GB/8.62 GB) | Speed: 33.7 MB/s | ETA: 2m 56s单线程进度: 325% [======= ] 35.5% (3.06 GB/8.62 GB) | Speed: 8.4 MB/s | ETA: 11m 18s单线程进度: 355% [======= ] 36.5% (3.15 GB/8.62 GB) | Speed: 44.5 MB/s | ETA: 2m 5s单线程进度: 365% [======== ] 40.0% (3.45 GB/8.62 GB) | Speed: 54.5 MB/s | ETA: 1m 36s单线程进度: 400% [========= ] 47.5% (4.10 GB/8.62 GB) | Speed: 20.3 MB/s | ETA: 3m 47s单线程进度: 475% [========= ] 49.5% (4.27 GB/8.62 GB) | Speed: 59.1 MB/s | ETA: 1m 15s单线程进度: 495% [========== ] 50.0% (4.31 GB/8.62 GB) | Speed: 37.0 MB/s | ETA: 1m 59s单线程进度: 500% [========== ] 50.5% (4.35 GB/8.62 GB) | Speed: 38.7 MB/s | ETA: 1m 52s单线程进度: 505% [============ ] 64.0% (5.51 GB/8.62 GB) | Speed: 5.1 MB/s | ETA: 10m 17s单线程进度: 640% [============= ] 65.0% (5.60 GB/8.62 GB) | Speed: 24.0 MB/s | ETA: 2m 8s单线程进度: 650% [============= ] 66.0% (5.69 GB/8.62 GB) | Speed: 44.1 MB/s | ETA: 1m 7s单线程进度: 660% [============= ] 67.0% (5.78 GB/8.62 GB) | Speed: 103.6 MB/s | ETA: 28s单线程进度: 670% [============= ] 69.5% (5.99 GB/8.62 GB) | Speed: 21.0 MB/s | ETA: 2m 7s单线程进度: 695% [============== ] 73.5% (6.34 GB/8.62 GB) | Speed: 36.3 MB/s | ETA: 1m 4s单线程进度: 735% [=============== ] 75.5% (6.51 GB/8.62 GB) | Speed: 79.4 MB/s | ETA: 27s单线程进度: 755% [=============== ] 76.0% (6.55 GB/8.62 GB) | Speed: 24.3 MB/s | ETA: 1m 27s单线程进度: 760% [=============== ] 76.5% (6.59 GB/8.62 GB) | Speed: 63.2 MB/s | ETA: 32s单线程进度: 765% [=============== ] 77.0% (6.64 GB/8.62 GB) | Speed: 53.0 MB/s | ETA: 38s单线程进度: 770% [=============== ] 77.5% (6.68 GB/8.62 GB) | Speed: 29.7 MB/s | ETA: 1m 6s单线程进度: 775% [=============== ] 78.0% (6.72 GB/8.62 GB) | Speed: 79.5 MB/s | ETA: 24s单线程进度: 780% [=============== ] 79.0% (6.81 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 0s单线程进度: 790% [=============== ] 79.5% (6.85 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 0s单线程进度: 795% [================ ] 80.0% (6.89 GB/8.62 GB) | Speed: 3.4 MB/s | ETA: 8m 41s单线程进度: 800% [================ ] 80.5% (6.94 GB/8.62 GB) | Speed: 5000.0 MB/s | ETA: 0s单线程进度: 805% [================ ] 81.0% (6.98 GB/8.62 GB) | Speed: 33.1 MB/s | ETA: 50s单线程进度: 810% [================ ] 81.5% (7.02 GB/8.62 GB) | Speed: 53.7 MB/s | ETA: 30s单线程进度: 815% [================ ] 83.0% (7.15 GB/8.62 GB) | Speed: 30.2 MB/s | ETA: 49s单线程进度: 830% [================ ] 83.5% (7.20 GB/8.62 GB) | Speed: 68.1 MB/s | ETA: 21s单线程进度: 835% [================ ] 84.0% (7.24 GB/8.62 GB) | Speed: 64.0 MB/s | ETA: 22s单线程进度: 840% [================== ] 91.5% (7.88 GB/8.62 GB) | Speed: 10.2 MB/s | ETA: 1m 13s单线程进度: 915% [=================== ] 95.0% (8.19 GB/8.62 GB) | Speed: 125.5 MB/s | ETA: 3s单线程进度: 950% [=================== ] 96.0% (8.28 GB/8.62 GB) | Speed: 42.1 MB/s | ETA: 8s单线程进度: 960% [=================== ] 96.5% (8.31 GB/8.62 GB) | Speed: 2.0 MB/s | ETA: 2m 34s单线程进度: 965% [====================] 100.0% (8.62 GB/8.62 GB) | Speed: 0.8 MB/s | ETA: --单线程进度: 1000% 取消单线程进度的显示: | Speed: 0.8 MB/s | ETA: --单线程进度: 1000% 我只在乎整体的进度,同时根据处理的文件个数来换算输出的进度,每处理一个文件更新一次:package com.example; import com.example.callback.ProgressCallback; import java.io.*; import java.nio.channels.FileChannel; import java.util.concurrent.atomic.AtomicLong; public class OptimizedFileCopier { // 配置参数 private static final int BUFFER_SIZE = 64 * 1024; // 64KB缓冲 private static final long SMALL_FILE_THRESHOLD = 32 * 1024; // 32KB private static final long MEDIUM_FILE_THRESHOLD = 128 * 1024 * 1024; // 128MB private static final long PROGRESS_UPDATE_INTERVAL = 1024 * 1024; // 1MB更新一次进度 private static final long MIN_PROGRESS_UPDATE_INTERVAL_MS = 500; // 最小进度更新间隔(毫秒) private static final double MAX_DISPLAY_SPEED = 5000; // 最大显示速度(MB/s) // 速度平滑处理相关 private static final int SPEED_HISTORY_SIZE = 3; private static final double[] speedHistory = new double[SPEED_HISTORY_SIZE]; private static int speedIndex = 0; private static long lastSpeedCalcTime = 0; private static long lastSpeedCalcBytes = 0; public static boolean copyDirectoryWithProgress(File src, File dest, ProgressCallback callback) throws IOException, InterruptedException { // 参数校验 if (!src.isDirectory()) { throw new IllegalArgumentException("Source path must be a directory"); } if (!dest.exists() && !dest.mkdirs()) { throw new IOException("Cannot create destination directory: " + dest.getAbsolutePath()); } // 初始化状态 long totalSize = getDirectorySize(src); System.out.println("Starting copy, total size: " + formatSize(totalSize)); AtomicLong copiedSize = new AtomicLong(0); long startTime = System.currentTimeMillis(); long lastUpdateTime = startTime; long lastUpdateSize = 0; // 执行复制 copyDirectoryInternal(src, dest, totalSize, copiedSize, callback, startTime, lastUpdateSize, lastUpdateTime); // 完成处理 if (callback != null) { callback.onProgress(1000, 1000); } // 输出统计信息 long totalTime = System.currentTimeMillis() - startTime; double avgSpeed = totalTime > 0 ? (totalSize / 1024.0 / 1024.0) / (totalTime / 1000.0) : 0; System.out.printf("\nCopy completed! Total: %s, Time: %s, Avg speed: %.1f MB/s\n", formatSize(totalSize), formatDuration(totalTime), avgSpeed); return true; } private static void copyDirectoryInternal(File src, File dest, long totalSize, AtomicLong copiedSize, ProgressCallback callback, long startTime, long lastUpdateSize, long lastUpdateTime) throws IOException, InterruptedException { File[] files = src.listFiles(); if (files == null) return; for (File file : files) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException("Copy interrupted"); } File target = new File(dest, file.getName()); if (file.isDirectory()) { if (!target.exists() && !target.mkdirs()) { throw new IOException("Cannot create subdirectory: " + target.getAbsolutePath()); } copyDirectoryInternal(file, target, totalSize, copiedSize, callback, startTime, lastUpdateSize, lastUpdateTime); } else { long copied = optimizedSmartCopy(file, target); copiedSize.addAndGet(copied); // 智能进度更新 long currentCopied = copiedSize.get(); long currentTime = System.currentTimeMillis(); if (currentCopied - lastUpdateSize >= PROGRESS_UPDATE_INTERVAL || currentCopied == totalSize || currentTime - lastUpdateTime >= MIN_PROGRESS_UPDATE_INTERVAL_MS) { updateProgress(currentCopied, totalSize, callback, startTime); lastUpdateSize = currentCopied; lastUpdateTime = currentTime; } } } } private static void updateProgress(long currentCopied, long totalSize, ProgressCallback callback, long startTime) { if (totalSize == 0) return; // 计算进度 (0-1000) int progress = (int) Math.min(1000, (currentCopied * 1000L) / Math.max(1, totalSize)); // 计算平滑后的速度 double speed = getSmoothedSpeed(startTime, currentCopied); speed = Math.min(speed, MAX_DISPLAY_SPEED); // 限制最大显示速度 // 计算剩余时间 String remainingTime = calculateRemainingTime(startTime, currentCopied, totalSize, speed); // 更新显示 System.out.printf("\r[%s] %.1f%% (%s/%s) | Speed: %.1f MB/s | ETA: %s", buildProgressBar(progress), progress / 10.0, formatSize(currentCopied), formatSize(totalSize), speed, remainingTime); // 回调通知 if (callback != null) { try { callback.onProgress(progress, 1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } private static double getSmoothedSpeed(long startTime, long copiedBytes) { long currentTime = System.currentTimeMillis(); long elapsed = currentTime - startTime; if (elapsed < 100) return 0; // 初始阶段不计算速度 // 计算瞬时速度 double instantSpeed = (copiedBytes - lastSpeedCalcBytes) / 1024.0 / 1024.0 / ((currentTime - lastSpeedCalcTime) / 1000.0); // 更新历史记录 speedHistory[speedIndex++ % SPEED_HISTORY_SIZE] = instantSpeed; lastSpeedCalcTime = currentTime; lastSpeedCalcBytes = copiedBytes; // 计算平滑速度 (取最近3次的平均值) double sum = 0; int count = 0; for (double s : speedHistory) { if (s > 0) { sum += s; count++; } } return count > 0 ? sum / count : 0; } private static String calculateRemainingTime(long startTime, long copiedBytes, long totalBytes, double speed) { if (copiedBytes <= 0 || copiedBytes >= totalBytes || speed <= 0.1) { return "--"; } double remainingMB = (totalBytes - copiedBytes) / (1024.0 * 1024.0); int remainingSec = (int) (remainingMB / speed); return formatDuration(remainingSec * 1000L); } private static String buildProgressBar(int progress) { int completed = progress / 50; completed = Math.min(20, completed); // 确保不超过20个字符 int remaining = 20 - completed; return "=".repeat(completed) + " ".repeat(remaining); } private static String formatSize(long bytes) { if (bytes < 1024) return bytes + " B"; if (bytes < 1024 * 1024) return String.format("%.1f KB", bytes / 1024.0); if (bytes < 1024 * 1024 * 1024) return String.format("%.1f MB", bytes / (1024.0 * 1024.0)); return String.format("%.2f GB", bytes / (1024.0 * 1024.0 * 1024.0)); } private static String formatDuration(long millis) { long seconds = millis / 1000; if (seconds < 60) return seconds + "s"; if (seconds < 3600) return String.format("%dm %ds", seconds/60, seconds%60); return String.format("%dh %dm", seconds/3600, (seconds%3600)/60); } private static long optimizedSmartCopy(File src, File dest) throws IOException { long size = src.length(); if (size < SMALL_FILE_THRESHOLD) { return smallFileCopy(src, dest); } else if (size < MEDIUM_FILE_THRESHOLD) { return mediumFileCopy(src, dest); } else { return largeFileCopy(src, dest); } } private static long smallFileCopy(File src, File dest) throws IOException { try (FileInputStream in = new FileInputStream(src); FileOutputStream out = new FileOutputStream(dest)) { byte[] buffer = new byte[BUFFER_SIZE]; long total = 0; int n; while ((n = in.read(buffer)) != -1) { out.write(buffer, 0, n); total += n; } return total; } } private static long mediumFileCopy(File src, File dest) throws IOException { try (FileChannel inChannel = new FileInputStream(src).getChannel(); FileChannel outChannel = new FileOutputStream(dest).getChannel()) { return inChannel.transferTo(0, inChannel.size(), outChannel); } } private static long largeFileCopy(File src, File dest) throws IOException { try (FileChannel inChannel = new FileInputStream(src).getChannel(); FileChannel outChannel = new FileOutputStream(dest).getChannel()) { long size = inChannel.size(); long position = 0; long chunkSize = 16 * 1024 * 1024; // 16MB分块 while (position < size) { long remaining = size - position; long transferSize = Math.min(chunkSize, remaining); position += inChannel.transferTo(position, transferSize, outChannel); } return size; } } public static long getDirectorySize(File dir) { if (dir == null || !dir.exists() || !dir.isDirectory()) { return 0; } long size = 0; File[] files = dir.listFiles(); if (files != null) { for (File file : files) { if (file.isDirectory()) { size += getDirectorySize(file); } else { size += file.length(); } } } return size; } }
08-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值