您的位置:首页 > 编程语言 > Java开发

jdk8多线程操作文件

2016-03-18 18:00 363 查看
今天同事让我帮看看多线程读写文件,尝试着写了一个实例。操作的文件以块形式进行处理,块大小等于缓存大小,线程池根据cpu决定池大小。


/**
* 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新特性是否能提供更便捷的代码操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: