มีวิธีง่ายๆในการหลีกเลี่ยงการจัดการกับปัญหาการเข้ารหัสข้อความหรือไม่?
มีวิธีง่ายๆในการหลีกเลี่ยงการจัดการกับปัญหาการเข้ารหัสข้อความหรือไม่?
คำตอบ:
คุณไม่สามารถหลีกเลี่ยงการจัดการกับปัญหาการเข้ารหัสข้อความได้ แต่มีวิธีแก้ไขที่มีอยู่ใน Apache Commons:
Reader
ถึงInputStream
:ReaderInputStream
Writer
ถึงOutputStream
:WriterOutputStream
คุณเพียงแค่ต้องเลือกการเข้ารหัสที่คุณต้องการ
หากคุณกำลังเริ่มต้นด้วย String คุณสามารถทำสิ่งต่อไปนี้:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
ReaderInputStream
การนำไปใช้งานที่ดีจะต้องใช้หน่วยความจำน้อยลง - ไม่จำเป็นต้องเก็บไบต์ทั้งหมดในอาร์เรย์พร้อมกัน
ผู้อ่านเกี่ยวข้องกับอักขระและข้อตกลง InputStream กับไบต์ การเข้ารหัสจะระบุวิธีที่คุณต้องการแทนอักขระของคุณเป็นไบต์ดังนั้นคุณจึงไม่สามารถเพิกเฉยต่อปัญหาได้ สำหรับการหลีกเลี่ยงปัญหาความคิดเห็นของฉันคือเลือกชุดอักขระหนึ่งชุด (เช่น "UTF-8") และติดไปด้วย
เกี่ยวกับวิธีการทำจริงตามที่ได้รับการชี้ออกมา " ชื่อที่ชัดเจนสำหรับการเรียนเหล่านี้เป็นReaderInputStreamและWriterOutputStream . " แปลกใจ " เหล่านี้จะไม่รวมอยู่ใน Java ห้องสมุด " แม้ว่าการเรียน 'ตรงข้าม' InputStreamReaderและOutputStreamWriter มีรวม
ดังนั้นผู้คนจำนวนมากได้มากับการใช้งานของตัวเองรวมทั้งApache Commons IO คุณอาจรวมไลบรารี commons-io ไว้ในโปรเจ็กต์ของคุณหรือแม้กระทั่งคัดลอกส่วนหนึ่งของซอร์สโค้ด (ซึ่งดาวน์โหลดได้ที่นี่ ) ทั้งนี้ขึ้นอยู่กับปัญหาการให้สิทธิ์การใช้งาน
ดังที่คุณเห็นเอกสารของทั้งสองคลาสระบุว่า "การเข้ารหัสชุดอักขระทั้งหมดที่ JRE รองรับได้รับการจัดการอย่างถูกต้อง"
หมายเหตุความคิดเห็นเกี่ยวกับหนึ่งในคำตอบอื่น ๆ ที่นี่กล่าวถึงข้อบกพร่องนี้ แต่มีผลกับคลาสApache Ant ReaderInputStream ( ที่นี่ ) ไม่ใช่คลาสApache Commons IO ReaderInputStream
โปรดทราบว่าหากคุณเริ่มต้นด้วย String คุณสามารถข้ามการสร้าง StringReader และสร้าง InputStream ได้ในขั้นตอนเดียวโดยใช้ org.apache.commons.io.IOUtils จากCommons IOดังนี้:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
แน่นอนว่าคุณยังคงต้องคิดถึงการเข้ารหัสข้อความ แต่อย่างน้อยการแปลงก็เกิดขึ้นในขั้นตอนเดียว
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
ซึ่งเกี่ยวข้องกับการจัดสรรสำเนารายงานเพิ่มเติมสองชุดในหน่วยความจำ ถ้ารายงานมีจำนวนมากก็แย่ ดูคำตอบของฉัน
ใช้:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
วิธีนี้ไม่จำเป็นต้องมีการแปลงล่วงหน้าเป็นString
แล้วเป็นbyte[]
ซึ่งจะจัดสรรหน่วยความจำฮีปมากขึ้นในกรณีที่รายงานมีขนาดใหญ่ มันแปลงเป็นไบต์ได้ทันทีเมื่ออ่านสตรีมจาก StringBuffer
ใช้CharSequenceInputStreamจากโครงการ Apache Commons IO
ชื่อที่ชัดเจนสำหรับคลาสเหล่านี้ ได้แก่ ReaderInputStream และ WriterOutputStream น่าเสียดายที่สิ่งเหล่านี้ไม่รวมอยู่ในไลบรารี Java อย่างไรก็ตาม Google เป็นเพื่อนของคุณ
ฉันไม่แน่ใจว่ามันจะช่วยแก้ปัญหาการเข้ารหัสข้อความทั้งหมด
มี RFEแต่ปิดอยู่จะไม่แก้ไข
คุณไม่สามารถหลีกเลี่ยงปัญหาการเข้ารหัสข้อความได้ แต่Apache commons-ioมี
โปรดทราบว่านี่คือไลบรารีที่อ้างถึงในคำตอบของ Peter ของ koders.com เพียงแค่ลิงก์ไปยังไลบรารีแทนซอร์สโค้ด
คุณกำลังพยายามเขียนเนื้อหาของ a Reader
ถึงOutputStream
หรือไม่? ถ้าเป็นเช่นนั้นคุณจะมีเวลาได้ง่ายขึ้นการตัดOutputStream
ในOutputStreamWriter
และเขียนchar
s จากReader
ไปWriter
แทนการพยายามแปลงผู้อ่านไปยังInputStream
:
final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block
คำเตือนเมื่อใช้ WriterOutputStream - มันไม่ได้จัดการกับการเขียนข้อมูลไบนารีไปยังไฟล์อย่างถูกต้องเสมอไป / เหมือนกับสตรีมเอาต์พุตทั่วไป ฉันมีปัญหากับเรื่องนี้ซึ่งต้องใช้เวลาสักพักในการติดตาม
หากทำได้ฉันขอแนะนำให้ใช้เอาต์พุตสตรีมเป็นฐานของคุณและหากคุณต้องการเขียนสตริงให้ใช้ตัวตัด OUtputStreamWriter รอบ ๆ สตรีมเพื่อทำ การแปลงข้อความเป็นไบต์มีความน่าเชื่อถือมากกว่าวิธีอื่น ๆ ซึ่งเป็นไปได้ว่าทำไม WriterOutputStream ไม่ได้เป็นส่วนหนึ่งของไลบรารี Java มาตรฐาน
คุณสามารถใช้Cactoos (ไม่มีวิธีการคงที่เฉพาะวัตถุ):
คุณสามารถแปลงวิธีอื่น ๆ ได้เช่นกัน:
สำหรับการอ่านสตริงในสตรีมโดยใช้สิ่งที่จาวาจัดหา
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));