博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java实现文件拷贝
阅读量:6404 次
发布时间:2019-06-23

本文共 10067 字,大约阅读时间需要 33 分钟。

经过一组简单的测试发现JAVA NIO提供的文件内存映射方法实现文件拷贝速度最快,不管是大文件还是小文件,特别是大文件的拷贝速度比普通方法提高20倍,唯一有个前提就是内存需要足够大,否则文件映射肯定失败(当然可以通过分割文件,部分映射的方法避免,但就比较麻烦了);其次NIO提供的文件管道传输速度也比较好,如果没法做文件内存映射,推荐这种拷贝方法;另外,Buffer的大小,对于读写速度还是有影响的,基本就是Buffer越大读写越快(有个疑问就是Buffer.allocateDirec()效率提高不明显);最后,总体看来NIO的效率比老IO高,不管使用哪种方式,老IO使用流读写只能一个字节一个字节的抠,NIO使用块的方式读写还是相对比较快,所以没有特别需求的情况下,推荐使用NIO,目前NIO基本能覆盖老IO的所有功能(当然NIO还提供N多新功能)。

  • 测试环境

1
2
3
4
5
6
7
8
9
Eclipse(Juno) JVM(Sun JDK1.
7
) 参数:
-Xms1536m
-Xmx1536m
-Xverify:none -XX:+UseParallelGC
-XX:PermSize=128M
-XX:MaxPermSize=128M
OS参数:
Win7 64Bit + 4GB
物理磁盘空间充足

  • 测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import 
