【问题标题】:How to read huge file in Java, in chunks without being blocked?如何在不被阻塞的情况下分块读取Java中的大文件?
【发布时间】:2012-02-01 00:14:41
【问题描述】:

假设您有一个更大的文件,那么您有内存要处理。您想依次读取文件n 字节并且不会在此过程中被阻止

  • 读取一个块
  • 将其传递给线程
  • 读取另一个块
  • 将其传递给线程

我尝试了不同的方法并取得了不同程度的成功,但阻塞似乎总是问题所在。

请提供一个非阻塞方式的示例以获取访问权限,例如byte[]

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    你不能。

    在等待磁盘为您提供数据时,您将总是阻塞。如果您对每个数据块有很多工作要做,那么使用第二个线程可能会有所帮助:该线程可以对数据执行 CPU 密集型工作,而第一个线程被阻塞等待下一次读取完成。

    但这听起来不像你的情况。

    最好的办法是尽可能大地读取数据(例如 1MB 或更多)。这可以最大限度地减少内核中阻塞的时间,并且可能会减少等待磁盘的时间(如果正在读取的块恰好是连续的)。


    这里是密码

    ExecutorService exec = Executors.newFixedThreadPool(1);
    
    // use RandomAccessFile because it supports readFully()
    RandomAccessFile in = new RandomAccessFile("myfile.dat", "r");
    in.seek(0L);
    
    while (in.getFilePointer() < in.length())
    {
        int readSize = (int)Math.min(1000000, in.length() - in.getFilePointer());
        final byte[] data = new byte[readSize];
        in.readFully(data);
        exec.execute(new Runnable() 
        {
            public void run() 
            {
                // do something with data
            }
        });
    }
    

    【讨论】:

    • 对。假设我一次阅读1M。在我读完它(并放在一个字节[]中)之后,我想将它传递给另一个线程之前我读了另一个 1M。
    • 你的问题是?
    • while(whatever) { byte[] chunk = new byte[1 &lt;&lt; 10]; myInputStream.read(chunk); executorService.submit(theTaskUsing(chunk)); }
    • “当第一个线程被阻塞等待下一次读取完成时,该线程可以对数据执行 CPU 密集型工作”但可能不会,如果 O/S 进行了一些预读并且您自己缓冲输入。
    【解决方案2】:

    听起来您正在寻找流、缓冲或两者的某种组合(BufferedInputStream 有人吗?)。

    检查一下: http://docs.oracle.com/javase/tutorial/essential/io/buffers.html

    这是处理超大文件的标准方法。如果这不是您要找的东西,我深表歉意,但希望无论如何它都能帮助您流淌。

    祝你好运!

    【讨论】:

      【解决方案3】:

      如果您有一个执行 I/O 和 CPU 计算的程序,如果平均而言,处理一个字节所需的 CPU 时间少于读取一个字节的时间,阻塞是不可避免的(在您的程序中的某处)。

      如果您尝试读取需要磁盘寻道的文件,则数据可能在 10 毫秒内无法到达。一个 2 GHz CPU 在这段时间内可以完成 20 M 个时钟周期的工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-20
        • 1970-01-01
        • 2016-07-08
        • 2019-10-27
        • 2019-09-09
        • 1970-01-01
        • 2011-05-25
        相关资源
        最近更新 更多