public static void copyFileUnbuffered(File src, File dst) throws IOException {
    if (nativeLoaded && Shell.WINDOWS) {
      copyFileUnbuffered0(src.getAbsolutePath(), dst.getAbsolutePath());
    } else {
      FileInputStream fis = new FileInputStream(src);
      FileChannel input = null;
      try {
        input = fis.getChannel();
        try (FileOutputStream fos = new FileOutputStream(dst);
             FileChannel output = fos.getChannel()) {
          long remaining = input.size();
          long position = 0;
          long transferred = 0;
          while (remaining > 0) {
            transferred = input.transferTo(position, remaining, output);
            remaining -= transferred;
            position += transferred;
          }
        }
      } finally {
        IOUtils.cleanupWithLogger(LOG, input, fis);
      }
    }
  }
@Test (timeout = 30000)
  public void testCopyFileUnbuffered() throws Exception {
    final String METHOD_NAME = GenericTestUtils.getMethodName();
    File srcFile = new File(TEST_DIR, METHOD_NAME + ".src.dat");
    File dstFile = new File(TEST_DIR, METHOD_NAME + ".dst.dat");
    final int fileSize = 0x8000000; // 128 MB
    final int SEED = 0xBEEF;
    final int batchSize = 4096;
    final int numBatches = fileSize / batchSize;
    Random rb = new Random(SEED);
    FileChannel channel = null;
    RandomAccessFile raSrcFile = null;
    try {
      raSrcFile = new RandomAccessFile(srcFile, "rw");
      channel = raSrcFile.getChannel();
      byte bytesToWrite[] = new byte[batchSize];
      MappedByteBuffer mapBuf;
      mapBuf = channel.map(MapMode.READ_WRITE, 0, fileSize);
      for (int i = 0; i < numBatches; i++) {
        rb.nextBytes(bytesToWrite);
        mapBuf.put(bytesToWrite);
      }
      NativeIO.copyFileUnbuffered(srcFile, dstFile);
      Assert.assertEquals(srcFile.length(), dstFile.length());
    } finally {
      IOUtils.cleanupWithLogger(LOG, channel);
      IOUtils.cleanupWithLogger(LOG, raSrcFile);
      FileUtils.deleteQuietly(TEST_DIR);
    }
  }