java - 为什么 FileInputStream read() 方法错误地读取问号(ascii : 63) when put into infinite loop?

标签 java io fileinputstream

网站上有一些类似的问题,但都在不同的场景中使用过。所以,我在这里问:

package Assign6B;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOpsDemo {
    public static void main(String[] args) throws IOException 
    {

        FileInputStream inputFile = null;
        FileOutputStream outputFile = null;

        try
        {
            inputFile = new FileInputStream("s:/inputFile.txt");
            outputFile = new FileOutputStream("s:/outputFile.txt");
            char c;
            while(( c = (char) inputFile.read()) != -1)
            {
                System.out.println((char)c);
                outputFile.write(c);
            }

            System.out.println("File transfer complete!");
        }

        finally
        {
            if (inputFile != null)
                inputFile.close();

            if (outputFile != null)
                outputFile.close();
        }
    }
}

这是我的代码。在 while 循环条件中,首先我将其设置为将 read() 输出的 int 类型转换为 char。结果是它进入了无限循环,所有字符都被转换为“?” (ASCII:63)。然后我意识到我的char转换错误并更改了它。

但是当我将 while 条件更改为“=-2”(没有字符转换)时(这种情况永远不会发生,因此将其放入无限循环)。在这里,即使没有字符转换,文件的前(例如 10)个有效字符仍然会被转换为“?”。 (到达 EOF 后,所有无效字符都变为“?” - 我假设已给出)。

为什么会发生这种情况?至少应该正确读取文件的有效字符,直到遇到 EOF 并开始输入无效字符!

最佳答案

Why is this happening?

问题出在这一行:

 while(( c = (char) inputFile.read()) != -1)

您正在执行以下操作:

  1. 从文件中读取一个字节。这将为您提供一个 int,它可以是 0 到 255 范围内的字节,也可以是 -1。

  2. 您正在将该值转换为 char。对于字节,它给出 0 到 255 范围内的 char 值。对于 -1,转换将为您提供 '\uffff'

  3. 您将该值分配给 c

  4. 然后根据 -1 测试该值。这就是出错的地方。在 read 返回 -1 的情况下,您现在将评估此 '\uffff' == -1。 LHS 转换为 int 值 ... 0x0000ffff ... 并与 0xffffffff 进行比较。他们是不同的。

然后打印 'uffff' ...当输出为默认字符集中的字符时,它会转换为 '?'

<小时/>

代码中有两个重大错误。首先,转换 int -> char -> int 不起作用;见上文。

第二,也是更重要的:

  • 您不应该尝试使用InputStream(面向字节)将数据读取为字符,并且

  • 您应该尝试将字符数据写入 OutputStream。

根据您实际想要实现的目标,您应该:

  • 读取和写入字节...中间没有虚假的“转换”为char,或者

  • 使用 FileReaderFileWriter 为平台默认字符集正确进行转换。

(关于缓冲、选择备用字符集等还可以提出一些其他观点,但这个答案已经太长了。)

关于java - 为什么 FileInputStream read() 方法错误地读取问号(ascii : 63) when put into infinite loop?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37438092/

相关文章:

android - 从android中的文本文件中读取

java - 在 Apache Beam 中读取 CSV 文件时跳过 header

java - SetLenient(false) 与年份

java - 防止在 SessionScoped beans 中序列化 CDI 注入(inject)的 Logger

java - 安卓有线网络如何切换?

java - 读取文件并打印字符串和整数的平均值

java - 用户输入Java

Java WriteFile 看不到内容

java - 从文件输入流,到文件输出流

java - 使用 FileOutputStream 将数据结构写入文件?