java document元素复制_java实现File的拷贝(Document learning —five)

1. 通过字节流实现文件的拷贝

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过字节流实现文件的拷贝

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByStream(String sourcePath,String targetPath){//源文件路径

File source = newFile(sourcePath);//目标文件路径

File target = newFile(targetPath);//如果源文件不存在则不能拷贝

if(!source.exists()){return;

}//如果目标文件目录不存在则创建

if(!target.getParentFile().exists()){

target.getParentFile().mkdirs();

}try{//实现文件的拷贝

InputStream inputStream = newFileInputStream(source);

OutputStream outputStream= newFileOutputStream(target);int temp = 0;//每次读取1024个字节

byte[] data = new byte[1024];//将每次读取的数据保存到字节数组里面,并且返回读取的个数

while ((temp = inputStream.read(data)) != -1){//输出数组

outputStream.write(data,0,temp);

}

inputStream.close();

outputStream.close();

}catch(IOException e) {

e.printStackTrace();

}

}

View Code

2. 通过字符流实现文件拷贝(使用字符流只能拷贝文本文件)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过字符流实现文件的拷贝

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByReaderAndWriter(String sourcePath, String targetPath) {//源文件路径

File source = newFile(sourcePath);//目标文件路径

File target = newFile(targetPath);//如果源文件不存在则不能拷贝

if (!source.exists()) {return;

}//如果目标文件目录不存在则创建

if (!target.getParentFile().exists()) {

target.getParentFile().mkdirs();

}

FileReader in= null;

FileWriter out= null;try{//字符输入流和字符输出流

in = newFileReader(source);

out= newFileWriter(target);char[] c = new char[1024];int temp = 0;//每次读取1024个字符

while ((temp = in.read(c)) != -1) {//输出到文件

out.write(c, 0, temp);

}

}catch(IOException e) {

e.printStackTrace();

}finally{//关闭流

try{if (in != null) {

in.close();

}if (out != null) {

out.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

3. 通过字节缓冲流实现文件拷贝

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过字节缓冲流实现文件的拷贝

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByBuffered(String sourcePath, String targetPath){//源文件路径

File source = newFile(sourcePath);//目标文件路径

File target = newFile(targetPath);//如果源文件不存在则不能拷贝

if (!source.exists()) {return;

}//如果目标文件目录不存在则创建

if (!target.getParentFile().exists()) {

target.getParentFile().mkdirs();

}

InputStream in= null;

OutputStream out= null;try{//字节缓冲输入流和字节缓冲输出流

in = new BufferedInputStream(newFileInputStream(source));

out= new BufferedOutputStream(newFileOutputStream(target));byte[] b = new byte[1024];int temp = 0;//每次读取一个1024的字节数组

while((temp = in.read(b)) != -1){//输出到文件

out.write(b,0,temp);

}

}catch(Exception e) {

e.printStackTrace();

}finally{//关闭流

try{if (in != null) {

in.close();

}if (out != null) {

out.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

4. 通过字符缓冲流拷贝文件(字符缓冲流只能读取文本文件)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过字符缓冲流实现文件的拷贝

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByBufferedChar(String sourcePath, String targetPath){//源文件路径

File source = newFile(sourcePath);//目标文件路径

File target = newFile(targetPath);//如果源文件不存在则不能拷贝

if (!source.exists()) {return;

}//如果目标文件目录不存在则创建

if (!target.getParentFile().exists()) {

target.getParentFile().mkdirs();

}

BufferedReader in= null;

BufferedWriter out= null;try{//字符缓冲输入流和字符缓冲输出流

in = new BufferedReader(newFileReader(source));

out= new BufferedWriter(newFileWriter(target));//读取文件(每次读取一行)

String temp = null;while((temp = in.readLine()) != null){//输出到文件

out.write(temp);

}

}catch(Exception e) {

e.printStackTrace();

}finally{//关闭流

try{if (in != null) {

in.close();

}if (out != null) {

out.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

5. 通过JAVA NIO 非直接缓冲区拷贝文件

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过JAVA NIO 非直接缓冲区拷贝文件

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByChannel(String sourcePath, String targetPath) {

FileChannel outChannel= null;

FileChannel inChannel= null;

FileInputStream fis= null;

FileOutputStream fos= null;try{

fis= newFileInputStream(sourcePath);

fos= newFileOutputStream(targetPath);//获取通道

inChannel =fis.getChannel();

outChannel=fos.getChannel();//分配指定大小的缓冲区

ByteBuffer buf = ByteBuffer.allocate(1024);while (inChannel.read(buf) != -1) {//转换为读取数据模式

buf.flip();//写入到磁盘

outChannel.write(buf);//清空缓冲区

buf.clear();

}

}catch(Exception e) {

e.printStackTrace();

}finally{//关闭流

try{if (outChannel != null) {

outChannel.close();

}if (inChannel != null) {

inChannel.close();

}if (fis != null) {

fis.close();

}if (fos != null) {

fos.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

6. 通过JAVA NIO 直接缓冲区拷贝文件

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过JAVA NIO 直接缓冲区拷贝文件(内存映射文件)

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByChannelBufferd(String sourcePath, String targetPath) {

FileChannel inChannel= null;

FileChannel outChannel= null;try{//获取通道,StandardOpenOption.READ表示可读,StandardOpenOption.WRITE表示可写,StandardOpenOption.CREATE表示可以创建

inChannel =FileChannel.open(Paths.get(sourcePath), StandardOpenOption.READ);

outChannel=FileChannel.open(Paths.get(targetPath), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);//创建内存映射文件

MappedByteBuffer inMapped = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());

MappedByteBuffer outMapped= outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());//直接操作内存映射文件

byte[] buf = new byte[inMapped.limit()];

inMapped.get(buf);

outMapped.put(buf);

}catch(IOException e) {

e.printStackTrace();

}finally{//关闭流

try{if (outChannel != null) {

outChannel.close();

}if (inChannel != null) {

inChannel.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

7. 通过JAVA NIO 通道传输拷贝文件

方式一:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过JAVA NIO 通道传输拷贝文件

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByChannelTransfer(String sourcePath, String targetPath) {

FileChannel inChannel= null;

FileChannel outChannel= null;try{//获取通道

inChannel =FileChannel.open(Paths.get(sourcePath), StandardOpenOption.READ);

outChannel=FileChannel.open(Paths.get(targetPath),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

inChannel.transferTo(0,inChannel.size(),outChannel);

}catch(IOException e) {

e.printStackTrace();

}finally{//关闭流

try{if (outChannel != null) {

outChannel.close();

}if (inChannel != null) {

inChannel.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

方式二:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 通过JAVA NIO 通道传输拷贝文件

*

*@paramsourcePath 源文件路径

*@paramtargetPath 目标文件路径*/

public static voidcopyFileByChannelTransfer2(String sourcePath, String targetPath) {

FileInputStream fis= null;

FileOutputStream fos= null;

FileChannel inChannel= null;

FileChannel outChannel= null;try{

fis= newFileInputStream(sourcePath);

fos= newFileOutputStream(targetPath);//获取通道

inChannel =fis.getChannel();

outChannel=fos.getChannel();

inChannel.transferTo(0,inChannel.size(),outChannel);

}catch(IOException e) {

e.printStackTrace();

}finally{//关闭流

try{if (outChannel != null) {

outChannel.close();

}if (inChannel != null) {

inChannel.close();

}

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

使用示例:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

String source = "e:\\demo\\纵天神帝.txt";

String target= "e:\\demo\\";long time1 =System.currentTimeMillis();

copyFileByStream(source, target+ "1.txt");

System.out.println("通过字节流实现文件的拷贝耗时:" + (System.currentTimeMillis() -time1));long time2 =System.currentTimeMillis();

copyFileByReaderAndWriter(source, target+ "2.txt");

System.out.println("通过字符流实现文件的拷贝耗时:" + (System.currentTimeMillis() -time2));long time3 =System.currentTimeMillis();

copyFileByBuffered(source, target+ "3.txt");

System.out.println("通过字节缓冲流实现文件的拷贝耗时:" + (System.currentTimeMillis() -time3));long time4 =System.currentTimeMillis();

copyFileByBufferedChar(source, target+ "4.txt");

System.out.println("通过字符缓冲流实现文件的拷贝耗时:" + (System.currentTimeMillis() -time4));long time5 =System.currentTimeMillis();

copyFileByChannel(source, target+ "5.txt");

System.out.println("通过JAVA NIO通道(非直接缓冲区)实现文件的拷贝耗时:" + (System.currentTimeMillis() -time5));long time6 =System.currentTimeMillis();

copyFileByChannelBufferd(source, target+ "6.txt");

System.out.println("通过JAVA NIO通道(直接缓冲区)实现文件的拷贝耗时:" + (System.currentTimeMillis() -time6));long time7 =System.currentTimeMillis();

copyFileByChannelTransfer(source, target+ "7.txt");

System.out.println("通过JAVA NIO通道传输实现文件的拷贝耗时:" + (System.currentTimeMillis() -time7));long time8 =System.currentTimeMillis();

copyFileByChannelTransfer(source, target+ "8.txt");

System.out.println("通过JAVA NIO通道传输2实现文件的拷贝耗时:" + (System.currentTimeMillis() - time8));

View Code

通过测试发现,使用JAVA NIO通道传输、JAVA NIO通道直接缓冲区以及字节缓冲流拷贝文件效率最高

在java中,FileChannel类中有一些优化方法可以提高传输的效率,其中transferTo( )和 transferFrom( )方法允许将一个通道交叉连接到另一个通道,而不需要通过一个缓冲区来传递数据。只有FileChannel类有这两个方法,因此 channel-to-channel 传输中通道之一必须是 FileChannel。不能在sock通道之间传输数据,不过socket 通道实现WritableByteChannel 和 ReadableByteChannel 接口,因此文件的内容可以用 transferTo( )方法传输给一个 socket 通道,或者也可以用 transferFrom( )方法将数据从一个 socket 通道直接读取到一个文件中。

Channel-to-channel 传输是可以极其快速的,特别是在底层操作系统提供本地支持的时候。某些操作系统可以不必通过用户空间传递数据而进行直接的数据传输。对于大量的数据传输,这会是一个巨大的帮助。

注意:如果要拷贝的文件大于4G,则不能直接用Channel-to-channel 的方法,替代的方法是使用ByteBuffer,先从原文件通道读取到ByteBuffer,再将ByteBuffer写到目标文件通道中。

下面为实现大文件快速拷贝的代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.newflows.notify.test;importjava.io.File;importjava.io.IOException;importjava.io.RandomAccessFile;importjava.nio.channels.FileChannel;public classBigFileCopy {/*** 通过channel到channel直接传输

*@paramsource

*@paramdest

*@throwsIOException*/

public static void copyByChannelToChannel(String source, String dest) throwsIOException {

File source_tmp_file= newFile(source);if (!source_tmp_file.exists()) {return;

}

RandomAccessFile source_file= new RandomAccessFile(source_tmp_file, "r");

FileChannel source_channel=source_file.getChannel();

File dest_tmp_file= newFile(dest);if (!dest_tmp_file.isFile()) {if (!dest_tmp_file.createNewFile()) {

source_channel.close();

source_file.close();return;

}

}

RandomAccessFile dest_file= new RandomAccessFile(dest_tmp_file, "rw");

FileChannel dest_channel=dest_file.getChannel();long left_size =source_channel.size();long position = 0;while (left_size > 0) {long write_size =source_channel.transferTo(position, left_size, dest_channel);

position+=write_size;

left_size-=write_size;

}

source_channel.close();

source_file.close();

dest_channel.close();

dest_file.close();

}public static voidmain(String[] args) {try{long start_time =System.currentTimeMillis();

BigFileCopy.copyByChannelToChannel("E:\\BaiduNetdiskDownload\\PowerDesigner安装包.rar", "E:\\BaiduNetdiskDownload\\dest_file.rar");long end_time =System.currentTimeMillis();

System.out.println("copy time = " + (end_time -start_time));

}catch(IOException e) {

e.printStackTrace();

}

}

}

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值