Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8274549

(fc) FileChannel.write(ByteBuffer[]...) only writes max 2Gb exactly 2147479552 bytes

XMLWordPrintable

    • x86_64
    • linux

      ADDITIONAL SYSTEM INFORMATION :
      openjdk version "17" 2021-09-14
      OpenJDK Runtime Environment (build 17+35-2724)
      OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)

      Distributor ID: Debian
      Description: Debian GNU/Linux 10 (buster)
      Release: 10
      Codename: buster

      A DESCRIPTION OF THE PROBLEM :
      There is nothing in the API that says write() should not be able to write more than 2Gb. It even returns a long for number of bytes written which would imply expectations that more than 2Gb would be supported.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create more than 2Gb of ByteBuffers as a array of ByteBuffers then try writing with FileChannel.write(ByteBuffer[]...)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      3Gb written to disk
      ACTUAL -
      2Gb written to disk

      ---------- BEGIN SOURCE ----------
      import java.io.IOException;
      import java.nio.ByteBuffer;
      import java.nio.channels.FileChannel;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.StandardOpenOption;

      public class FileChannel2GLimitTest {
          static final int GB = 1024*1024*1024;
          public static void main(String[] args) throws IOException {
              ByteBuffer[] bigBuffers = new ByteBuffer[] {
                      ByteBuffer.allocateDirect(GB),
                      ByteBuffer.allocateDirect(GB),
                      ByteBuffer.allocateDirect(GB)
              };
              for(ByteBuffer buf:bigBuffers) buf.clear();
              Path tempFile = Files.createTempFile("FileChannel2GLimitTest",".dat");
              try {
                  System.out.println("Starting to write 3Gb of data...");
                  FileChannel fc = FileChannel.open(tempFile, StandardOpenOption.CREATE,StandardOpenOption.WRITE);
                  long bytesWritten = fc.write(bigBuffers);
                  System.out.printf("Bytes written = %,d\n",bytesWritten);
                  System.out.printf("Total bytes = %,d\n",GB*3L);
              } finally {
                  Files.delete(tempFile);
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I think you can call FileChannel.write in a loop till number of bytes written is 0 but not checked data yet to know that every byte is currently written and none are lost.

      FREQUENCY : always


            bpb Brian Burkhalter
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: