BufferedCopy

该代码示例展示了如何使用Java的BufferedReader和BufferedWriter类复制文本文件,以及使用BufferedInputStream和BufferedOutputStream类复制二进制文件。程序通过读取源文件并写入目标文件实现文件的拷贝,处理过程中确保了数据的正确传输。

 字符的复制

package file.Buffered;

import java.io.*;
//BufferedReader和BufferedWriter 是安装字符操作
//不要去操作二进制文件,可能造成文件损坏
/*
* 二进制文件是以字节为单位进行读写的文件,它包含了任意类型的数据,包括图片、音频、视频
* 等非文本数据。在处理二进制文件时,可以使用字节流(InputStream和OutputStream)来读写数据。(声音视频,word,excel,ppt文件等)
*
*文本文件是以字符为单位进行读写的文件,它包含了文本数据,通常使用ASCII或Unicode编码表示字符。
* 在处理文本文件时,可以使用字符流(Reader和Writer)来读写数据。
*/
public class BufferedCopy {
    public static void main(String[] args) {
        String sourcePath = "d:\\news.txt";
        String destPath ="d:\\destnews.txt";
        BufferedReader br =null;
        BufferedWriter bw = null;
        String line;//按行读取
        try {
            br = new BufferedReader(new FileReader(sourcePath));
            bw = new BufferedWriter(new FileWriter(destPath));
            while((line = br.readLine()) != null){//判断是否为空,如不为空则继续读入
                bw.write(line);//每读取一行就插入一行
                bw.newLine();//插入换行符
            }
            System.out.println("拷贝完成");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭流
            try {
                if(br != null){
                    br.close();
                }
                if(bw != null){
                    bw.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

字节的复制

package file.Buffered;

import java.io.*;

public class BufferedCopy02 {
    public static void main(String[] args) {
        String spath = "d:\\PP.jpg";
        String dpath = "d:\\dPP.jpg";
        BufferedInputStream bi = null;
        BufferedOutputStream bo = null;

        try {
            bi = new BufferedInputStream(new FileInputStream(spath));
            bo = new BufferedOutputStream(new FileOutputStream(dpath));
            byte[] buff = new byte[1024];
            int readln = 0;
            while((readln = bi.read(buff))!= -1){//返回-1,文件读取完毕
                bo.write(buff,0,readln);
            }
            System.out.println("文件拷贝成功");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if(bi != null){
                    bi.close();
                }
                if(bo !=  null){
                    bo.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

 

package com.example; import com.example.callback.ProgressCallback; import java.io.*; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; public class FileUtilszwx { private static final int THREAD_POOL_SIZE = 4; 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更新一次进度 // 单线程复制(优化版) public static boolean copyDirectoryWithProgress(File src, File dest, ProgressCallback callback) throws IOException, InterruptedException { if (!src.isDirectory()) { throw new IllegalArgumentException("源路径必须是目录"); } if (!dest.exists() && !dest.mkdirs()) { throw new IOException("无法创建目标目录: " + dest.getAbsolutePath()); } long totalSize = getDirectorySize(src); AtomicLong copiedSize = new AtomicLong(0); long lastUpdateSize = 0; copyDirectoryInternal(src, dest, totalSize, copiedSize, callback, lastUpdateSize); if (callback != null) { callback.onProgress(1000, 1000); } return true; } private static void copyDirectoryInternal(File src, File dest, long totalSize, AtomicLong copiedSize, ProgressCallback callback, long lastUpdateSize) throws IOException, InterruptedException { File[] files = src.listFiles(); if (files == null) return; for (File file : files) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException("复制被中断"); } File target = new File(dest, file.getName()); if (file.isDirectory()) { if (!target.exists() && !target.mkdirs()) { throw new IOException("无法创建子目录: " + target.getAbsolutePath()); } copyDirectoryInternal(file, target, totalSize, copiedSize, callback, lastUpdateSize); } else { long copied = optimizedSmartCopy(file, target); copiedSize.addAndGet(copied); // 智能进度更新 long currentCopied = copiedSize.get(); if (currentCopied - lastUpdateSize >= PROGRESS_UPDATE_INTERVAL || currentCopied == totalSize) { updateProgress(currentCopied, totalSize, callback); lastUpdateSize = currentCopied; } } } } // 多线程复制(优化版) public static boolean copyDirectoryWithProgressMultiThreaded( File src, File dest, ProgressCallback callback) throws IOException, InterruptedException { if (!src.isDirectory()) { throw new IllegalArgumentException("源路径必须是目录"); } if (!dest.exists() && !dest.mkdirs()) { throw new IOException("无法创建目标目录: " + dest.getAbsolutePath()); } long totalSize = getDirectorySize(src); if (totalSize == 0) { System.out.println("源目录为空或大小为0"); return true; } AtomicLong copiedSize = new AtomicLong(0); ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE); ExecutorService progressExecutor = Executors.newSingleThreadExecutor(); File[] files = src.listFiles(); if (files == null || files.length == 0) { executor.shutdown(); progressExecutor.shutdown(); return true; } AtomicInteger lastProgress = new AtomicInteger(0); CountDownLatch latch = new CountDownLatch(files.length); for (File file : files) { executor.submit(() -> { try { File target = new File(dest, file.getName()); long fileCopied; if (file.isDirectory()) { if (!target.exists() && !target.mkdirs()) { throw new IOException("无法创建子目录: " + target.getAbsolutePath()); } fileCopied = optimizedCopyDirectory(file, target, totalSize, copiedSize); } else { fileCopied = optimizedSmartCopy(file, target); copiedSize.addAndGet(fileCopied); } updateProgress(copiedSize.get(), totalSize, lastProgress, callback, progressExecutor); } catch (IOException e) { System.err.println("复制失败: " + file.getName()); e.printStackTrace(); } finally { latch.countDown(); } }); } latch.await(); progressExecutor.submit(() -> { if (callback != null) { try { callback.onProgress(1000, 1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } System.out.println("多线程进度: 100.0%"); }); executor.shutdown(); progressExecutor.shutdown(); progressExecutor.awaitTermination(10, TimeUnit.SECONDS); return true; } // 优化的目录复制方法 private static long optimizedCopyDirectory(File src, File dest, long totalSize, AtomicLong copiedSize) throws IOException { long copied = 0; File[] files = src.listFiles(); if (files == null) return 0; for (File file : files) { File target = new File(dest, file.getName()); if (file.isDirectory()) { if (!target.exists() && !target.mkdirs()) { throw new IOException("无法创建子目录: " + target.getAbsolutePath()); } copied += optimizedCopyDirectory(file, target, totalSize, copiedSize); } else { long fileCopied = optimizedSmartCopy(file, target); copied += fileCopied; copiedSize.addAndGet(fileCopied); } } return copied; } // 优化的智能复制方法 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; } } // 中等文件复制(transferTo) 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); } } // 大文件复制(分块transferTo) 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; } } // 保持原有的进度更新方法不变 private static void updateProgress(long currentCopied, long totalSize, ProgressCallback callback) { // 原有实现保持不变 } private static void updateProgress(long currentCopied, long totalSize, AtomicInteger lastProgress, ProgressCallback callback, ExecutorService progressExecutor) { // 原有实现保持不变 } // 优化的目录大小计算 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; } } [INFO] --- exec-maven-plugin:3.5.0:java (default-cli) @ compress-benchmark --- /home/zhouweixiang/test/git/S32-GIT-DOWNLOAD true true === 单线程复制开始 === 单线程进度: 1000% 单线程复制完成,耗时: 240352 ms,结果: true 目前没有任何进度打印在命令行请你解决,并且目前9gb文件夹复制花费4分钟
08-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值