jdk8多线程操作文件 jdk多线程文件
程序员文章站
2022-07-09 14:58:47
...
今天同事让我帮看看多线程读写文件,尝试着写了一个实例。操作的文件以块形式进行处理,块大小等于缓存大小,线程池根据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新特性是否能提供更便捷的代码操作。
上一篇: J2me游戏梦幻西游——建邺城