广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java利用多线程复制文件
  • 104
分享到

Java利用多线程复制文件

2024-04-02 19:04:59 104人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

前言 复制一个文件,是学习io流时最基本的操作。你可以使用字节型文件流,也可以使用高级缓冲流。 但是,它们都是单线程的。 如果需要复制一个大型文件,单线程的复制一般而言是不能够充分发

前言

复制一个文件,是学习io流时最基本的操作。你可以使用字节型文件流,也可以使用高级缓冲流。

但是,它们都是单线程的。

如果需要复制一个大型文件,单线程的复制一般而言是不能够充分发挥CPU以及内存的性能。这时候就需要利用多线程来复制文件。

多线程的读:

我们很自然地想到,利用FileInputStream类的skip()方法,可以跳着读,这就对多线程比较友好,启动多个线程,第一个线程读一部分,第二个线程跳过一部分字节再读,这没有问题。

但是如果要写呢?我们知道FileOutputStream类是没有与skip类似的方法的,也就是说,它不能跳着写,这就很麻烦。

这就意味着,如果需要利用多线程复制一个文件,那么首先得把这个文件利用多线程并发,读取并同时写入成多个文件碎片,然后再利用单线程去一一读取这些文件碎片,把它们的内容写入到一个完整的文件中。必要的话,最后再删除这些中间文件碎片。

这个过程,复杂,且性能不高。涉及到两套读写,前面多线程读写,后面单线程读写。很显然这个过程虽然使用到了多线程但它不能提高性能,反而降低了性能。

既然鸡肋点在于FileOutputStream不能跳着写,那么就找一个能跳着写的类吧。

RandomAccessFile

RandoMaccessFile是java Io体系中功能最丰富的文件内容访问类。即可以读取文件内容,也可以向文件中写入内容。但是和其他输入/输入流不同的是,程序可以直接跳到文件的任意位置来读写数据。

RandomAccessFile包含了以下两个方法来操作文件的记录指针:

  • long getFilePointer(); 返回文件记录指针的当前位置
  • void seek(long pos); 将文件记录指针定位到pos位置

有了RandomAccessFile这个类,上面的问题就迎刃而解,因为它最大的好处就是可以实现从指定位置写入一些数据到文件中!

顺便说一下它的构造方法:

  • RandomAccessFile(File file, String mode)
  • RandomAccessFile(String name, String mode)

mode表示RandomAccessFile的访问模式,她有4个值:

  • “r”:只有读的权限,如果你试图去执行写入方法,则抛出IOException异常。
  • “rw”:有读和写 两个权限,如果该文件不存在,则会创建该文件。
  • “rws”:相对于”rw” 模式,还要求对文件内容或元数据的每个更新都同步写入到底层设备。
  • “rwd”:相对于”rw” 模式,还要求对文件内容每个更新都同步写入到底层设备。

一般而言我们使用“r”和“rw”就够了,后面那两个我也不懂干嘛的。

代码

package testThread.file_threading;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

public class ThreadFileCopy extends Thread {
    private String srcFileStr;//源文件的路径
    private String desFileStr;//目标文件的路径 ,des --> destination目的地
    private long skipLen;//跳过多少个字节开始读/写
    private long workload;//总共要读/写多少个字节
    private final int IO_UNIT = 1024;//每次读写的基本单位(1024个字节)

