当前位置: 首页 > 知识库问答 >
问题:

如何正确读取字节java文件

於彬
2023-03-14

我想以UTF-8快速地逐行读取大的csv文件(大约~1GB)。我已经为它创建了一个类,但它不能正常工作。UTF-8从2字节解码西里尔符号。我使用字节缓冲区来读取它,例如,它有10个字节的长度。因此,如果文件中的符号由10和11字节组成,它将无法正常解码:(

public class MyReader extends InputStream {

  private FileChannel channel;
  private ByteBuffer buffer = ByteBuffer.allocate(10);
  private int buffSize = 0;
  private int position = 0;
  private boolean EOF = false;
  private CharBuffer charBuffer;

  private MyReader() {}

  static MyReader getFromFile(final String path) throws IOException {
    MyReader myReader = new MyReader();
    myReader.channel = FileChannel.open(Path.of(path),
        StandardOpenOption.READ);
    myReader.initNewBuffer();
    return myReader;
  }
  private void initNewBuffer() {
    try {
      buffSize = channel.read(buffer);
      buffer.position(0);
      charBuffer = Charset.forName("UTF-8").decode(buffer);
      buffer.position(0);
    } catch (IOException e) {
      throw new RuntimeException("Error reading file: {}", e);
    }
  }
  @Override
  public int read() throws IOException {
    if (EOF) {
      return -1;
    }
    if (position < charBuffer.length()) {
      return charBuffer.array()[position++];
    } else {
      initNewBuffer();
      if (buffSize < 1) {
        EOF = true;
      } else {
        position = 0;
      }
      return read();
    }
  }
  public char[] readLine() throws IOException {
    int readResult = 0;
    int startPos = position;
    while (readResult != -1) {
      readResult = read();
    }
    return Arrays.copyOfRange(charBuffer.array(), startPos, position);
  }
}

共有1个答案

严子默
2023-03-14

糟糕的解决方案,但它有效)

private void initNewBuffer() {
    try {
      buffSize = channel.read(buffer);
      buffer.position(0);
      charBuffer = StandardCharsets.UTF_8.decode(buffer);
      if (buffSize > 0) {
        byte edgeByte = buffer.array()[buffSize - 1];
        if (edgeByte == (byte) 0xd0 ||
            edgeByte == (byte) 0xd1 ||
            edgeByte == (byte) 0xc2 ||
            edgeByte == (byte) 0xd2 ||
            edgeByte == (byte) 0xd3
        ) {
          channel.position(channel.position() - 1);
          charBuffer.limit(charBuffer.limit()-1);
        }
      }
      buffer.position(0);
    } catch (IOException e) {
      throw new RuntimeException("Error reading file: {}", e);
    }
  }
 类似资料:
  • 问题内容: 我正在尝试在Android应用程序中获取文件内容(以字节为单位)。我已经在SD卡中获取了文件,现在想获取选定的文件(以字节为单位)。我用谷歌搜索,但没有成功。请帮忙 以下是获取带有扩展名的文件的代码。通过这个,我得到文件并显示在微调器中。在文件选择上,我想以字节为单位获取文件。 问题答案: 这很简单: 在manifest.xml中添加权限:

  • 问题内容: 我无法弄清楚/的运作方式。我对此有些了解,但无法使其正常工作。 我知道我可以使用,但是如果这样做,我知道我永远不会理解/ 我只会埋葬这个问题。 目标:调用并返回文件的内容。 每次调用该文件都会增加一次(每页加载)。该文件包含二进制缓冲区的转储,并存储在SSD中。 无论我做什么,都会出现错误或在控制台中。 问题答案: 要使用/,您需要返回承诺的方法。没有包装器,核心API函数就不会这样做

  • 问题内容: 我想将文件读入Java的String中,一次x个字符。然后,我将对字符串进行某些操作,并希望从我中断的地方继续。我该怎么办? 编辑: 目标文件是一个简单的文本文件。 问题答案: 好吧,首先您需要区分 字节 和 字符 。您可以一次从一定数量的字节中读取(作为最大数量;不能保证您将获得所需的所有字节),并且一次可以读取多个字符(再次,最大)。 听起来您 可能 想要在周围使用,指定适当的字符

  • 问题内容: 我现在使用的代码: 似乎工作正常,但我不确定在将ByteBuffer返回池之前是否需要ByteBuffer。我什至不确定要使用。文档中没有太多关于它的内容。 问题答案: 读取请求正文的一种更简单的方法是将其分派到一个工作线程,该工作线程可以使用。 有两种方法:使用或文档中所示的调度模式。这是使用的示例: 在基本上没有派遣你。

  • http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read() 文档说“从输入流中读取一些字节,并将它们存储到缓冲区数组b中”。 Java 中的 InputStream read() 如何确定字节数?

  • 问题内容: 如何在Java中将文件读取为字节? 重要的是要注意,所有字节都必须为正,即不能使用负范围。 可以用Java完成吗,如果可以,怎么做? 我需要能够将文件的内容乘以一个常数。我以为我可以将字节读取到BigInteger中,然后相乘,但是由于某些字节为负,所以我最终得到12 13 15 -12等并被卡住。 问题答案: 嗯,Java没有无符号字节的概念……该类型始终是带符号的,其值介于-128