2010-09-27 12 views
16

Tệp được đề cập không nằm trong tầm kiểm soát của tôi. Hầu hết các chuỗi byte là hợp lệ UTF-8, nó không phải là ISO-8859-1 (hoặc một mã hóa khác). Tôi muốn làm hết sức mình để trích xuất càng nhiều thông tin càng tốt.Làm thế nào để phát hiện các chuỗi byte UTF-8 bất hợp pháp để thay thế chúng trong java inputstream?

Tệp có chứa một vài chuỗi byte bất hợp pháp, những tệp này phải được thay thế bằng ký tự thay thế.

Nó không phải là một nhiệm vụ dễ dàng, nó nghĩ rằng nó đòi hỏi một số kiến ​​thức về máy trạng thái UTF-8.

Oracle có một wrapper mà làm những gì tôi cần:
UTF8ValidationFilter javadoc

Có một cái gì đó như thế có sẵn (mục đích thương mại hoặc phần mềm như miễn phí)?

Cảm ơn
-stephan

Giải pháp:

final BufferedInputStream in = new BufferedInputStream(istream); 
final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder(); 
charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE); 
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 
final Reader inputReader = new InputStreamReader(in, charsetDecoder); 
+10

Tôi ghét điều này. nhà sản xuất nội dung nên tạo nội dung hợp lệ, không yêu cầu người tiêu dùng đoán và sửa. Điều đó đã gây ra rất nhiều rắc rối trong ngành của chúng tôi. – irreputable

Trả lời

12

java.nio.charset.CharsetDecoder làm những gì bạn cần. Lớp này cung cấp giải mã ký tự với các hành động có thể xác định người dùng trên các loại lỗi khác nhau (xem onMalformedInput()onUnmappableCharacter()).

CharsetDecoder ghi vào OutputStream, bạn có thể ống vào một InputStream sử dụng java.io.PipedOutputStream, tạo hiệu quả lọc InputStream.

+0

Đó là một lời cảm ơn rất hữu ích. – user85155

+0

@Henning - điều gì sẽ xảy ra nếu tôi muốn biết dòng xe nào có kẻ xấu? – Dejell

+1

@Dejel bạn có thể chia đầu vào thành các dòng và cố gắng phát hiện các dòng lỗi trên mỗi dòng. –

0

Một cách là đọc một vài byte đầu tiên để kiểm tra Dấu thứ tự byte (nếu có). Thông tin thêm về BOM: http://en.wikipedia.org/wiki/Byte_order_mark Trong url đã cho, bạn sẽ tìm thấy một bảng các byte BOM. Tuy nhiên, một vấn đề là, UTF-8 không yêu cầu sử dụng BOM trong tiêu đề của nó. Có một cách khác để giải quyết vấn đề là nhận dạng mẫu (đọc vài byte-8 bit mỗi lần). Dù sao, đây là giải pháp phức tạp ..

+0

Sự cố không phải là BOM, nó đã bị xóa. Có một BOMStripperInputStream nổi xung quanh, giúp ở đây: http://code.google.com/p/train-graph/source/browse/trunk/src/org/paradise/etrc/data/BOMStripperInputStream.java?r=31 – user85155

0

Hành vi bạn muốn đã là mặc định cho InputStreamReader. Vì vậy, không cần phải chỉ định nó cho mình. Điều này đủ:

final BufferedInputStream in = new BufferedInputStream(istream); 
final Reader inputReader = new InputStreamReader(in, StandardCharsets.UTF_8); 
Các vấn đề liên quan