jdk8多线程操作文件
2016-03-18 18:00
363 查看
今天同事让我帮看看多线程读写文件,尝试着写了一个实例。操作的文件以块形式进行处理,块大小等于缓存大小,线程池根据cpu决定池大小。
程序只做为测试,不够严谨。欢迎提意见和改进想法,看看java新特性是否能提供更便捷的代码操作。
/**
* Created on 2016年3月18日
*/
package org.zl.test;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 文件以块形式进行处理,块大小等于缓存大小
*
* 采用FileChannel的map方式读写文件
* 线程池根据cpu决定池大小
*
* <br>
* change log:<br>
* 0.01 2016年3月18日 Created <br>
* @version 0.01
* @author Leo
*/
public class FileRW {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
int bufferSize = 1024 * 1024;//块大小
Path copy_from = Paths.get("d:\\web\\ajaxswing410.zip");
//Path copy_from = Paths.get("d:\\license.txt");
Path copy_to = Paths.get("d:\\data2.zip");
//Path copy_to = Paths.get("d:\\l.txt");
FileChannel fileChannel_from = FileChannel.open(copy_from,EnumSet.of(StandardOpenOption.READ));
Files.deleteIfExists(copy_to);
FileChannel fileChannel_to = FileChannel.open(copy_to,EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE));
ExecutorService executor = Executors.newWorkStealingPool();
//分任务块
long filesize = fileChannel_from.size();
long bytesCount = 0;
//List<Runnable> callables = Arrays.asList();
while(filesize>bytesCount){
long length=(filesize<(bytesCount+bufferSize))?filesize-bytesCount:bufferSize;
Runnable task = new MyThread(fileChannel_from,fileChannel_to,bytesCount,length);
executor.submit(task);
bytesCount = bytesCount+bufferSize;
}
//线程结束关闭通道
while(!executor.isShutdown()){
executor.shutdown();
TimeUnit.SECONDS.sleep(2);
}
fileChannel_from.close();
fileChannel_to.close();
}
}
class MyThread implements Runnable{
FileChannel fileChannel_from;
FileChannel fileChannel_to;
long offset;
int length;
/**
*
* @param fileChannel_from 读通道
* @param fileChannel_to 写通道
* @param offset 起点
* @param length 长度
*/
public MyThread(FileChannel fileChannel_from,FileChannel fileChannel_to,long offset,long length) {
this.fileChannel_from =fileChannel_from;
this.fileChannel_to =fileChannel_to;
this.offset=offset;
this.length=Long.valueOf(length).intValue();
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
long startTime = System.nanoTime();
//ByteBuffer bytebuffer = ByteBuffer.allocate(length);
//ByteBuffer bytebuffer = ByteBuffer.allocateDirect(TestThread.bufferSize);
//bytebuffer.flip();
try {
System.out.println("read:"+length);
//fileChannel_from.read(bytebuffer, offset);
MappedByteBuffer buffer = fileChannel_from.map(FileChannel.MapMode.READ_ONLY,offset,length);
fileChannel_to.write(buffer,offset);
//bytebuffer.clear();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String threadName = Thread.currentThread().getName();
long elapsedTime = System.nanoTime() - startTime;
System.out.println(threadName+" Elapsed Time is " + (elapsedTime / 1000000000.0) + " seconds");
}
}
程序只做为测试,不够严谨。欢迎提意见和改进想法,看看java新特性是否能提供更便捷的代码操作。
相关文章推荐
- android的文件、目录操作(二)
- C#经典操作文件的方法
- delphi操作文本文件简介(一)
- IO操作查找某文件字母数字空格个数
- python文件操作
- Python 文件常见操作
- Python 利用pydub库操作音频文件的方法
- 關于在WIN32調用一些Zw系列的文件操作函數.
- VC++文件操作之最全篇
- linux 文件操作指令
- 关于python文件操作专题
- xutils3 上传文件操作——个人小计
- java io操作文件实例
- OpenCV学习笔记(23)cv.Mat 与 .txt 文件数据的读写操作
- Java操作Excel文件导入
- Linux文件和目录的操作(三) ls
- C#谈文件操作NO1(文件加密)
- Perl文件及目录操作
- C语言文件操作 关于scanf遇空格结束
- 文件操作opendir()/readdir()/closedir()/stat()