java.io.FileInputStream;
import 
java.io.FileNotFoundException;
import 
java.io.FileOutputStream;
import 
java.io.IOException;
import 
java.io.RandomAccessFile;
import 
java.nio.ByteBuffer;
import 
java.nio.MappedByteBuffer;
import 
java.nio.channels.FileChannel;
public 
class 
FileCopy {
    
private 
static 
final 
int 
BUFFER_SIZE_1024 = 
1024
;
    
private 
static 
final 
int 
BUFFER_SIZE_4096 = 
4096
;
    
private 
static 
final 
int 
BUFFER_SIZE_10240 = 
10240
;
        
    
private 
static 
final 
String FROM_FILE_42MB = 
"G:/from_42MB.rar"
;
    
private 
static 
final 
String FROM_FILE_1GB = 
"G:/from_350MB.rar"
;
        
    
private 
static 
int 
BUFFER_SIZE = BUFFER_SIZE_1024;
    
private 
static 
String FROM_FILE = FROM_FILE_42MB;
    
/**
     
* @param args
     
* @throws Exception
     
*/
    
public 
static 
void 
main(String[] args) 
throws 
Exception {
        
System.out.println(
"File :" 
+ FROM_FILE + 
" ---- Buffer Size : " 
+ BUFFER_SIZE + 
"--------------"
);
        
testFileCopy();
            
        
BUFFER_SIZE = BUFFER_SIZE_4096;
        
System.out.println(
"File :" 
+ FROM_FILE + 
" ---- Buffer Size : " 
+ BUFFER_SIZE + 
"--------------"
);
        
testFileCopy();
            
        
BUFFER_SIZE = BUFFER_SIZE_10240;
        
System.out.println(
"File :" 
+ FROM_FILE + 
" ---- Buffer Size : " 
+ BUFFER_SIZE + 
"--------------"
);
        
testFileCopy();
            
        
BUFFER_SIZE = BUFFER_SIZE_1024;
        
FROM_FILE = FROM_FILE_1GB;
        
System.out.println(
"File :" 
+ FROM_FILE + 
" ---- Buffer Size : " 
+ BUFFER_SIZE + 
"--------------"
);
        
testFileCopy();
            
        
BUFFER_SIZE = BUFFER_SIZE_4096;
        
FROM_FILE = FROM_FILE_1GB;
        
System.out.println(
"File :" 
+ FROM_FILE + 
" ---- Buffer Size : " 
+ BUFFER_SIZE + 
"--------------"
);
        
testFileCopy();
            
        
BUFFER_SIZE = BUFFER_SIZE_10240;
        
FROM_FILE = FROM_FILE_1GB;
        
System.out.println(
"File :" 
+ FROM_FILE + 
" ---- Buffer Size : " 
+ BUFFER_SIZE + 
"--------------"
);
        
testFileCopy();
            
    
}
    
private 
static 
void 
testFileCopy() 
throws 
FileNotFoundException,
            
IOException {
        
coypByMbb();
        
copyByNioTransferFrom();
        
copyByNioTransferTo();
        
coypByBufferRead();
        
coypByFastBufferRead();           
        
coypByStream();
//Old IO style
    
}
    
/**
     
* 使用FileChannel.transferFrom()实现
     
* @throws FileNotFoundException
     
* @throws IOException
     
*/
    
private 
static 
void 
copyByNioTransferFrom() 
throws 
FileNotFoundException,
            
IOException {
        
long 
startTime = System.currentTimeMillis();
        
RandomAccessFile fromFile = 
new 
RandomAccessFile(FROM_FILE, 
"rw"
);
        
FileChannel fromChannel = fromFile.getChannel();
        
RandomAccessFile toFile = 
new 
RandomAccessFile(
"G:/to1.rar"
"rw"
);
        
FileChannel toChannel = toFile.getChannel();
        
long 
position = 
0
;
        
long 
count = fromChannel.size();
        
toChannel.transferFrom(fromChannel, position, count);
        
long 
endTime = System.currentTimeMillis();
        
System.out.println(
"copyByNioTransferFrom time consumed(buffer size no effect) : "
                
+ (endTime - startTime));
    
}
    
/**
     
* 使用FileChannel.transferTo()实现
     
* @throws FileNotFoundException
     
* @throws IOException
     
*/
    
private 
static 
void 
copyByNioTransferTo() 
throws 
FileNotFoundException,
            
IOException {
        
long 
startTime = System.currentTimeMillis();
        
RandomAccessFile fromFile = 
new 
RandomAccessFile(FROM_FILE, 
"rw"
);
        
FileChannel fromChannel = fromFile.getChannel();
        
RandomAccessFile toFile = 
new 
RandomAccessFile(
"G:/to2.rar"
"rw"
);
        
FileChannel toChannel = toFile.getChannel();
        
long 
position = 
0
;
        
long 
count = fromChannel.size();
        
fromChannel.transferTo(position, count, toChannel);
        
long 
endTime = System.currentTimeMillis();
        
System.out.println(
"copyByNioTransferTo time consumed(buffer size no effect) : "
                
+ (endTime - startTime));
    
}
    
/**
     
* 使用Channel, Buffer简单读写实现
     
* @throws IOException
     
*/
    
private 
static 
void 
coypByBufferRead() 
throws 
IOException {
        
long 
startTime = System.currentTimeMillis();
        
FileInputStream fin = 
new 
FileInputStream(FROM_FILE);
        
FileOutputStream fout = 
new 
FileOutputStream(
"G:/to3.rar"
);
        
FileChannel fcin = fin.getChannel();
        
FileChannel fcout = fout.getChannel();
        
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
        
while 
(
true
) {
            
buffer.clear();
            
int 
r = fcin.read(buffer);
            
if 
(r == -
1
) {
                
break
;
            
}
            
buffer.flip();
            
fcout.write(buffer);
        
}
        
long 
endTime = System.currentTimeMillis();
        
System.out.println(
"coypByBufferRead time consumed(buffer size take effect) : "
                
+ (endTime - startTime));
    
}
    
/**
     
* 使用连续内存的Buffer实现
     
* @throws IOException
     
*/
    
private 
static 
void 
coypByFastBufferRead() 
throws 
IOException {
        
long 
startTime = System.currentTimeMillis();
        
FileInputStream fin = 
new 
FileInputStream(FROM_FILE);
        
FileOutputStream fout = 
new 
FileOutputStream(
"G:/to4.rar"
);
        
FileChannel fcin = fin.getChannel();
        
FileChannel fcout = fout.getChannel();
        
ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
        
while 
(
true
) {
            
buffer.clear();
            
int 
r = fcin.read(buffer);
            
if 
(r == -
1
) {
                
break
;
            
}
            
buffer.flip();
            
fcout.write(buffer);
        
}
        
long 
endTime = System.currentTimeMillis();
        
System.out.println(
"coypByFastBufferRead time consumed(buffer size take effect) : "
                
+ (endTime - startTime));
    
}
    
/**
     
* 使用文件内存映射实现
     
* @throws IOException
     
*/
    
private 
static 
void 
coypByMbb() 
throws 
IOException {
        
long 
startTime = System.currentTimeMillis();
        
FileInputStream fin = 
new 
FileInputStream(FROM_FILE);
        
RandomAccessFile fout = 
new 
RandomAccessFile(
"G:/to5.rar"
"rw"
);
        
FileChannel fcin = fin.getChannel();
        
FileChannel fcout = fout.getChannel();
        
MappedByteBuffer mbbi = fcin.map(FileChannel.MapMode.READ_ONLY, 
0
,
                
fcin.size());
        
MappedByteBuffer mbbo = fcout.map(FileChannel.MapMode.READ_WRITE, 
0
,
                
fcin.size());
        
mbbo.put(mbbi);
        
mbbi.clear();
        
mbbo.clear();
        
long 
endTime = System.currentTimeMillis();
        
System.out
                
.println(
"coypByMbb time consumed(buffer size no effect) : " 
+ (endTime - startTime));
    
}
    
/**
     
* 使用传统IO的流读写方式实现
     
* @throws IOException
     
*/
    
private 
static 
void 
coypByStream() 
throws 
IOException {
        
long 
startTime = System.currentTimeMillis();
        
FileInputStream fin = 
new 
FileInputStream(FROM_FILE);
        
FileOutputStream fout = 
new 
FileOutputStream(
"G:/to6.rar"
);
        
byte
[] buffer = 
new 
byte
[BUFFER_SIZE];
        
while 
(
true
) {
            
int 
ins = fin.read(buffer);
            
if 
(ins == -
1
) {
                
fin.close();
                
fout.flush();
                
fout.close();
                
break
;
            
else
{
                
fout.write(buffer, 
0
, ins);
            
}             
        
}
        
long 
endTime = System.currentTimeMillis();
        
System.out.println(
"coypByStream time consumed(buffer size take effect) : " 
+ (endTime - startTime));
    
}
}
  • 测试结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    File :G:/from_42MB.rar ---- Buffer Size : 
    1024
    --------------
    coypByMbb time consumed(buffer size no effect) : 
    47
    copyByNioTransferFrom time consumed(buffer size no effect) : 
    62
    copyByNioTransferTo time consumed(buffer size no effect) : 
    47
    coypByBufferRead time consumed(buffer size take effect) : 
    249
    coypByFastBufferRead time consumed(buffer size take effect) : 
    188
    coypByStream time consumed(buffer size take effect) : 
    187
              
    File :G:/from_42MB.rar ---- Buffer Size : 
    4096
    --------------
    coypByMbb time consumed(buffer size no effect) : 
    15
    copyByNioTransferFrom time consumed(buffer size no effect) : 
    16
    copyByNioTransferTo time consumed(buffer size no effect) : 
    31
    coypByBufferRead time consumed(buffer size take effect) : 
    125
    coypByFastBufferRead time consumed(buffer size take effect) : 
    79
    coypByStream time consumed(buffer size take effect) : 
    93
              
    File :G:/from_42MB.rar ---- Buffer Size : 
    10240
    --------------
    coypByMbb time consumed(buffer size no effect) : 
    16
    copyByNioTransferFrom time consumed(buffer size no effect) : 
    32
    copyByNioTransferTo time consumed(buffer size no effect) : 
    31
    coypByBufferRead time consumed(buffer size take effect) : 
    78
    coypByFastBufferRead time consumed(buffer size take effect) : 
    62
    coypByStream time consumed(buffer size take effect) : 
    63
              
    File :G:/from_350MB.rar ---- Buffer Size : 
    1024
    --------------
    coypByMbb time consumed(buffer size no effect) : 
    280
    copyByNioTransferFrom time consumed(buffer size no effect) : 
    453
    copyByNioTransferTo time consumed(buffer size no effect) : 
    7785
    coypByBufferRead time consumed(buffer size take effect) : 
    8144
    coypByFastBufferRead time consumed(buffer size take effect) : 
    7068
    coypByStream time consumed(buffer size take effect) : 
    8503
              
    File :G:/from_350MB.rar ---- Buffer Size : 
    4096
    --------------
    coypByMbb time consumed(buffer size no effect) : 
    1904
    copyByNioTransferFrom time consumed(buffer size no effect) : 
    5978
    copyByNioTransferTo time consumed(buffer size no effect) : 
    7379
    coypByBufferRead time consumed(buffer size take effect) : 
    7621
    coypByFastBufferRead time consumed(buffer size take effect) : 
    7474
    coypByStream time consumed(buffer size take effect) : 
    8200
              
    File :G:/from_350MB.rar ---- Buffer Size : 
    10240
    --------------
    coypByMbb time consumed(buffer size no effect) : 
    328
    copyByNioTransferFrom time consumed(buffer size no effect) : 
    6864
    copyByNioTransferTo time consumed(buffer size no effect) : 
    7021
    coypByBufferRead time consumed(buffer size take effect) : 
    7199
    coypByFastBufferRead time consumed(buffer size take effect) : 
    7941
    coypByStream time consumed(buffer size take effect) : 
    7801
     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1272956,如需转载请自行联系原作者
你可能感兴趣的文章
Hadoop HDFS原理分析
查看>>
【webpack4】基本配置和入门api
查看>>
Mac使用ssh公钥登录Linux
查看>>
【366天】跃迁之路——程序员高效学习方法论探索系列(实验阶段124-2018.02.06)...
查看>>
POJ3070-Fibonacci(矩阵快速幂)
查看>>
[vue插件]基于vue2.x的电商图片放大镜插件
查看>>
标准的组件结构
查看>>
vue——一个页面实现音乐播放器
查看>>
SVG 扬帆起航
查看>>
NET Core-学习笔记(二)
查看>>
职业生涯上的点点滴滴
查看>>
Linux下添加新硬盘,分区及挂载
查看>>
一起来将vscode变成私人定制笔记本
查看>>
Flutter 云音乐
查看>>
RecyclerView实现多type页面
查看>>
个人的web商城网站
查看>>
debian fcitx
查看>>
排中律与实无穷问题的性质分析
查看>>
08/23 学习总结
查看>>
关于Ubuntu下安装phpmyadmin后mysqli丢失的解决
查看>>