package com.pangwen.usefultools.io; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * 文件拷贝工具类 * Created on 2017/4/18. * * @author pangwen * @version 0.1 */public final class FileCopyUtils { /** * 大于500M的文件为大文件 */ private static final long BIG_FILE_SIZE = 1024 * 1024 * 500; /** * byte[]默认长度为1024 */ private static final int BUFFER_SIZE = 1024; /** * 最大线程数 */ private static final int MAX_THREAD_NUM = 5; /** * 静态内部类实现多线程 */ private static class FileCopyWorker implements Runnable { private final File srcFile; private final File targetFile; private final long startPosition; private final long endPosition; /** * constructor * * @param srcFile 源文件 * @param targetFile 目标文件 * @param startPosition 文件开始位置 * @param endPosition 文件结束位置 */ public FileCopyWorker(final File srcFile, final File targetFile, final long startPosition, final long endPosition) { this.srcFile = srcFile; this.targetFile = targetFile; this.startPosition = startPosition; this.endPosition = endPosition; } //@Override public void run() { RandomAccessFile rin = null; RandomAccessFile rout = null; try { rin = new RandomAccessFile(srcFile, "r"); rin.seek(startPosition); rout = new RandomAccessFile(targetFile, "rw"); rout.seek(startPosition); byte[] buffer = new byte[BUFFER_SIZE]; int i; int readLength = 0; while ((i = rin.read(buffer)) != -1 && startPosition + readLength <= endPosition) { rout.write(buffer, 0, i); readLength += i; } } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != rin) rin.close(); } catch (Exception e) { e.printStackTrace(); } try { if (null != rout) rout.close(); } catch (Exception e) { e.printStackTrace(); } } } } /** * nio拷贝文件 * * @param srcFile 源文件 * @param targetFile 目标文件 */ public static void copyFileNio(final File srcFile, final File targetFile) throws FileNotFoundException { if (null == srcFile) throw new FileNotFoundException("src file not found!"); makeParentDirs(targetFile); FileInputStream in = new FileInputStream(srcFile); FileOutputStream out = new FileOutputStream(targetFile); //获取通道 FileChannel inChannel = null; FileChannel outChannel = null; try { inChannel = in.getChannel(); outChannel = out.getChannel(); //创建缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); //将数据读入缓冲区 while (inChannel.read(buffer) != -1) { //flip() 方法让缓冲区可以将新读入的数据写入另一个通道。 buffer.flip(); //将缓冲区数据写入文件 outChannel.write(buffer); //clear() 方法重设缓冲区,使它可以接受读入的数据。 buffer.clear(); } } catch (IOException e) { e.printStackTrace(); } finally { if (inChannel != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (outChannel != null) { try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 拷贝文件 * * @param srcFile 源文件 * @param targetFile 目标文件 * @param allowMultipleThread 是否开启多线程 * @throws FileNotFoundException */ public static void copyFile(final File srcFile, final File targetFile, final boolean allowMultipleThread) throws FileNotFoundException { if (null == srcFile) throw new FileNotFoundException("src file not found!"); //创建父文件夹 makeParentDirs(targetFile); long srcFileLength = srcFile.length(); if (allowMultipleThread && srcFileLength > BIG_FILE_SIZE) { try { //大文件调用多线程 copyFileMultipleThread(srcFile, targetFile); return; } catch (Exception e) { e.printStackTrace(); //多线程拷贝文件失败时调用单线程拷贝文件 copyFile(srcFile, targetFile, false); } } FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream(srcFile); out = new FileOutputStream(targetFile); byte[] buffer = new byte[BUFFER_SIZE]; int i; while ((i = in.read(buffer)) != -1) { out.write(buffer, 0, i); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != in) in.close(); } catch (Exception e) { e.printStackTrace(); } try { if (null != out) out.close(); } catch (Exception e) { e.printStackTrace(); } } } /** * 多线程拷贝文件 RandomAccessFile * * @param srcFile 源文件 * @param targetFile 目标文件 */ private static void copyFileMultipleThread(final File srcFile, final File targetFile) { final long srcFileLength = srcFile.length(); int threadNum = (int) (srcFileLength / BIG_FILE_SIZE); if (threadNum > MAX_THREAD_NUM) threadNum = MAX_THREAD_NUM; long residuumFileLength = srcFileLength % threadNum; //每份文件大小 long perFileSize = (srcFileLength - residuumFileLength) / threadNum; //开始位置 long startPosition = 0; //结束位置 long endPosition = perFileSize; for (int i = 0; i < threadNum; i++) { new Thread(new FileCopyWorker(srcFile, targetFile, startPosition, endPosition)).start(); //下一现场读取文件开始位置 startPosition = endPosition + 1; //下一现场读取文件结束位置 endPosition += perFileSize; //最后一个线程读取到文件末 if (i == threadNum - 2) endPosition = srcFileLength; } } private static void makeParentDirs(final File file) throws FileNotFoundException { if (null == file) throw new FileNotFoundException("target file must not be null!"); File parent = file.getParentFile(); if (!parent.exists()) parent.mkdirs(); } private FileCopyUtils() { throw new IllegalAccessError("can not create instance!"); } }
近期热议
推荐标签 标签
-
Python
556 引用 • 674 回帖
Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。
-
Quicker
36 引用 • 155 回帖 • 1 关注
Quicker 您的指尖工具箱!操作更少,收获更多!
-
TextBundle
1 引用 • 2 回帖 • 76 关注
TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。
-
Lute
28 引用 • 197 回帖 • 25 关注
Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。
-
HBase
17 引用 • 6 回帖 • 62 关注
HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。
-
Maven
186 引用 • 318 回帖 • 262 关注
Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。
-
Jenkins
54 引用 • 37 回帖
Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。
-
ReactiveX
1 引用 • 2 回帖 • 175 关注
ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。
-
又拍云
20 引用 • 37 回帖 • 570 关注
又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。
-
游戏
180 引用 • 821 回帖
沉迷游戏伤身,强撸灰飞烟灭。
-
InfluxDB
2 引用 • 85 关注
InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。
-
RESTful
30 引用 • 114 回帖 • 6 关注
一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
-
外包
26 引用 • 233 回帖 • 1 关注
有空闲时间是接外包好呢还是学习好呢?
-
微软
8 引用 • 44 回帖 • 1 关注
微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。
-
DNSPod
6 引用 • 26 回帖 • 528 关注
DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。
-
NetBeans
78 引用 • 102 回帖 • 701 关注
NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。
-
持续集成
15 引用 • 7 回帖
持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
-
Webswing
1 引用 • 15 回帖 • 638 关注
Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用 。
-
Laravel
20 引用 • 23 回帖 • 737 关注
Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。
-
Kubernetes
116 引用 • 54 回帖 • 5 关注
Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。
-
架构
143 引用 • 442 回帖
我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。
-
脑图
31 引用 • 96 回帖
脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。
-
AngularJS
12 引用 • 50 回帖 • 500 关注
AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。
-
OpenShift
14 引用 • 20 回帖 • 650 关注
红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。
-
友情链接
24 引用 • 373 回帖
确认过眼神后的灵魂连接,站在链在!
-
Flume
9 引用 • 6 回帖 • 651 关注
Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。
-
WebComponents
1 引用 • 8 关注
Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于