[java] Java FileReader 인코딩 문제

java.io.FileReader를 사용하여 일부 텍스트 파일을 읽고 문자열로 변환하려고 시도했지만 결과가 잘못 인코딩되어 읽을 수 없다는 것을 알았습니다.

내 환경은 다음과 같습니다.

  • Windows 2003, OS 인코딩 : CP1252

  • 자바 5.0

내 파일은 UTF-8로 인코딩되거나 CP1252로 인코딩되며 일부 (UTF-8로 인코딩 된 파일)에는 중국어 (라틴 문자가 아닌) 문자가 포함될 수 있습니다.

다음 코드를 사용하여 작업을 수행합니다.

   private static String readFileAsString(String filePath)
    throws java.io.IOException{
        StringBuffer fileData = new StringBuffer(1000);
        FileReader reader = new FileReader(filePath);
        //System.out.println(reader.getEncoding());
        BufferedReader reader = new BufferedReader(reader);
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }

위의 코드는 작동하지 않습니다. 텍스트가 UTF-8로 인코딩 된 경우에도 FileReader의 인코딩이 CP1252라는 것을 알았습니다. 그러나 java.io.FileReader의 JavaDoc은 다음과 같이 말합니다.

이 클래스의 생성자는 기본 문자 인코딩과 기본 바이트 버퍼 크기가 적절하다고 가정합니다.

FileReader를 사용하는 경우 직접 문자 인코딩을 설정할 필요가 없다는 의미입니까? 그러나 현재 잘못 인코딩 된 데이터를 얻었습니다. situtaion을 처리하는 올바른 방법은 무엇입니까? 감사.



답변

예, 읽으려는 파일 의 인코딩을 지정해야합니다 .

예, 읽으려는 파일의 인코딩 을 알고 있어야 합니다.

아니요, 주어진 “일반 텍스트”파일의 인코딩 을 추측 하는 일반적인 방법은 없습니다 .

하나의 인수 생성자는FileReader 항상 플랫폼 기본 인코딩을 사용하는데 이는 일반적 으로 나쁜 생각 입니다.

Java 11 FileReader은 인코딩을 허용하는 생성자를 얻었으므로 : new FileReader(file, charset)new FileReader(fileName, charset).

이전 버전의 Java에서는을 사용해야 합니다.new InputStreamReader(new FileInputStream(pathToFile), <encoding>)


답변

FileReader Java의 플랫폼 기본 인코딩을 사용합니다.이 인코딩은 실행중인 컴퓨터의 시스템 설정에 따라 다르며 일반적으로 해당 로캘의 사용자에게 가장 인기있는 인코딩입니다.

이 “최상의 추측”이 올바르지 않으면 인코딩을 명시 적으로 지정해야합니다. 불행히도 FileReader이것을 허용하지 않습니다 (API의 주요 감독). 대신 new InputStreamReader(new FileInputStream(filePath), encoding)파일에 대한 메타 데이터에서 인코딩 을 사용 하고 이상적으로 가져와야합니다.


답변

Java 11부터는 다음을 사용할 수 있습니다.

public FileReader(String fileName, Charset charset) throws IOException;


답변

Java 7+ doc의 경우 다음을 사용할 수 있습니다.

BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);

여기에 모든 Charsets doc가 있습니다

예를 들어 파일이 CP1252에있는 경우이 방법을 사용하십시오.

Charset.forName("windows-1252");

IO 및 NIO doc 모두에 대한 Java 인코딩의 다른 표준 이름은 다음과 같습니다.

파일에 정확히 인코딩되어 있는지 모르는 경우 Google 의이 도구와 같은 타사 라이브러리를 사용하면 상당히 깔끔합니다.


답변

InputStreamReader를 사용하는 FileInputStream은 FileReader를 직접 사용하는 것보다 낫습니다. 후자는 인코딩 문자 세트를 지정할 수 없기 때문입니다.

다음은 BufferedReader, FileInputStream 및 InputStreamReader를 함께 사용하여 파일에서 행을 읽을 수있는 예제입니다.

List<String> words = new ArrayList<>();
List<String> meanings = new ArrayList<>();
public void readAll( ) throws IOException{
    String fileName = "College_Grade4.txt";
    String charset = "UTF-8";
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(
            new FileInputStream(fileName), charset));

    String line;
    while ((line = reader.readLine()) != null) {
        line = line.trim();
        if( line.length() == 0 ) continue;
        int idx = line.indexOf("\t");
        words.add( line.substring(0, idx ));
        meanings.add( line.substring(idx+1));
    }
    reader.close();
}


답변

키릴 자모와 같은 라틴 언어의 다른 경우 다음과 같이 사용할 수 있습니다.

FileReader fr = new FileReader("src/text.txt", StandardCharsets.UTF_8);

.txt파일이 UTF-8(기본이 아닌 ANSI) 형식 으로 저장되어 있는지 확인하십시오 . 건배!


답변