2010-02-22 7 views
8

Tôi có một ứng dụng web cho phép người dùng tải lên nội dung của họ để xử lý. Công cụ xử lý mong đợi UTF8 (và tôi đang soạn XML từ các tệp của nhiều người dùng), vì vậy tôi cần đảm bảo rằng tôi có thể giải mã đúng các tệp được tải lên.Có thể tự động giải mã tệp người dùng thành Unicode không? [C#]

Vì tôi sẽ ngạc nhiên nếu bất kỳ người sử dụng tôi đã biết tập tin của họ thậm chí mã hóa, tôi có rất ít hy vọng họ sẽ có thể chính xác định bảng mã (decoder) để sử dụng. Và như vậy, ứng dụng của tôi là trái với nhiệm vụ phát hiện trước khi giải mã.

Điều này có vẻ như một vấn đề phổ quát như vậy, tôi ngạc nhiên không tìm thấy khả năng khung hoặc công thức chung cho giải pháp. Có thể nào tôi không tìm kiếm với các cụm từ tìm kiếm có ý nghĩa?

Tôi đã triển khai phát hiện BOM nhận thức (http://en.wikipedia.org/wiki/Byte_order_mark) nhưng tôi không chắc chắn tần suất tệp sẽ được tải lên với BOM để chỉ mã hóa và điều này không hữu ích đối với hầu hết các tệp không phải UTF.

Câu hỏi của tôi đun sôi xuống:

  1. là phát hiện BOM-aware đủ cho phần lớn các tập tin?
  2. Trong trường hợp phát hiện BOM không thành công, bạn có thể thử các bộ giải mã khác nhau và xác định xem chúng có "hợp lệ" không? (Các nỗ lực của tôi cho biết câu trả lời là "không").
  3. Trong trường hợp nào thì tệp "hợp lệ" không thành công với khung công cụ mã hóa/giải mã C#?
  4. Có kho lưu trữ ở bất kỳ nơi nào có nhiều tệp với các mã hóa khác nhau để sử dụng để thử nghiệm không?
  5. Trong khi tôi hỏi cụ thể về C# /. NET, tôi muốn biết câu trả lời cho Java, Python và các ngôn ngữ khác cho lần sau tôi phải làm điều này.

Cho đến nay tôi đã tìm thấy:

  • A "hợp lệ" UTF-16 tập với Ctrl-S nhân vật đã gây ra mã hóa sang UTF-8 để ném một ngoại lệ (nhân vật bất hợp pháp?) (Đó là ngoại lệ mã hóa XML.)
  • Giải mã tệp UTF-16 hợp lệ với UTF-8 thành công nhưng cung cấp văn bản có ký tự rỗng. Huh?
  • Hiện tại, tôi chỉ mong đợi các tệp UTF-8, UTF-16 và có thể là ISO-8859-1, nhưng tôi muốn giải pháp có thể mở rộng nếu có thể.
  • Tập hợp tệp đầu vào hiện tại của tôi không đủ rộng để phát hiện tất cả các sự cố xảy ra với tệp trực tiếp.
  • Mặc dù các tệp tôi đang cố gắng giải mã là "văn bản" Tôi nghĩ chúng thường được tạo bằng các phương thức để lại các ký tự rác trong các tệp. Do đó các tệp "hợp lệ" có thể không phải là "thuần túy". Oh niềm vui.

Cảm ơn.

+0

bạn làm cho gì nghĩ UTF-8 và UTF-16 tương thích? Một cửa hàng dữ liệu trong khối byte đơn, khác trong khối 2-byte ... –

+0

BOM chủ yếu được sử dụng trên hệ điều hành Microsoft, Unices thích mã hóa withoug BOM. – Vlad

+0

Cho dù ký tự 'Ctrl-S' có được phép hay không, không phụ thuộc vào định dạng của bạn. Cả UTF-8 và UTF-16 đều có thể mã hóa 'Ctrl-S', chỉ dành cho phần mềm (sử dụng UTF-8 thu được) ký tự này có thể là bất ngờ. – Vlad

Trả lời

2

Bạn đã thử đọc một mặt cắt ngang đại diện của các tệp của mình từ người dùng, chạy chúng qua chương trình của bạn, kiểm tra, sửa bất kỳ lỗi nào và di chuyển không?

Tôi đã tìm thấy Tệp.ReadAllLines() khá hiệu quả trên rất nhiều ứng dụng mà không phải lo lắng về tất cả các mã hóa. Dường như nó xử lý khá tốt.

Xmlreader() đã hoạt động khá tốt khi tôi đã tìm ra cách sử dụng nó đúng cách.

Có thể bạn có thể đăng một số ví dụ cụ thể về dữ liệu và nhận được một số phản hồi tốt hơn.

+0

Cuộc bỏ phiếu ẩn danh. Yêu thích của tôi. –

+0

câu trả lời hợp lệ của nó, tại sao lại là downvote? –

+0

Cảm ơn, nhưng tôi đang tìm một giải pháp đa năng. Trong ứng dụng này, ứng dụng được triển khai tại trang web của khách hàng và tôi không có quyền truy cập (hoặc sự cho phép pháp lý) đối với các tệp. Chúng là * bất kỳ tài liệu văn bản nào mà người dùng muốn tải lên. Một số là PDF-to-văn bản, một số được cạo từ các trang web, một số là từ PPT slide, một số là .... ai biết được. – NVRAM

1

Đây là vấn đề nổi tiếng. Bạn có thể thử làm những gì Internet Explorer đang làm. Đây là một số article trong CodeProject mô tả giải pháp của Microsoft cho vấn đề này. Tuy nhiên không có giải pháp nào chính xác 100% vì mọi thứ đều dựa trên heuristcs. Và nó cũng không an toàn để giả định rằng một BOM sẽ có mặt.

3

Sẽ không có một cách hoàn toàn đáng tin cậy, nhưng bạn có thể nhận được kết quả "khá tốt" với một số chẩn đoán.

  • Nếu dữ liệu bắt đầu bằng BOM, hãy sử dụng dữ liệu đó.
  • Nếu dữ liệu chứa 0 byte, có thể là utf-16 hoặc ucs-32. Bạn có thể phân biệt giữa các biến thể này và giữa các biến thể lớn và cuối nhỏ bằng cách xem các vị trí của 0 -34
  • Nếu dữ liệu có thể được giải mã là utf-8 (không có lỗi) thì đó là rất có thể là utf-8 (hoặc US-ASCII, nhưng đây là tập con của utf-8)
  • Tiếp theo, nếu bạn muốn đi quốc tế, hãy ánh xạ cài đặt ngôn ngữ của trình duyệt sang mã hóa có khả năng nhất cho ngôn ngữ đó.
  • Cuối cùng, giả sử ISO-8859-1

dù "khá tốt" là "đủ tốt" phụ thuộc vào ứng dụng của bạn, tất nhiên. Nếu bạn cần chắc chắn, bạn có thể muốn hiển thị kết quả dưới dạng xem trước và cho phép người dùng xác nhận rằng dữ liệu có vẻ đúng. Nếu không, hãy thử mã hóa có khả năng tiếp theo, cho đến khi người dùng hài lòng.

Lưu ý: thuật toán này sẽ không hoạt động nếu dữ liệu chứa ký tự rác. Ví dụ, một byte rác đơn lẻ nếu không hợp lệ utf-8 sẽ làm cho giải mã utf-8 thất bại, làm cho thuật toán đi sai đường dẫn. Bạn có thể cần phải thực hiện các biện pháp bổ sung để xử lý việc này. Ví dụ: nếu bạn có thể xác định trước có thể rác, hãy xóa nó trước khi bạn cố gắng xác định mã hóa. (Không quan trọng nếu bạn dải quá tích cực, một khi bạn đã xác định mã hóa, bạn có thể giải mã dữ liệu chưa được lưu trữ ban đầu, chỉ cần định cấu hình bộ giải mã để thay thế các ký tự không hợp lệ thay vì ném ngoại lệ.) . Nhưng điều này có thể phụ thuộc nhiều vào bản chất của rác thải của bạn, tức là những giả định mà bạn có thể thực hiện.

+1

Điều này hữu ích, mặc dù lưu ý rằng một số tệp UTF16LE tôi đã giải mã * mà không có ngoại lệ * bởi khung mã hóa C#/.NET; có * lỗi * (ký tự null) nhưng không có * ngoại lệ *. Ý định của tôi là tự động phát hiện (do đó gửi bài) và tôi đã thực hiện một phần vì tôi đã phát hiện MSWord, PDF và các tệp không phải văn bản khác, nhưng vấn đề đang xác định khi mã hóa là * phải *. – NVRAM

+0

Bạn nói đúng, kiểm tra 0 Byte cần phải đi trước, tôi đã sửa thứ tự các bước trong câu trả lời của tôi cho phù hợp – oefe

1

Bạn có thể xem giải pháp dựa trên Python được gọi là chardet. Đó là một cổng Python của mã Mozilla. Mặc dù bạn không thể sử dụng nó trực tiếp, tài liệu của nó cũng đáng đọc, như là bài báo gốc của Mozilla mà nó tham khảo.

+0

FWIW, tôi đã lấy UDE [http://code.google.com/p/ude/] biên dịch nó với Mono. Sau đó tôi chạy EXE kết quả dựa vào các tệp đã được mã hóa ISO-8859-1, -2, UTF- {8,16LE, 16BE, 32LE, 32BE} và nó chỉ nhận dạng UTF-8 đúng (được đoán là windows-1255 hoặc -1252) cho mọi thứ khác). – NVRAM

+0

Nó sẽ không nhận ra UTF-nnxE mà không có BOM; bạn đã có BOM chưa? ISO-8859-n là một phần của trí tưởng tượng - giải mã nó thành Unicode và xem bạn có bất kỳ ký tự nào trong dải ô U + 0080 đến U + 009F ;-) không –

0

Tôi gặp sự cố tương tự. Tôi cần một kịch bản PowerShell để tìm ra một tập tin được mã hóa văn bản (trong bất kỳ mã hóa phổ biến) hay không.

Đó chắc chắn không đầy đủ, nhưng đây là giải pháp của tôi ...

PowerShell search script that ignores binary files