【Java基础练习题】多线程IO流操作实现文件的复制(举一反三)

前言:时不我待,忽而已春,初夏将至。然惊觉自身Java基础仍薄弱不堪,虽“雄关万道真如铁”,只得“万里关山从头越”。把基础打扎实才是根本,对于日后的工作而言也是极为重要。通过不断的学习和理解加上手动实践代码程序,才是编程学习的上上之选!

题目:使用多线程实现文件的复制。输入初始文件路径,输入目标文件夹路径,实现复制操作。

思路:

1、如果只是实现文件的复制操作,可以通过文件的reNameTo()方法实现,但是如果文件包括文件夹那就只能通过文件IO流操作实现。

2、首先,最基本的实现遍历一个文件夹所有文件并打包到一个集合中。

3、启用多线程,建立线程池,对文件进行IO流操作实现文件的复制。

一、文件的遍历

1、获取全部文件

 public static List GetAllFiles(String SourceFile)//获取所有文件
    {
        List<File> FileList=new ArrayList<>();//文件列表
        File file=new File(SourceFile);//获取源文件
        if (file.exists()&&file.isDirectory()) {//如果文件存在且是文件夹形式则进行递归
            FileList = LongEegodic(file, FileList);
        }
        return FileList;
    }

2、递归

public static List LongEegodic(File file,List res)//递归获取文件、文件夹
    {
        File filelist[]=file.listFiles();
        if (filelist==null)//文件为空直接返回
            return null;
        for (File file1:filelist)
        {
            res.add(file1);//无论是文件夹还是文件都加入列表
            LongEegodic(file1,res);//递归,继续获取子文件
        }
        return res;
    }

