[java] “java.nio.charset.MalformedInputException : Input length = 1″을 피하기위한 모든 포함 문자셋?

디렉토리의 텍스트 기반 파일을 읽는 Java로 간단한 wordcount 프로그램을 만들고 있습니다.

그러나 계속 오류가 발생합니다.

java.nio.charset.MalformedInputException: Input length = 1

이 코드 줄에서 :

BufferedReader reader = Files.newBufferedReader(file,Charset.forName("UTF-8"));

Charset텍스트 파일에 일부 문자가 포함되지 않은 a 를 사용했기 때문에이 메시지를 얻을 수 있으며 일부는 다른 언어의 문자를 포함합니다. 하지만 그 캐릭터를 포함하고 싶습니다.

나중에 JavaDocs 에서는 Charset선택 사항이며 파일을보다 효율적으로 읽는 데만 사용 된다는 사실을 알게 되었으므로 코드를 다음과 같이 변경했습니다.

BufferedReader reader = Files.newBufferedReader(file);

그러나 일부 파일은 여전히 MalformedInputException. 이유를 모르겠습니다.

Charset다양한 유형의 문자가있는 텍스트 파일을 읽을 수 있는 모든 기능이 있는지 궁금합니다 .

감사.



답변

지원되는 인코딩 목록이 필요할 수 있습니다. 각 파일에 대해 UTF-8로 시작하여 각 인코딩을 차례로 시도하십시오. 를 잡을 때마다 MalformedInputException다음 인코딩을 시도하십시오.


답변

Files.newBufferedReader에서 BufferedReader 만들기

Files.newBufferedReader(Paths.get("a.txt"), StandardCharsets.UTF_8);

응용 프로그램을 실행할 때 다음 예외가 발생할 수 있습니다.

java.nio.charset.MalformedInputException: Input length = 1

그러나

new BufferedReader(new InputStreamReader(new FileInputStream("a.txt"),"utf-8"));

잘 작동합니다.

다른 점은 전자가 CharsetDecoder 기본 작업을 사용한다는 것입니다.

잘못된 입력 및 매핑 할 수없는 문자 오류에 대한 기본 조치는이를 보고 하는 것입니다.

후자는 REPLACE 작업을 사용합니다.

cs.newDecoder().onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE)


답변

ISO-8859-1은 MalformedInputException을 발생시키지 않도록 보장된다는 점에서 모든 것을 포함하는 문자 세트입니다. 따라서 입력이이 문자 세트에없는 경우에도 디버깅에 좋습니다. 그래서:-

req.setCharacterEncoding("ISO-8859-1");

내 입력에 이중 오른쪽 따옴표 / 왼쪽 이중 따옴표 문자가 있었고 US-ASCII와 UTF-8 모두에 MalformedInputException이 발생했지만 ISO-8859-1이 작동했습니다.


답변

또한 오류 메시지와 함께이 예외가 발생했습니다.

java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.BufferedWriter.write(Unknown Source)
at java.io.Writer.write(Unknown Source)

사용하려고 할 때 이상한 버그가 발생하는 것을 발견했습니다.

BufferedWriter writer = Files.newBufferedWriter(Paths.get(filePath));

클래스의 일반 유형에서 캐스트 된 문자열 “orazg 54″를 작성합니다.

//key is of generic type <Key extends Comparable<Key>>
writer.write(item.getKey() + "\t" + item.getValue() + "\n");

이 문자열은 다음 코드 포인트가있는 문자를 포함하는 길이 9입니다.

111114 97122103 9 53 52 10

그러나 클래스의 BufferedWriter가 다음으로 대체되는 경우 :

FileOutputStream outputStream = new FileOutputStream(filePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));

예외없이이 문자열을 성공적으로 쓸 수 있습니다. 또한 문자에서 동일한 문자열을 작성하면 여전히 정상적으로 작동합니다.

String string = new String(new char[] {111, 114, 97, 122, 103, 9, 53, 52, 10});
BufferedWriter writer = Files.newBufferedWriter(Paths.get("a.txt"));
writer.write(string);
writer.close();

이전에는 첫 번째 BufferedWriter를 사용하여 문자열을 쓸 때 예외가 발생하지 않았습니다. java.nio.file.Files.newBufferedWriter (path, options)에서 생성 된 BufferedWriter에 발생하는 이상한 버그입니다.


답변

ISO_8859_1 저를 위해 일했습니다! 쉼표로 구분 된 값이있는 텍스트 파일을 읽고있었습니다.


답변

사용 가능한 문자 집합을 기반으로 결과 목록을 표준 출력으로 인쇄하기 위해 다음을 작성했습니다. 또한 어떤 문자가 문제를 일으키는 지 문제를 해결하는 경우 0 기반 줄 번호에서 실패한 줄을 알려줍니다.

public static void testCharset(String fileName) {
    SortedMap<String, Charset> charsets = Charset.availableCharsets();
    for (String k : charsets.keySet()) {
        int line = 0;
        boolean success = true;
        try (BufferedReader b = Files.newBufferedReader(Paths.get(fileName),charsets.get(k))) {
            while (b.ready()) {
                b.readLine();
                line++;
            }
        } catch (IOException e) {
            success = false;
            System.out.println(k+" failed on line "+line);
        }
        if (success)
            System.out.println("*************************  Successs "+k);
    }
}


답변

이것을 시도하십시오 .. 나는 동일한 문제가 있었는데, 아래 구현이 나를 위해 일했습니다.

Reader reader = Files.newBufferedReader(Paths.get(<yourfilewithpath>), StandardCharsets.ISO_8859_1);

그런 다음 원하는 곳에서 Reader를 사용하십시오.

예 :

CsvToBean<anyPojo> csvToBean = null;
    try {
        Reader reader = Files.newBufferedReader(Paths.get(csvFilePath),
                        StandardCharsets.ISO_8859_1);
        csvToBean = new CsvToBeanBuilder(reader)
                .withType(anyPojo.class)
                .withIgnoreLeadingWhiteSpace(true)
                .withSkipLines(1)
                .build();

    } catch (IOException e) {
        e.printStackTrace();
    }