簡體   English   中英

為什么將FileInputStream read()方法置於無限循環中時會錯誤地讀取問號(ascii:63)?

[英]Why is FileInputStream read() method wrongly reading question mark (ascii: 63) when put into infinite loop?

該網站上有一些類似的問題,但是所有問題都已在不同的場景中使用。 所以,我在這里問:

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)。 然后我意識到了我對字符轉換的錯誤,並進行了更改。

但是,當我將while條件更改為“ = -2”(不進行char轉換)時(此條件將永遠不會發生,因此會陷入無限循環)。 即使沒有char轉換,這里的文件的第一個(例如10個)有效字符仍將轉換為'?'。 (到達EOF后,所有無效字符都變為'?'-我假設已給出)。

為什么會這樣呢? 至少應該正確讀取文件的有效字符,直到遇到EOF並開始使用無效字符!

為什么會這樣呢?

問題在這一行:

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

您正在執行以下操作:

  1. 從文件讀取一個字節。 這將為您提供一個int ,該值可以是0到255或-1之間的字節。

  2. 您正在將該值轉換為char 對於字節,給出的char值介於0到255之間。對於-1'\￿'將給出'\￿'

  3. 您將該值分配給c

  4. 然后,您針對-1測試該值。 這就是問題所在。 read返回-1的情況下,您現在將評估此'\￿' == -1 LHS轉換為int值... 0x0000ffff ...並將其與0xffffffff進行比較。 他們是不同的。

然后,您打印'uffff' ...將被轉換為'?' 在默認字符集中以字符形式輸出時。


代碼中有兩個主要錯誤。 首先,轉換int > char > int無效。 往上看。

其次,更重要的是:

  • 您不應該嘗試使用InputStream(面向字節)將數據讀取為字符,並且

  • 您應該嘗試將字符數據寫入OutputStream。

根據您在此處實際嘗試實現的目標,您應該:

  • 讀取和寫入字節...在中間沒有虛假的“轉換”為char

  • 使用FileReaderFileWriter對平台默認字符集正確進行轉換。

(關於緩沖,選擇備用字符集等還有其他幾點,但是這個答案已經太長了。)

只需更改這段代碼-一旦轉換為char,就無法成功將其與整數進行比較,因此永遠不會滿足while退出條件。

int c;
while ((c = inputFile.read()) != -1) {
    System.out.println((char) c);
    outputFile.write(c);
}

同樣使用Java 8 java.nio和java.io包要簡單得多

public static void main(String[] args) throws IOException {
    List<String> lines = Files.readAllLines(Paths.get("s:/inputFile.txt"));
    Files.write(Paths.get("s:/outputFile.txt"), lines);
}

in.read()的結果類型in.read()為char是不好的樣式。 字符只能從閱讀器讀取 -在這種情況下,您可以使用InputStreamReader:

    inputFile = new FileInputStream("s:/inputFile.txt");
    outputFile = new FileOutputStream("s:/outputFile.txt");
    Reader inputReader = InputStreamReader(inputFile, StandardCharsets.UTF_8);
    Writer outputWriter = OutputStreamWriter(outputFile, StandardCharsets.UTF_8);
    char[] cbuf = new char[4096];
    int read;
    while( (read = inputReader.read(cbuf)) >= 0)
    {
        System.out.println(new String(cbuf, 0, read));
        outputWriter.write(cbuf, 0, read);
    }

此外,此示例不逐字節復制(提高了速度),並且將UTF-8用作字符集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM