Чтение 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. Я не знал ни о каких хороших сетевых библиотеках; какие-либо предложения?
Chris Kuehl

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
tobijdc

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
Вместо file + = str создайте StringBuilder и добавьте к нему. Компилятор может оптимизировать добавление строки, но, скорее всего, создает много мусора
seand

2
Если вы хотите преобразовать BufferedReader в строку, используйте Apache Commons, не изобретайте заново: String myStr = org.apache.commons.io.IOUtils.toString (myBufferedReaderInstance);
Хайме Марин,

8
UTF8 = "utf8", хорошая переменная;)
Никофиси 09

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.