Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
并发读取文件(首选java)_Java_File_Concurrency_Io - Fatal编程技术网

并发读取文件(首选java)

并发读取文件(首选java),java,file,concurrency,io,Java,File,Concurrency,Io,我有一个大文件,需要几个小时才能处理。因此,我想尝试估算块并并行阅读块 是否可以在单个文件上同时读取?我已经看过了RandomAccessFile和nio.FileChannel,但根据其他帖子,我不确定这种方法是否有效。如果你从硬盘读取文件,那么获取数据的最快方法是从头到尾读取文件,也就是说,不是同时读取 如果处理需要时间,那么让多个线程同时处理不同的数据块可能会带来好处,但这与读取文件的方式无关。如果有多个独立的spindal,则可以并行读取大文件。例如,如果您有Raid 0+1剥离文件系统

我有一个大文件,需要几个小时才能处理。因此,我想尝试估算块并并行阅读块


是否可以在单个文件上同时读取?我已经看过了
RandomAccessFile
nio.FileChannel
,但根据其他帖子,我不确定这种方法是否有效。

如果你从硬盘读取文件,那么获取数据的最快方法是从头到尾读取文件,也就是说,不是同时读取


如果处理需要时间,那么让多个线程同时处理不同的数据块可能会带来好处,但这与读取文件的方式无关。

如果有多个独立的spindal,则可以并行读取大文件。例如,如果您有Raid 0+1剥离文件系统,则可以通过触发对同一文件的多个并发读取来提高性能

但是,如果您有一个组合文件系统,如Raid 5或Raid 6或一个普通的单磁盘。按顺序读取文件很可能是从该磁盘读取文件的最快方式。注意:操作系统足够智能,当它看到您正在按顺序读取时,可以预取读取,因此使用额外的线程来执行这项操作不太可能有帮助

i、 使用多线程不会使您的磁盘速度更快


如果您想更快地从磁盘读取数据,请使用更快的驱动器。一个典型的SATA HDD可以读取约60 MB/秒,执行120 IOPS。一个典型的SATA SSD驱动器可以以大约400 MB/s的速度读取数据并执行80000 IOPS,而一个典型的PCI SSD可以以900 MB/s的速度读取数据并执行230000 IOPS。

您可以并行处理,但您的硬盘驱动器一次只能读取一条数据。 如果使用单个线程读取文件,则可以使用多个线程处理数据。

这里最重要的问题是您的案例中的瓶颈是什么

如果瓶颈是您的磁盘IO,那么您在软件部分就无能为力了。并行计算只会让事情变得更糟,因为同时从不同部分读取文件会降低磁盘性能

如果瓶颈是处理能力
,并且您有多个CPU核,那么您可以利用启动多个线程来处理文件的不同部分。您可以安全地创建几个
InputStream
s或
Reader
s来并行读取文件的不同部分(只要您不超过操作系统对打开文件数量的限制)。您可以将工作分为多个任务并并行运行,如本例所示:

import java.io.*;
导入java.util.*;
导入java.util.concurrent.*;
公共阶级分裂{
私有文件;
公共拆分(文件){
this.file=文件;
}
//处理文件的给定部分。
//从多个线程同时调用。
//根据需要使用自定义返回类型,我使用字符串只是为了给出一个示例。
公共字符串processPart(长起始、长结束)
抛出异常
{
InputStream is=新文件InputStream(文件);
是。跳过(开始);
//使用输入流进行计算,
//检查读取的字节数是否不超过(结束-开始)字节
System.out.println(“计算从“+开始+”到“+结束”的部分);
睡眠(1000);
System.out.println(“完成了从“+开始+”到“+结束”的部分);
is.close();
返回“某个结果”;
}
//创建将处理文件给定部分的任务,
//执行时。
公共可调用processPartTask(最终长启动、最终长结束){
返回新的可调用(){
公共字符串调用()
抛出异常
{
返回处理部分(开始、结束);
}
};
}
//将计算拆分为给定大小的块,
//创建适当的任务并使用
//给定的线程数。
public void processAll(int noOfThreads、int chunkSize)
抛出异常
{
int count=(int)((file.length()+chunkSize-1)/chunkSize);
java.util.List tasks=新的ArrayList(计数);
for(int i=0;i
哪个操作系统?不管是不是Java,Windows都不能很好地处理这类事情。我在某个地方读到,当它是diskIO时,您可能无法获得并发性的优势。为什么要投反对票?我发现这个问题非常有趣。@user1132593我开始寻找你问题的答案,发现了一些非常有趣的东西,但我不知道你想走多远。这里:只是为了确保讨论的方向正确;您的问题是读取数据太慢,还是数据处理太慢?我认为这并不能回答问题。问题是:是否有可能“并行化”读取一个大文件?我的印象是,基本问题更多的是“通过并行读取,我可以更快地读取一个文件吗?”编辑后:我想这与读取有关,因为正如他所说,这是一个“大文件”。顺便说一句,-1不是我写的。通过内存映射不同的部分(提示:
FileChann),您可以轻松地同时读取文件的不同部分