二、文件的IO流实现文件的复制操作

  public static void Copy(File Source,File Target)//使用IO流进行文件的复制操作
    {
        FileInputStream Fis=null;//输入流
        FileOutputStream Fos=null;//输出流
        try {
            Fis=new FileInputStream(Source);
            Fos=new FileOutputStream(Target);
            byte buf[]=new byte[1024];//每次传送的字节数量
            int len=0;
            while ((len=Fis.read(buf))!=-1)//如果还有字节则继续传送
            {
                Fos.write(buf,0,len);//写入目标文件夹
            }
        }
        catch (Exception e)
        {
       e.printStackTrace();
        }
        finally {
            try {
                Fis.close();//关闭流
                Fos.flush();//刷新流
                Fos.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

三、多线程实现文件复制

 public static void main(String args[])
    {
        Scanner scan=new Scanner(System.in);
        System.out.println("要复制的文件夹:");
        String SourceFilePath=scan.next();
        System.out.println("要复制到哪里去:");
        String TargetFilePath=scan.next();
        File SourceFile=new File(SourceFilePath);
        File TargetFile=new File(TargetFilePath);
         new  Thread(){//多线程实现文件的复制
           public void run() {
               if (SourceFile.isFile()) {
                   System.out.println("复制单个文件");
                   Copy(SourceFile, TargetFile);
               }
               else {
                List<File> FileLists=GetAllFiles(SourceFilePath);//获取全部文件
                   ExecutorService threadpool=Executors.newFixedThreadPool(20);//启用线程池,设定线程数量为20
                   for (File file:FileLists)
                   {
                       String PrimaryPath=file.getPath();//原文件路径
                       String NewPath=PrimaryPath.replace(SourceFile.getParent(),TargetFilePath+"/");//更改为新路径
                       System.out.println(PrimaryPath+ "变成了" + NewPath);
                       if (file.isDirectory())
                       {//文件夹则可以直接创建文件目录
                           new File(NewPath).mkdirs();
                       }
                       else {
                           threadpool.execute(new Runnable() {
                               @Override
                               public void run() {//重写方法
                                   File copyfile=new File(NewPath);
                                    copyfile.getParentFile().mkdirs();//先要有父文件夹
                                    Copy(file,copyfile);//复制文件
                               }
                           });
                       }
                   }
               }
           }
    }.start();
    }

四、完整源码+运行结果

package FileTest;
import java.util.concurrent.Executors;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
public class Test6 {
    public static void main(String args[])
    {
        Scanner scan=new Scanner(System.in);
        System.out.println("要复制的文件夹:");
        String SourceFilePath=scan.next();
        System.out.println("要复制到哪里去:");
        String TargetFilePath=scan.next();
        File SourceFile=new File(SourceFilePath);
        File TargetFile=new File(TargetFilePath);
         new  Thread(){//多线程实现文件的复制
           public void run() {
               if (SourceFile.isFile()) {
                   System.out.println("复制单个文件");
                   Copy(SourceFile, TargetFile);
               }
               else {
                List<File> FileLists=GetAllFiles(SourceFilePath);//获取全部文件
                   ExecutorService threadpool=Executors.newFixedThreadPool(20);//启用线程池,设定线程数量为20
                   for (File file:FileLists)
                   {
                       String PrimaryPath=file.getPath();//原文件路径
                       String NewPath=PrimaryPath.replace(SourceFile.getParent(),TargetFilePath+"/");//更改为新路径
                       System.out.println(PrimaryPath+ "变成了" + NewPath);
                       if (file.isDirectory())
                       {//文件夹则可以直接创建文件目录
                           new File(NewPath).mkdirs();
                       }
                       else {
                           threadpool.execute(new Runnable() {
                               @Override
                               public void run() {//重写方法
                                   File copyfile=new File(NewPath);
                                    copyfile.getParentFile().mkdirs();//先要有父文件夹
                                    Copy(file,copyfile);//复制文件
                               }
                           });
                       }
                   }
               }
           }
    }.start();
    }
    public static void Copy(File Source,File Target)//使用IO流进行文件的复制操作
    {
        FileInputStream Fis=null;//输入流
        FileOutputStream Fos=null;//输出流
        try {
            Fis=new FileInputStream(Source);
            Fos=new FileOutputStream(Target);
            byte buf[]=new byte[1024];//每次传送的字节数量
            int len=0;
            while ((len=Fis.read(buf))!=-1)//如果还有字节则继续传送
            {
                Fos.write(buf,0,len);//写入目标文件夹
            }
        }
        catch (Exception e)
        {
       e.printStackTrace();
        }
        finally {
            try {
                Fis.close();//关闭流
                Fos.flush();//刷新流
                Fos.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    public static List GetAllFiles(String SourceFile)//获取所有文件
    {
        List<File> FileList=new ArrayList<>();//文件列表
        File file=new File(SourceFile);//获取源文件
        if (file.exists()&&file.isDirectory()) {//如果文件存在且是文件夹形式则进行递归
            FileList = LongEegodic(file, FileList);
        }
        return FileList;
    }
    public static List LongEegodic(File file,List res)//递归获取文件、文件夹
    {
        File filelist[]=file.listFiles();
        if (filelist==null)
            return null;
        for (File file1:filelist)
        {
            res.add(file1);
            LongEegodic(file1,res);
        }
        return res;
    }
}

结果:

发文不易,恳请大佬们高抬贵手!


点赞:随手点赞是种美德,是大佬们对于本人创作的认可!


评论:往来无白丁,是你我交流的的开始!


收藏:愿君多采撷,是大佬们对在下的赞赏!

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
如果你需要在Java中使用多线程进行IO操作,可以使用Java线程池和Java NIO(New IO)库。以下是一个使用线程池和NIO库进行文件导出的示例代码: ```java import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Exporter { public static void main(String[] args) { // 创建线程池 ExecutorService pool = Executors.newFixedThreadPool(10); // 定义文件路径和文件名 final String filePath = "/path/to/file"; final String fileName = "file.txt"; // 为每个线程分配写入文件的位置 final int blockSize = 1024 * 1024; // 1MB final long fileSize = 1024 * 1024 * 1024; // 1GB int blockCount = (int) (fileSize / blockSize); for (int i = 0; i < blockCount; i++) { final int blockIndex = i; pool.execute(new Runnable() { @Override public void run() { try { // 创建文件通道 RandomAccessFile file = new RandomAccessFile(filePath + fileName, "rw"); FileChannel channel = file.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(blockSize); // 写入数据 long position = blockIndex * blockSize; for (int j = 0; j < blockSize; j++) { buffer.put((byte) (position + j)); } buffer.flip(); channel.write(buffer, position); // 关闭文件通道 channel.close(); file.close(); } catch (IOException e) { e.printStackTrace(); } } }); } // 关闭线程池 pool.shutdown(); } } ``` 在上述代码中,我们使用了一个线程池来管理多个线程,每个线程负责写入文件的一个固定大小的块。我们使用NIO库来读写文件,这样可以提高IO性能。请注意,我们使用的是随机访问文件(RandomAccessFile),这使得我们可以在文件中定位并写入特定位置的字节。在实际应用中,你需要根据实际需求来调整块的大小和线程数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kook小辉的进阶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值