กำลังอ่าน InputStream เป็น UTF-8


97

ฉันพยายามอ่านจาก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พื้นฐานซึ่งคุณสามารถตรวจสอบการเข้ารหัสเนื้อหาจากนั้นเปิด InputStreamReader ด้วยอาร์กิวเมนต์ที่ถูกต้อง การตรวจสอบแหล่งที่มาอย่างรวดเร็วไม่ได้ทำให้เกิดสิ่งใดที่ดูเหมือนจะทำเพื่อคุณซึ่งดูเหมือนจะง่อยและผิดพลาดได้ง่ายดังนั้นฉันอาจพลาดอะไรบางอย่าง
tchrist

คำตอบ:


192

แก้ไขปัญหาของตัวเอง บรรทัดนี้:

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

7
เนื่องจาก Java 7 เป็นไปได้ที่จะเขียนให้ Charset เป็นค่าคงที่ไม่ใช่สตริง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
แทนที่จะเป็นไฟล์ + = str ให้สร้าง StringBuilder และต่อท้าย คอมไพเลอร์อาจสามารถเพิ่มประสิทธิภาพสตริงต่อท้ายได้ แต่มีแนวโน้มว่าจะสร้างขยะจำนวนมาก
ดู

2
หากคุณต้องการแปลง BufferedReader เป็นสตริงให้ใช้ Apache Commons อย่าสร้างเวลใหม่: String myStr = org.apache.commons.io.IOUtils.toString (myBufferedReaderInstance);
Jaime Marín

8
UTF8 = "utf8", ตัวแปรที่ดี;)
Nicofisi

8

ฉันพบปัญหาเดิมทุกครั้งที่พบว่ามีอักขระพิเศษทำเครื่องหมายว่า เพื่อแก้ปัญหานี้ฉันลองใช้การเข้ารหัส: ISO-8859-1

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

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

}

ฉันหวังว่านี่จะช่วยทุกคนที่เห็นโพสต์นี้


1
คุณช่วยบอกได้ไหมว่าอะไรคืออักขระที่ไม่รองรับใน UTF-8?
USM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.