Đọc InputStream dưới dạng UTF-8


96

Tôi đang cố đọc từng dòng từ một text/plaintệp qua internet. Mã tôi có ngay bây giờ là:

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);
}

Tệp, test.txtchứa ¡Hélló!, mà tôi đang sử dụng để kiểm tra mã hóa.

Khi tôi xem lại OutputStream( out), tôi thấy nó là > ¬°H√©ll√≥!. Tôi không tin rằng đây là một vấn đề với OutputStreamvì tôi có thể làm out.println("é");mà không có vấn đề.

Bất kỳ ý tưởng nào để đọc dạng InputStreamUTF-8? Cảm ơn!


1
Giao thức HTTP chỉ định mã hóa. Tại sao bạn không sử dụng API thư viện để xử lý điều đó cho bạn? Bạn không bao giờ phải đoán mã hóa như thế này. Tôi không có ý tiêu cực: bạn đang làm rất tốt! Tôi chỉ tự hỏi liệu không có cách nào dễ dàng hơn.
tchrist

1
text/plainRất tiếc, tôi sẽ không có quyền truy cập vào máy chủ đang cung cấp tệp và nó không sử dụng mã hóa UTF-8. Tôi không biết về bất kỳ thư viện mạng nào tốt; bất kỳ đề xuất?
Chris Kuehl

1
Nhìn vào các tài liệu , tôi sẽ không nghĩ rằng bạn sẽ phải chỉ định mã hóa nào cả. Tôi ngạc nhiên khi họ cung cấp cho bạn một luồng byte! Bạn có quyền truy cập vào URLConnection bên dưới , từ đó bạn có thể kiểm tra Content-Encoding, sau đó mở InputStreamReader với đối số chính xác. Kiểm tra nhanh nguồn không hiển thị bất cứ điều gì có vẻ như làm điều đó cho bạn, điều này có vẻ khá tệ hại và dễ xảy ra lỗi, vì vậy có thể tôi đã bỏ sót điều gì đó.
tchrist

Câu trả lời:


189

Đã giải quyết vấn đề của riêng tôi. Đường thẳng này:

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

cần phải:

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

hoặc kể từ Java 7:

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

3
Tôi khá chắc chắn rằng biểu mẫu của hàm tạo sẽ không tạo ra ngoại lệ trên đầu vào không hợp lệ. Bạn cần sử dụng với một CharsetDecoder decđối số. Đây cũng là lỗi thiết kế Java mà các hàm OutputStreamWritertạo mắc phải: chỉ một trong bốn lỗi thực sự đủ khả năng thông báo cho bạn khi có sự cố. Bạn cũng phải sử dụng CharsetDecoder declập luận lạ lùng ở đó. Điều an toàn và lành mạnh duy nhất cần làm là xem xét tất cả các trình xây dựng khác không được dùng nữa, bởi vì chúng không thể đáng tin cậy để hoạt động.
tchrist

6
Kể từ Java 7 có thể viết cung cấp Charset là một hằng số không phải là một StringStandardCharsets.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) {

}

Thử cái này,.. :-)


8
Thay vì tệp + = str, hãy tạo một StringBuilder và thêm vào đó. Trình biên dịch có thể tối ưu hóa việc nối chuỗi, nhưng nó có khả năng tạo ra rất nhiều rác
seand

2
Nếu bạn muốn chuyển đổi BufferedReader thành một chuỗi, hãy sử dụng Apache Commons, không phát minh lại wheal: String myStr = org.apache.commons.io.IOUtils.toString (myBufferedReaderInstance);
Jaime Marín

8
UTF8 = "utf8", biến tốt;)
Nicofisi

7

Tôi gặp phải vấn đề tương tự mỗi khi nó tìm thấy một ký tự đặc biệt đánh dấu nó là . để giải quyết vấn đề này, tôi đã thử sử dụng mã hóa: ISO-8859-1

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

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

}

Tôi hy vọng điều này có thể giúp bất cứ ai xem bài đăng này.


1
Bạn có thể vui lòng cho biết các ký tự không được hỗ trợ trong UTF-8 là gì không?
USM
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.