Java: InputStream too slow to read huge files

前端 未结 4 1076
失恋的感觉
失恋的感觉 2020-12-15 23:57

I have to read a 53 MB file character by character. When I do it in C++ using ifstream, it is completed in milliseconds but using Java InputStream it takes several minutes.

相关标签:
4条回答
  • 2020-12-16 00:11

    As noted above, use a BufferedInputStream. You could also use the NIO package. Note that for most files, BufferedInputStream will be just as fast reading as NIO. However, for extremely large files, NIO may do better because you can memory mapped file operations. Furthermore, the NIO package does interruptible IO, whereas the java.io package does not. That means if you want to cancel the operation from another thread, you have to use NIO to make it reliable.

    ByteBuffer buf = ByteBuffer.allocate(BUF_SIZE);
    FileChannel fileChannel = fileInputStream.getChannel();
    int readCount = 0;
    while ( (readCount = fileChannel.read(buf)) > 0) {
      buf.flip();
      while (buf.hasRemaining()) {
        byte b = buf.get();
      }
      buf.clear();
    }
    
    0 讨论(0)
  • 2020-12-16 00:14

    I would try this

    // create the file so we have something to read.
    final String fileName = "1.2.fasta";
    FileOutputStream fos = new FileOutputStream(fileName);
    fos.write(new byte[54 * 1024 * 1024]);
    fos.close();
    
    // read the file in one hit.
    long start = System.nanoTime();
    FileChannel fc = new FileInputStream(fileName).getChannel();
    ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
    while (bb.remaining() > 0)
        bb.getLong();
    long time = System.nanoTime() - start;
    System.out.printf("Took %.3f seconds to read %.1f MB%n", time / 1e9, fc.size() / 1e6);
    fc.close();
    ((DirectBuffer) bb).cleaner().clean();
    

    prints

    Took 0.016 seconds to read 56.6 MB
    
    0 讨论(0)
  • 2020-12-16 00:22

    Use a BufferedInputStream:

    InputStream buffy = new BufferedInputStream(inputStream);
    
    0 讨论(0)
  • 2020-12-16 00:30

    I ran this code with a 183 MB file. It printed "Elapsed 250 ms".

    final InputStream in = new BufferedInputStream(new FileInputStream("file.txt"));
    final long start = System.currentTimeMillis();
    int cnt = 0;
    final byte[] buf = new byte[1000];
    while (in.read(buf) != -1) cnt++;
    in.close();
    System.out.println("Elapsed " + (System.currentTimeMillis() - start) + " ms");
    
    0 讨论(0)
提交回复
热议问题