Có cách nào dễ dàng để tránh đối phó với các vấn đề về mã hóa văn bản không?Làm thế nào để chuyển đổi một Reader thành InputStream và Writer thành OutputStream?
Trả lời
Bạn có thể không thực sự tránh đối phó với các vấn đề mã hóa văn bản, nhưng có những giải pháp hiện có:
Reader
đểInputStream
:ReaderInputStream
Writer
-OutputStream
:WriterOutputStream
Bạn chỉ cần phải chọn mã hóa của sự lựa chọn của bạn.
Tên rõ ràng cho các lớp này là ReaderInputStream và WriterOutputStream. Thật không may, chúng không được bao gồm trong thư viện Java. Tuy nhiên, google là bạn của bạn.
Tôi không chắc chắn rằng nó sẽ khắc phục tất cả các sự cố mã hóa văn bản, điều này rất đáng sợ.
There is an RFE, nhưng đã đóng, sẽ không khắc phục.
https://bugs.openjdk.java.net/browse/JDK-4103785 chứa bình luận "chúng tôi có một API công cộng cho nhân vật thiết lập mã hóa ... không có lý do thuyết phục để thêm những lớp học "- vậy làm thế nào người ta làm điều này trong Java 7, mà không có thư viện bổ sung, mười hai năm xuống đường? –
Bạn đang cố viết nội dung của số Reader
vào một số OutputStream
? Nếu vậy, bạn sẽ có một thời gian dễ dàng hơn gói các OutputStream
trong một OutputStreamWriter
và viết char
s từ Reader
đến Writer
, thay vì cố gắng để chuyển đổi người đọc một 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
Cũng lưu ý rằng, nếu bạn đang bắt đầu với một string, bạn có thể bỏ qua việc tạo ra một StringReader và tạo ra một InputStream trong một bước sử dụng org.apache.commons.io.IOUtils từ Commons IO như vậy:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
Tất nhiên bạn vẫn cần suy nghĩ về mã hóa văn bản, nhưng tại st chuyển đổi đang diễn ra trong một bước.
Phương pháp này về cơ bản là 'mới ByteArrayInputStream (report.toString(). GetBytes ("utf-8")) ', trong đó bao gồm việc phân bổ hai bản sao bổ sung của báo cáo trong bộ nhớ.Nếu báo cáo là lớn, nó là xấu Xem câu trả lời của tôi – Oliv
Nếu bạn đang bắt đầu với một String bạn cũng có thể làm như sau:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
Điều này giải quyết một vấn đề với chuỗi, nhưng không phải là bản gốc – sbeliakov
Việc triển khai 'ReaderInputStream' tốt sẽ yêu cầu ít bộ nhớ hơn - không cần phải lưu trữ tất cả các byte trong một mảng cùng một lúc. –
Tôi thích giải pháp này cho nó hoạt động khi bạn cần đơn vị mã kiểm tra chấp nhận đầu vào (ví dụ) đầu vào tiêu chuẩn. –
Bạn không thể tránh các vấn đề mã hóa văn bản, nhưng Apache commons-io có
Lưu ý đây là những thư viện được nhắc đến trong câu trả lời của koders.com của Peter, chỉ liên kết đến thư viện thay vì mã nguồn.
Vâng, Reader có giao dịch với các ký tự và giao dịch InputStream với byte. Bảng mã chỉ định cách bạn muốn đại diện cho các ký tự của bạn dưới dạng byte, vì vậy bạn không thể bỏ qua vấn đề. Để tránh các vấn đề, ý kiến của tôi là: chọn một bộ ký tự (ví dụ: "UTF-8") và gắn với nó.
Về làm thế nào để thực sự làm điều đó, như đã được chỉ ra, "tên rõ ràng cho các lớp này là ReaderInputStream và WriterOutputStream." Đáng ngạc nhiên, "những không có trong thư viện Java" mặc dù các lớp 'đối diện', InputStreamReader và OutputStreamWriterđược bao gồm.
Vì vậy, nhiều người đã đưa ra các triển khai của riêng họ, bao gồm ApacheCommons IO. Tùy thuộc vào các vấn đề cấp phép, bạn có thể sẽ bao gồm thư viện commons-io trong dự án của bạn, hoặc thậm chí sao chép một phần mã nguồn (có thể tải xuống here).
- Apache ReaderInputStream: API/source code direct link
- Apache WriterOutputStream: API/source code direct link
Như bạn có thể thấy, tài liệu hướng dẫn cả lớp khẳng định rằng "tất cả các mã hóa charset được hỗ trợ bởi JRE được xử lý một cách chính xác" .
N.B. Nhận xét về một trong các câu trả lời khác ở đây đề cập đến this bug. Nhưng điều đó ảnh hưởng đến lớp học Apache Ant ReaderInputStream (here), không Apache Commons IO lớp ReaderInputStream.
Cảnh báo khi sử dụng WriterOutputStream - nó không phải lúc nào cũng xử lý ghi dữ liệu nhị phân vào một tệp đúng/giống như luồng đầu ra thông thường. Tôi đã có một vấn đề với điều này mà đã cho tôi một thời gian để theo dõi.
Nếu có thể, tôi khuyên bạn nên sử dụng luồng đầu ra làm cơ sở của mình và nếu bạn cần viết chuỗi, hãy sử dụng trình bao bọc OUtputStreamWriter quanh luồng để thực hiện. Nó là xa đáng tin cậy hơn để chuyển đổi văn bản để byte so với cách khác xung quanh, đó là khả năng lý do tại sao WriterOutputStream không phải là một phần của thư viện chuẩn của Java
Sử dụng:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
Bằng cách này không yêu cầu trả trước chuyển đổi thành String
và sau đó đến byte[]
, phân bổ nhiều bộ nhớ heap hơn, trong trường hợp báo cáo lớn. Nó chuyển đổi thành byte khi di chuyển khi luồng được đọc, ngay từ StringBuffer.
Nó sử dụng CharSequenceInputStream từ dự án Apache Commons IO.
Để đọc chuỗi trong luồng chỉ bằng cách sử dụng nguồn cung cấp java.
InputStream s = new BufferedInputStream(new ReaderInputStream(new StringReader("a string")));
ReaderInputStream nằm trong Apache Commons IO. –
Bạn có thể sử dụng Cactoos (không có phương pháp tĩnh, chỉ có đối tượng):
Bạn có thể chuyển đổi các cách khác xung quanh quá:
- 1. Làm thế nào để chuyển đổi byte [] thành InputStream?
- 2. Làm thế nào tôi có thể chuyển đổi một InputStream không nén thành một Gzip'ed InputStream một cách hiệu quả?
- 3. Chuyển đổi StreamWriter thành OutputStream trong java?
- 4. Làm thế nào để chuyển đổi chuỗi thành Hex và Hex thành chuỗi?
- 5. Chuyển đổi InputStream (Hình ảnh) thành ByteArrayInputStream
- 6. Làm cách nào để chuyển đổi một InputStream thành một chuỗi trong Java?
- 7. Làm thế nào tôi có thể chuyển đổi một đối tượng thành Inputstream
- 8. Làm thế nào để chuyển đổi StringBuffer thành InputStream trong Java ME?
- 9. Cách chuyển đổi chuỗi thành Reader trong java
- 10. Làm thế nào để bạn có thể tạo một OutputStream thành một StreamingDataHandler?
- 11. Làm thế nào để chuyển đổi một byte thành bit?
- 12. Làm thế nào để chuyển đổi InputStream để FileInputStream
- 13. Làm thế nào để chuyển đổi một chuỗi thành CharSequence?
- 14. Làm thế nào để chuyển đổi một SparseArray thành ArrayList?
- 15. Chuyển đổi động XML thành JSON
- 16. Làm thế nào để chuyển đổi sRGB thành CIELAb và CIELab thành sRGB hiệu quả?
- 17. Làm thế nào để chuyển đổi một mảng float thành một byte [] và ngược lại?
- 18. Làm thế nào để mã hóa một CharSequence bằng cách sử dụng một CharSet (không chuyển đổi thành String)
- 19. Chúng ta có thể chuyển đổi một mảng byte thành một InputStream trong Java không?
- 20. Làm thế nào để bạn chuyển đổi một chuỗi thành ascii thành nhị phân trong C#?
- 21. Làm thế nào để chuyển đổi SecureString thành System.String?
- 22. làm thế nào để chuyển đổi datetime thành ngày ngắn?
- 23. Làm thế nào để chuyển đổi chuỗi thành mảng byte?
- 24. Làm thế nào để chuyển đổi JSON thành chuỗi?
- 25. Làm thế nào để chuyển đổi chuỗi thành ObjectId
- 26. Làm thế nào để chuyển đổi NSIndexPath thành NSInteger?
- 27. VB.NET: Làm thế nào để chuyển đổi chuỗi thành Ngày?
- 28. Làm thế nào để chuyển đổi Char thành Float
- 29. Làm thế nào để chuyển đổi NSString thành chuỗi C?
- 30. Làm thế nào để chuyển đổi ndarray thành mảng?
FYI: mã ReaderInputStream có lỗi trong cách đọc byte (nó sẽ không hoạt động đối với tất cả các mã hóa). Bằng chứng: http://illegalargumentexception.blogspot.com/2009/05/java-rough-guide-to-character-encoding.html#javaencoding_stringclass Có một lỗi mở: https://issues.apache.org/bugzilla/show_bug .cgi? id = 40455 – McDowell
Ngoài ra mã có bản quyền: ( – Armand
Bạn có thể tìm thấy các lớp trong thư viện commons-io của Apache: http://commons.apache.org/proper/commons-io/ –