Reserach Introduction 1

1.如何快速读取大文件

java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果文件超大的话,更快的方式是采用ByteBuffer。

  • ByteBuffer有两种模式:直接/间接.间接模式最典型(也只有这么一种)的就是HeapByteBuffer,即操作堆内存 (byte[]).但是内存毕竟有限,如果发送一个1G的文件怎么办?不可能去分配1G的内存.这时就必须使用"直接"模式,即 MappedByteBuffer,文件映射.
  • MappedByteBuffer 就是映射大文件文件的一部分到内存,如果需要处理整个文件,可以每次处理一部分,多次处理最后等效于处理整个文件,用运算时间换取了内存空间。
//------》测试代码
 public class MapMemeryBuffer {  
 9   
10     public static void main(String[] args) throws Exception {  
11         ByteBuffer byteBuf = ByteBuffer.allocate(1024 * 14 * 1024);  
12         byte[] bbb = new byte[14 * 1024 * 1024];  
13         FileInputStream fis = new FileInputStream("e://data/other/UltraEdit_17.00.0.1035_SC.exe");  
14         FileOutputStream fos = new FileOutputStream("e://data/other/outFile.txt");  
15         FileChannel fc = fis.getChannel();  
16         long timeStar = System.currentTimeMillis();// 得到当前的时间  
17         fc.read(byteBuf);// 1 读取  
18         //MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());  
19         System.out.println(fc.size()/1024);  
20         long timeEnd = System.currentTimeMillis();// 得到当前的时间  
21         System.out.println("Read time :" + (timeEnd - timeStar) + "ms");  
22         timeStar = System.currentTimeMillis();  
23         fos.write(bbb);//2.写入  
24         //mbb.flip();  
25         timeEnd = System.currentTimeMillis();  
26         System.out.println("Write time :" + (timeEnd - timeStar) + "ms");  
27         fos.flush();  
28         fc.close();  
29         fis.close();  
30     }  
31   
32 } 

Reserach Introduction 1_第1张图片

  • MappedByteBuffer也存在一些问题,主要就是内存占用和文件关闭等不确定问题。被MappedByteBuffer打开的文件只有在垃圾收集时才会被关闭,而这个点是不确定的。

2.多个线程任务调度

  • 单生产者–单消费者:最简单模型,使用写线程,读线程 2个线程,中间通过一个任务队列解耦合。
  • 多生产者-单消费者:与上面的不同在于多个写线程,多个写线程就会产生竞争条件,可以参考Netty使用的Mpsc队列

Reserach Introduction 1_第2张图片

  • 多生产者-多消费者:与上面的不同在于多个写线程和多个读线程,可以使用BlockingQueue,有两种实现ArrayBlockingQueue(有界队列)或者LinkedBlockingQueue(无界队列),前一种入队出队一把锁,后一种出队入队是不同的锁,各自适合不同场景。

多线程 ForkJoinPool 处理密集计算任务

参考文章

  • 默认线程cpu核数个
  • 分治法,递归计算

实例问题:假设一个CSV文件有8GB,里面有1亿条数据,每行数据最长不超过1KB,目前需要将这1亿条数据拆分为10MB一个的子CSV文件,写入到同目录下,要求:

  • 每一个子CSV文件的数据必须是完整行
  • 所有子文件不能大于10MB
  • 确保文件拆分后文件内容不会丢失;
  • Reserach Introduction 1_第3张图片

你可能感兴趣的:(每日工作学习)