Trình tạo mã hóa an toàn
Để Java thông báo chính xác cho bạn về các lỗi mã hóa là một việc khó. Bạn phải sử dụng chi tiết nhất và, than ôi, được sử dụng ít nhất trong số bốn cấu trúc thay thế cho mỗi cấu trúc InputStreamReader
và OutputStreamWriter
để nhận được một ngoại lệ thích hợp về trục trặc mã hóa.
Đối với I / O tệp, hãy luôn đảm bảo luôn sử dụng làm đối số thứ hai cho cả hai OutputStreamWriter
và InputStreamReader
đối số bộ mã hóa ưa thích:
Charset.forName("UTF-8").newEncoder()
Có những khả năng khác thậm chí còn kỳ diệu hơn, nhưng không có khả năng nào trong ba khả năng đơn giản hơn phù hợp với việc xử lý ngoại lệ. Những điều này làm:
OutputStreamWriter char_output = new OutputStreamWriter(
new FileOutputStream("some_output.utf8"),
Charset.forName("UTF-8").newEncoder()
);
InputStreamReader char_input = new InputStreamReader(
new FileInputStream("some_input.utf8"),
Charset.forName("UTF-8").newDecoder()
);
Đối với việc chạy với
$ java -Dfile.encoding=utf8 SomeTrulyRemarkablyLongcLassNameGoeShere
Vấn đề là điều đó sẽ không sử dụng biểu mẫu đối số bộ mã hóa đầy đủ cho các luồng ký tự, và vì vậy bạn sẽ lại bỏ lỡ các vấn đề mã hóa.
Ví dụ dài hơn
Đây là một ví dụ dài hơn, ví dụ này quản lý một quá trình thay vì một tệp, trong đó chúng tôi quảng bá hai luồng byte đầu vào khác nhau và một luồng byte đầu ra tất cả thành luồng ký tự UTF-8 với xử lý ngoại lệ đầy đủ :
Process
slave_process = Runtime.getRuntime().exec("perl -CS script args");
OutputStream
__bytes_into_his_stdin = slave_process.getOutputStream();
OutputStreamWriter
chars_into_his_stdin = new OutputStreamWriter(
__bytes_into_his_stdin,
Charset.forName("UTF-8").newEncoder()
);
InputStream
__bytes_from_his_stdout = slave_process.getInputStream();
InputStreamReader
chars_from_his_stdout = new InputStreamReader(
__bytes_from_his_stdout,
Charset.forName("UTF-8").newDecoder()
);
InputStream
__bytes_from_his_stderr = slave_process.getErrorStream();
InputStreamReader
chars_from_his_stderr = new InputStreamReader(
__bytes_from_his_stderr,
Charset.forName("UTF-8").newDecoder()
);
Bây giờ bạn có ba dòng nhân vật mà tất cả tăng ngoại lệ về mã hóa lỗi, tương ứng gọi là chars_into_his_stdin
, chars_from_his_stdout
và chars_from_his_stderr
.
Điều này chỉ phức tạp hơn một chút so với những gì bạn cần cho vấn đề của mình, giải pháp mà tôi đã đưa ra trong nửa đầu của câu trả lời này. Điểm mấu chốt là đây là cách duy nhất để phát hiện lỗi mã hóa.
Chỉ cần đừng khiến tôi bắt đầu về PrintStream
các ngoại lệ ăn uống.
InputStreamReader char_input = new InputStreamWriter
nên đọc:InputStreamReader char_input = new InputStreamReader
và hàmInputStreamReader
tạo nhận aCharsetDecoder
, không phải aCharsetEncoder
.