请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

[已解决] FileChannel position的问题。

原始问题是:

我想问一下,先用FileChannel position,再读。和用int read(ByteBuffer dst, long position)这个方法。效果是不是一样的?

例如在下面的这些代码。

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;

public class IOLearning {
  public static void main(String[] args) throws IOException {
    Path path = Paths.get("hello.txt");
    FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);

    //先使用position,再read
    ByteBuffer byteBuffer = ByteBuffer.allocate(1);
    fileChannel.position(2);
    fileChannel.read(byteBuffer);
    System.out.println(Arrays.toString(byteBuffer.array()));

    //再读一次
    ByteBuffer byteBuffer1 = ByteBuffer.allocate(1);
    fileChannel.read(byteBuffer1);
    System.out.println(Arrays.toString(byteBuffer1.array()));

    //使用read(buffer, position)方法
    ByteBuffer byteBuffer2 = ByteBuffer.allocate(1);
    fileChannel.read(byteBuffer2, 2);
    System.out.println(Arrays.toString(byteBuffer2.array()));

    //再读一次
    ByteBuffer byteBuffer3 = ByteBuffer.allocate(1);
    fileChannel.read(byteBuffer3);
    System.out.println(Arrays.toString(byteBuffer3.array()));

    //再用一次position
    ByteBuffer byteBuffer4 = ByteBuffer.allocate(1);
    fileChannel.position(1);
    fileChannel.read(byteBuffer);
    System.out.println(Arrays.toString(byteBuffer4.array()));

    //再读一次
    ByteBuffer byteBuffer5 = ByteBuffer.allocate(1);
    fileChannel.read(byteBuffer5);
    System.out.println(Arrays.toString(byteBuffer5.array()));
  }
}

其中hello.txt的内容为:

123456789

输出的内容为:

[51]
[52]
[51]
[53]
[0]
[50]

我们可以发现position方法会改变位置,read()不会。先用FileChannel position,再读,和用int read(ByteBuffer dst, long position)这个方法,效果是不一样的。不知道position方法对性能影响大不大。
这个问题是来自我去修改一个时序数据库的底层文件格式遇到的。你可以再这里找到这个文件(https://github.com/apache/incubator-iotdb/blob/master/tsfile/src/main/java/org/apache/iotdb/tsfile/read/TsFileSequenceReader.java)。这里值得注意的是tsFileInput指向的对象实际上使用了FileChannel,不论是调用了position还是read,就是在调用FileChannel的position和read。

  /**
   * this function does not modify the position of the file reader.
   *
   * @param movePosition whether move the position of the file reader after reading the magic header
   * to the end of the magic head string.
   */
  public String readHeadMagic(boolean movePosition) throws IOException {
    ByteBuffer magicStringBytes = ByteBuffer.allocate(TSFileConfig.MAGIC_STRING.length());
    if (movePosition) {
      tsFileInput.position(0);
      tsFileInput.read(magicStringBytes);
    } else {
      tsFileInput.read(magicStringBytes, 0);
    }
    magicStringBytes.flip();
    return new String(magicStringBytes.array());
  }

正在回答 回答被采纳积分+3

1回答

Stannum 2019-10-04 05:26:15

自我学习能力超强~给你置顶!

0 回复 有任何疑惑可以回复我~

相似问题

登录后可查看更多问答,登录/注册

问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信