Читання InputStream як UTF-8


96

Я намагаюся читати з text/plainфайлу через Інтернет, підряд за рядком. Зараз у мене код:

URL url = new URL("http://kuehldesign.net/test.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
LinkedList<String> lines = new LinkedList();
String readLine;

while ((readLine = in.readLine()) != null) {
    lines.add(readLine);
}

for (String line : lines) {
    out.println("> " + line);
}

Файл, test.txtмістить ¡Hélló!, який я використовую для тестування кодування.

Коли я переглядаю OutputStream( out), я бачу це як > ¬°H√©ll√≥!. Я не вірю, що це проблема з тим, що OutputStreamя можу обійтися out.println("é");без проблем.

Будь-які ідеї для читання у формі InputStreamUTF-8? Дякую!


1
Протокол HTTP визначає кодування. Чому ви не використовуєте бібліотечний API, який обробляє це для вас? Вам ніколи не доведеться вгадувати таке кодування. Я не хочу бути негативним: у вас чудово виходить! Мені просто цікаво, чи немає простішого шляху.
tchrist

1
На text/plainжаль, у мене не буде доступу до сервера, який обслуговує файл, на жаль, і він не використовує кодування UTF-8. Я не знав жодної хорошої мережевої бібліотеки; будь-які пропозиції?
Кріс Куель

1
Дивлячись на документи , я не думаю, що вам взагалі доведеться вказувати кодування. Я здивований, що вони дають вам байт-потік! У вас є доступ до основної URLConnection , з якої ви можете перевірити Content-Encoding, а потім відкрити InputStreamReader з правильним аргументом. Швидка перевірка джерела не виявляє нічого, що, здається, робить це для вас, що здається досить похмурим кульгавим та схильним до помилок, тому я, можливо, щось пропустив.
tchrist

Відповіді:


189

Вирішив власну проблему. Цей рядок:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

потрібно:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));

або з Java 7:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));

3
Я майже впевнений, що форма конструктора не призведе до виключення з недійсного введення. Вам потрібно використовувати CharsetDecoder decаргумент. Це та сама помилка дизайну Java, яку OutputStreamWriterмають конструктори: лише один із чотирьох насправді поблажливо повідомляє, коли щось піде не так. Знову ж вам доведеться використовувати і химерний CharsetDecoder decаргумент. Єдине безпечне і розумне, що потрібно зробити - це вважати всі інші конструктори застарілими, оскільки їм не можна довіряти, щоб вони поводились.
tchrist

6
Оскільки Java 7 можна писати StandardCharsets.UTF_8
набір символів

18
String file = "";

try {

    InputStream is = new FileInputStream(filename);
    String UTF8 = "utf8";
    int BUFFER_SIZE = 8192;

    BufferedReader br = new BufferedReader(new InputStreamReader(is,
            UTF8), BUFFER_SIZE);
    String str;
    while ((str = br.readLine()) != null) {
        file += str;
    }
} catch (Exception e) {

}

Спробуйте це,.. :-)


8
Замість файлу + = str створіть StringBuilder та додайте до цього. Компілятор, можливо, зможе оптимізувати додавання рядка, але, швидше за все, він створює багато сміття
море та

2
Якщо ви хочете перетворити BufferedReader в рядок, використовуйте Apache Commons, не винаходийте wheal: String myStr = org.apache.commons.io.IOUtils.toString (myBufferedReaderInstance);
Хайме Марін,

8
UTF8 = "utf8", приємна змінна;)
Нікофісі

7

Я стикався з тією ж проблемою щоразу, коли виявляє, що спеціальний символ позначає це як . щоб вирішити це, я спробував використовувати кодування: ISO-8859-1

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("txtPath"),"ISO-8859-1"));

while ((line = br.readLine()) != null) {

}

Сподіваюся, це може допомогти кожному, хто бачить цю публікацію.


1
Не могли б ви сказати, які символи не підтримуються в UTF-8?
USM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.