【Java】文件复制的各种姿势,java复制姿势
分享于 点击 36274 次 点评:286
【Java】文件复制的各种姿势,java复制姿势
下面讲解一下Java中复制文件的各种姿势。
1. BIO
第一种是传统IO操作方式,即输入输出流配合,一个读一个写,相对简单
public static void copyFile(String s, String d) {
int readPerSize = 1024 * 1024;
try (FileInputStream in = new FileInputStream(s);
FileOutputStream out = new FileOutputStream(d);) {
byte[] buffer = new byte[readPerSize];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
2. NIO Buffer
- 从 FileInputStream 获取 FileChannel;
- 创建 Buffer(ByteBuffer的
allocate
或allocateDirect
方法,一个是堆内存,一个是本地内存); - 将数据从 FileChannel 读到 Buffer 中,并通过返回值大小判断Buffer大小;
- 同时切换读模式 filp,然后写入FileOutputStream的 FileChannel中;
- 缓存清除;
- FileChannel关闭;
public static void copyFileByByteBuffer(String source, String dest, ByteBuffer buffer) {
try (FileInputStream in = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(dest);
) {
FileChannel inChannel = in.getChannel();
FileChannel outChannel = out.getChannel();
int size = inChannel.read(buffer);
while (size > -1) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
size = inChannel.read(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
buffer.clear();
}
}
3. NIO Channel
与Buffer
方式类似,但是复制过程通过outChannel
的transferFrom
或inChannel
的transferTo
实现
public static void copyFileByChannel(String s, String d, ByteBuffer buffer) {
int readPerSize = 1024 * 1024;
try (FileInputStream in = new FileInputStream(s);
FileOutputStream out = new FileOutputStream(d);){
FileChannel inChannel = in.getChannel();
FileChannel outChannel = out.getChannel();
int pos = 0;
// 也可以通过 inChannel 的 transferTo 去写入
while (pos < inChannel.size()) {
pos += outChannel.transferFrom(inChannel, pos, readPerSize);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4. NIO 文件内存映射
public static void copyFileByDirectBuffer(String s, String d) {
int readPerSize = 1024 * 1024;
try {
FileChannel inChannel = new RandomAccessFile(s,"r").getChannel();
FileChannel outChannel = new RandomAccessFile(d,"rw").getChannel();
long fileSize = inChannel.size();
int pos = 0;
while (pos < fileSize) {
long copyFileSize = Math.min((fileSize-pos),readPerSize);
//得到的是DirectByteBuffer
MappedByteBuffer byteBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE,pos,copyFileSize);
inChannel.read(byteBuffer);
pos += byteBuffer.position();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
5. 终极大招
JDK7提供了一个文件操作的工具类 —- Files
File提供了诸如:copy / delete / move / read 等各种静态方法,对文件的操作进一步封装。
有了这些方法,就不需要我们手动的去操作输入输出流,读写操作等,实乃良心。
Files.copy(Paths.get("E:\\Book\\ Vim实用技巧.pdf"),Paths.get("D:\\Vim实用技巧.pdf"));
引用
《Java特种兵·上册》 第四章
相关文章
- 暂无相关文章
用户点评