【问题标题】:Java FileInputStreamJava 文件输入流
【发布时间】:2013-03-07 13:28:33
【问题描述】:

我正在尝试使用 FileInputStream 从本质上读取文本文件,然后将其输出到不同的文本文件中。但是,当我这样做时,我总是得到非常奇怪的字符。我确定这是我犯的一些简单错误,感谢您的帮助或为我指明正确的方向。这是我到目前为止所得到的。

    File sendFile = new File(fileName);
    FileInputStream fileIn = new FileInputStream(sendFile);
    byte buf[] = new byte[1024];
    while(fileIn.read(buf) > 0) {
        System.out.println(buf);
    }

它正在读取的文件只是一个常规 ASCII 字符的大文本文件。然而,每当我执行 system.out.println 时,我都会得到输出 [B@a422ede.关于如何使这项工作的任何想法?谢谢

【问题讨论】:

  • 请注意,您无法使用InputStream 读取文本/字符串/字符。为此,您需要Reader。您可以使用InputStreamReader 将字节转换为字符。

标签: java bytearray java-io fileinputstream


【解决方案1】:

发生这种情况是因为您正在打印字节数组对象本身,而不是打印其内容。您应该从缓冲区和长度构造一个字符串,然后打印该字符串。用于此的构造函数是

String s = new String(buf, 0, len, charsetName);

上面,len 应该是调用 read() 方法返回的值。 charsetName 应该代表底层文件使用的编码。

【讨论】:

  • 不,这绝对不是要使用的构造函数!每当您从字节转换为字符串或从字符串转换为字节时,您需要一个编码new String(bytes, encoding)。如果您不指定编码,您将获得平台默认值,这对于所有意图和目的都是随机的。此外,您不能在缓冲区中使用任何随机偏移量和长度,您最终可能会切断多字节字符。
  • @ChristofferHammarström 你说得对,我添加了第 4 个参数。谢谢!
  • 另外,len 不应该是 read() 方法返回的值,因为它可能会切入多字节字符的中间并且不能保证读取所有文件。请改用InputStreamReader
【解决方案2】:

如果你正在从一个文件读取到另一个文件,你根本不应该将字节转换为字符串,只需将读取的字节写入另一个文件。

如果您打算将文本文件从一种编码转换为另一种编码,请从new InputStreamReader(in, sourceEncoding) 读取,并写入new OutputStreamWriter(out, targetEncoding)

【讨论】:

  • 所有,请注意 christoffer-hammarstrom@'s cmets on other answer's here。
【解决方案3】:

这是因为打印buf 将打印对字节数组的引用,而不是像您期望的那样将字节本身打印为字符串。你需要做new String(buf)将字节数组构造成字符串

还可以考虑使用 BufferedReader 而不是创建自己的缓冲区。有了它,你就可以做

String line = new BufferedReader(new FileReader("filename.txt")).readLine();

【讨论】:

  • 不,永远不要使用FileReader,它应该被弃用,因为它无法指定编码。这意味着您的文本将根据平台编码随机损坏,这基本上是随机的。
  • 另外,切勿将BufferedReader.readLine() 用于您需要完全按原样读取的数据。它会吃掉你的换行符,所以你永远无法确定输入中的换行符是完美的。
【解决方案4】:

你的循环应该是这样的:

int len;
while((len = fileIn.read(buf)) > 0) {
        System.out.write(buf, 0, len);
    }

您 (a) 使用了错误的方法并且 (b) 忽略了 read() 返回的长度,而不是检查 < 0. 所以您在每个缓冲区的末尾打印垃圾。

【讨论】:

    【解决方案5】:

    对象的默认 toString 方法是返回对象在内存中的 id。 byte buf[] 是一个对象。

    你可以用这个打印。

    File sendFile = new File(fileName);
    FileInputStream fileIn = new FileInputStream(sendFile);
    byte buf[] = new byte[1024];
    
    while(fileIn.read(buf) > 0) {
        System.out.println(Arrays.toString(buf));
    }
    

     File sendFile = new File(fileName);
    FileInputStream fileIn = new FileInputStream(sendFile);
    byte buf[] = new byte[1024];
    int len=0;
    while((len=fileIn.read(buf)) > 0) {
        for(int i=0;i<len;i++){
            System.out.print(buf[i]);
        }
        System.out.println();
    }
    

    【讨论】:

    • 第一个版本不起作用,因为它没有考虑read()返回的长度。第二个版本的复杂程度是必要的几倍。您只需要System.out.write(buf, 0, len);
    猜你喜欢
    • 2012-05-16
    • 2018-05-25
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    相关资源
    最近更新 更多