Android 下高效复制文件的方法

如果安卓8.0(API26)以上的系统,建议使用java.nio.file.Files.copy()方法。

因为如果在同一个文件系统上的话,Files.copy会调用系统的复制文件方法,此时性能开销最小。

连缓存块的操作都不需要,直接由系统内核在DMA(Direct Memory Access)处操作。 

如果两个文件不在一个文件系统上,比如一个是磁盘,一个是网络,则使用buffers缓冲区复制文件。

使用方法如下:

try {
      // 同一个系统的话,使用系统的复制功能,否则使用buffers复制
      Files.copy(in.toPath(), out.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
      e.printStackTrace();
}

如果安卓8.0(API26)以下的系统上,建议使用java.nio.filechannel复制文件。

因为nio都是块操作,有buffer,并且可以实现零拷贝。远比旧的Stream IO跑到用户空间调用系统的read()/write()方法,额外消耗cpu资源的方式好多了。

// 自动关闭资源的写法,实现closeable的资源

try (FileChannel src = new FileInputStream(in).getChannel(); FileChannel dst = new FileOutputStream(out).getChannel()) {
    dst.transferFrom(src, 0, src.size());
} catch (Exception e) {
    e.printStackTrace();
}

如果需要修改文件内容的话,使用mapper,映射到内存,此时映射的内容会直接由系统的页缓存管理,当发生修改的时候,系统页缓会存标记修改的内容为脏数据,进而触发刷写到内存。单纯的复制文件则没必要使用。

MappedByteBuffer mbb = sourceCh.map(FileChannel.MapMode.READ_ONLY, 0, sourceCh.size());

 

 

 

评论列表: