Search code examples
javaniofilechannel

Why the fileChannel.read loop never end?


I try to use nio to read a small text which contains only 5 characters,however, the fileChannel.read loop never go to end.

public static void main(String[] args) throws IOException {
        FileChannel fileChannel = FileChannel.open(Paths.get("input.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE);
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        while (fileChannel.read(byteBuffer) != -1) {
            byteBuffer.flip();
            while (byteBuffer.hasRemaining()) {
                char c = (char)byteBuffer.get();
                System.out.println(c);
            }
        }
    }

Solution

  • The problem is that you forget to reset your buffer's limit and position after the inner while loop. After you read the first 1024 character, the buffer will be full, and each attempt to read into the buffer will try to read up to remaining = limit - position bytes, that is, 0 bytes once the buffer is full.

    Also, you should always capture the return value from fileChannel.read(). In your case, it would tell you that it is continuously returning 0.

    Calling byteBuffer.clear() after the inner loop resolves the problem:

    public static void main(String[] args) throws IOException {
      FileChannel fileChannel = FileChannel.open(Paths.get("JPPFConfiguration.txt"), StandardOpenOption.READ, StandardOpenOption.WRITE);
      ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
      int n;
      long sum = 0L;
      while ((n = fileChannel.read(byteBuffer)) != -1) {
        sum += n;
        byteBuffer.flip();
        while (byteBuffer.hasRemaining()) {
          char c = (char) byteBuffer.get();
          System.out.print(c);
        }
        System.out.println("\n read " + n  + " bytes");
        byteBuffer.clear();
      }
      System.out.println("read " + sum + " bytes total");
    }