【问题标题】:Java BufferedReader for zero-terminated strings用于零终止字符串的 Java BufferedReader
【发布时间】:2009-11-06 10:40:01
【问题描述】:

我需要从 Java 中的 InputStream 中读取以零结尾的字符串。

是否有类似 BufferedReader.readLine() 的方法来读取以零结尾的字符串?

【问题讨论】:

    标签: java bufferedinputstream null-terminated


    【解决方案1】:
    package com;
    
    import java.io.*;
    import java.util.Scanner;
    
    public class AAA {
    
        private static final String ENCODING = "UTF-8";
    
        public static void main(String[] args) throws Exception {
            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
            bOut.write("the first line".getBytes(ENCODING));
            bOut.write(0);
            bOut.write("the second line\r\n (long one)".getBytes(ENCODING));
            bOut.write(0);
            bOut.write("the third line".getBytes(ENCODING));
            printLines(new ByteArrayInputStream(bOut.toByteArray()));
        }
    
        public static void printLines(InputStream in) {
            Scanner scanner = new Scanner(in, ENCODING);
            scanner.useDelimiter("\u0000");
            while (scanner.hasNext()) {
                System.out.println(scanner.next());
                System.out.println("--------------------------------");
            }
        }
    }
    

    【讨论】:

    • 这个。 Scanner 必须是使用率最低的 java.util.* 类。
    【解决方案2】:

    没有。 Java 不能识别以零结尾的字符串。您必须阅读 InputStream 并查找 0 字节。

    请注意,这并没有解决字符编码的问题。 InputStream 将为您提供字节流,然后您必须通过 Reader 将字符编码为字符。如果你有一个多字节字符编码,那么问题就会变得更加复杂。

    【讨论】:

    • 是否有效取决于字符编码。实际上,他需要从 Reader 中读取并查找 0 字符,而不是 0 字节。
    • 他明确要求来自 InputStream 的以零结尾的字符串。这很令人困惑,因为他随后提到了 BufferedReader
    • 既然您无法从 InputStream 中读取字符和字符串,您最好告诉他,而不是用一个半错的答案让他感到困惑吗?
    • 这就是为什么 a) 我明确强调了 0 字节 b) 已经澄清了以下反馈。如果你能写出一个你更满意的答案,你可能想自己发布一个答案。
    • MacGordon 已经做到了,所以我不知道我为什么要重复他。实际上,“否”已经足以回答 Domas 的问题,因为他只是问是否有类似于 readLine 的方法来读取以空字符结尾的字符串。
    【解决方案3】:

    您还需要了解“零”是什么意思。输入/输出流处理字节,而读取器/写入器处理字符。如果你想匹配一个零字符,那么字节到字符的转换编码就会发挥作用。

    【讨论】:

      【解决方案4】:

      您可以创建一种类似于下面的方法。从InputStream 创建BufferedReaderBufferedReader 通过引用传递,因此它将保留状态。它也可以很容易地存储在实例变量中。

      public String readLine(BufferedReader buff) throws IOException{
          int c = buff.read();
          // if EOF
          if (c == -1){
              return null;
          }
          StringBuilder builder = new StringBuilder("");
          // Check if new line or EOF
          while (c != -1 && c != 0){
              builder.append((char) c);
              c = buff.read();
          }
          return builder.toString();
      }
      

      ....

      String line = reader.readLine(buff);
      while (line != null)
      {
      System.out.println(line);
      line = reader.readLine(someBufferedReader);
      
      }
      

      【讨论】:

      • 这会将第一个 0 字节之后的所有内容丢弃到下一个 EOL。如果您的文件仅包含 0 字节分隔的 Strings,您将只能从中获得一个 String
      • BufferedReader 是通过引用传递的,因此将保持其状态。在第二次调用时,它将从上次中断的地方开始。
      • 此解决方案不处理多字节编码字符。 @dennis.zhdanov 的解决方案可以。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-11
      • 2013-05-31
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多