    public ThreadFileCopy(String srcFileStr, String desFileStr, long skipLen, long workload) {
        this.srcFileStr = srcFileStr;
        this.desFileStr = desFileStr;
        this.skipLen = skipLen;
        this.workload = workload;
    }
    public void run(){
        FileInputStream fis = null;
        BufferedInputStream bis = null;//利用高级缓冲流,加快读的速度
        RandomAccessFile raf = null;
        try {
            fis = new FileInputStream(srcFileStr);
            bis = new BufferedInputStream(fis);
            raf = new RandomAccessFile(desFileStr,"rw");
            bis.skip(this.skipLen);//跳过一部分字节开始读
            raf.seek(this.skipLen);//跳过一部分字节开始写
            byte[] bytes = new byte[IO_UNIT];
            //根据总共需要复制的字节数 和 读写的基本单元 计算出一共需要读写的次数,利用读写次数控制循环
            long io_num = this.workload/IO_UNIT + 1;//因为workload/1024 很可能不能整除,会有余数
            if(this.workload % IO_UNIT == 0)
                io_num--;//如果碰巧整除,读写次数减一
            //count表示读取的有效字节数,虽然count不参与控制循环结束,
            // 但是它能有效避免最后一次读取出的byte数组中有大量空字节写入到文件中,导致复制出的文件稍稍变大
            int count = bis.read(bytes);
            while (io_num != 0){
                raf.write(bytes,0,count);
                count = bis.read(bytes,0,count);//重新计算count的值
                io_num--;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bis != null)
                    bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (raf != null)
                    raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

测试

package testThread.file_threading;

import java.io.File;

public class TestMain {
    public static void main(String[] args) {
        int thread_num = 5;//创建5个线程读写
        String srcFileStr = "E:\\test\\123.flv";
        String desFileStr = "E:\\test\\thread.flv";
        File srcFile = new File(srcFileStr);
        long workload = srcFile.length()/thread_num;//总共要读/写多少个字节
        //用一个数组来存储每个线程跳过的字节数
        long[] skipLenArr = new long[thread_num];
        for(int i = 0;i<skipLenArr.length;i++){
            skipLenArr[i] = i*workload;
        }
        //用一个数组来存储所有的线程
        ThreadFileCopy[] tfcs = new ThreadFileCopy[thread_num];
        //初始化所有线程
        for(int i = 0;i<tfcs.length;i++){
            tfcs[i] = new ThreadFileCopy(srcFileStr,desFileStr,skipLenArr[i],workload);
        }
        //让所有线程进入就绪状态
        for(int i = 0;i<tfcs.length;i++){
            tfcs[i].start();
        }
        System.out.println("复制完毕!");
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Java利用多线程复制文件

本文链接: https://www.lsjlt.com/news/167705.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java利用多线程复制文件
    前言 复制一个文件,是学习IO流时最基本的操作。你可以使用字节型文件流,也可以使用高级缓冲流。 但是,它们都是单线程的。 如果需要复制一个大型文件,单线程的复制一般而言是不能够充分发...
    99+
    2022-11-13
  • Java多线程实现复制文件
    本文实例为大家分享了Java多线程实现复制文件的具体代码,供大家参考,具体内容如下 代码实现如下: package com.tulun.thread; import java.i...
    99+
    2022-11-13
  • Java文件复制多种方法
    InputStream与OutputStream  创建两个文件 - 源和目标。然后我们从源创建InputStream并使用OutputStream将其写入目标文件进行 java 复制文件操作。 private static void ...
    99+
    2023-10-27
    java jvm c++
  • win7系统使用多线程加快文件复制与传输
      为什么没办法在 Windows 7 下加快 Windows 7 中文件复制/传输功能呢可以用 robocopy 实现多线程文件复制。   经常进行文件管理操作的朋友们,提到复制/粘贴操作,深度系统下载想必很多人还会回...
    99+
    2023-05-31
    win7 多线程 文件复制 传输 系统 文件
  • 怎么在Java中利用IO流复制文件
    这期内容当中小编将会给大家带来有关怎么在Java中利用IO流复制文件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3....
    99+
    2023-06-14
  • 怎么在Java中利用socket多线程访问服务器文件
    今天就跟大家聊聊有关怎么在Java中利用socket多线程访问服务器文件,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。ServerMain.javapackage com....
    99+
    2023-05-30
    java socket 多线程
  • 控制文件多路复用
    控制文件是oracle数据库中最重要的文件之一。它记录了数据库的名称及其他关键配置,也记录了当前数据库中所有的数据文件和日志文件的位置及状态等重要信息,是数据库启动过程中必须查找并且使用的关键文件。默认情况...
    99+
    2022-10-18
  • 浅谈一下Java多线程断点复制
    目录细节介绍代码部分定时任务类记录信息类复制线程类复制工具类总结上次写了一个利用 RandomAccessFile 和 多线程实现的多线程复制,但是没有增加断点复制的功能。这里的断点...
    99+
    2023-05-15
    Java多线程 Java断点 Java断点复制
  • 在Java项目中如何利用多线程实现文件下载功能
    这篇文章将为大家详细讲解有关在Java项目中如何利用多线程实现文件下载功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。具体内容如下import java.io.File; import j...
    99+
    2023-05-31
    java 多线程 文件下载
  • java实现系统多级文件夹复制
    本文实例为大家分享了java实现系统多级文件夹复制的具体代码,供大家参考,具体内容如下 package com.jae; import java.io.*; //复制文件夹内...
    99+
    2022-11-12
  • Java多线程断点复制的方法是什么
    这篇文章主要介绍了Java多线程断点复制的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java多线程断点复制的方法是什么文章都会有所收获,下面我们一起来看看吧。细节介绍我这里是使用一个Timer类(...
    99+
    2023-07-06
  • Java中怎么利用多线程信号量控制相关资源
    这期内容当中小编将会给大家带来有关Java中怎么利用多线程信号量控制相关资源,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java多线程信号量如何才能更好的控制相关的数据量?这个问题需要我们就详细的介绍下...
    99+
    2023-06-17
  • 怎么在java中利用多线程执行多个程序
    这期内容当中小编将会给大家带来有关怎么在java中利用多线程执行多个程序,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于...
    99+
    2023-06-14
  • 利用JAVA实现一个多线程爬虫
    利用JAVA实现一个多线程爬虫?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。JAVA 多线程爬虫实例详解前言以前喜欢Python的爬虫是出于他的简洁,但到了后期...
    99+
    2023-05-31
    java 多线程 爬虫
  • Java多线程实现FTP批量上传文件
    本文实例为大家分享了Java多线程实现FTP批量上传文件的具体代码,供大家参考,具体内容如下 1、构建FTP客户端 package cn.com.pingtech.common.ft...
    99+
    2022-11-13
  • java实现多线程文件的断点续传
    java文件的多线程断点续传大致原理,供大家参考,具体内容如下 谈到文件断点续传那么就离不开java.io.RandomAcessFile HttpUrlConnection类 大致...
    99+
    2022-11-13
  • 怎么在JAVA中利用多线程抢红包
    这篇文章给大家介绍怎么在JAVA中利用多线程抢红包,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。代码实现import java.util.Random;import java.util.Scanne...
    99+
    2023-06-14
  • Java中怎么利用多线程处理任务
    这篇文章将为大家详细讲解有关Java中怎么利用多线程处理任务,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.直接传递一批任务给到多线程处理方法,返回处理结果代码如下: publi...
    99+
    2023-06-17
  • 详解Java线程池是如何重复利用空闲线程的
    在Java开发中,经常需要创建线程去执行一些任务,实现起来也非常方便,但如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率...
    99+
    2022-11-12
  • WxPython界面利用pubsub如何实现多线程控制
    目录WxPython界面用pubsub实现多线程控制下面提供本文的代码WxPython界面用pubsub实现多线程控制 用WxPython做界面时, 如果数据操作时间比较长,会使 W...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作