2010-12-14 24 views
6

All,java.net.URLConnection.guessContentTypeFromStream và text/plain

Tôi cố gắng để xác định tập tin văn bản đơn giản với kết thúc dòng Mac và, bên trong một InputStream, âm thầm chuyển đổi chúng sang Windows hoặc Linux kết thúc dòng (quan trọng một phần là nhân vật LF, thực sự). Cụ thể, tôi đang làm việc với một số API lấy InputStream và bị khóa cứng để tìm kiếm \ n làm dòng mới.

Đôi khi, tôi nhận tệp nhị phân. Rõ ràng, một tập tin không phải là văn bản giống như không nên thay thế này được thực hiện, bởi vì giá trị đó sẽ xảy ra tương ứng với \ r rõ ràng là không thể im lặng được theo sau bởi một \ n mà không mangling những điều xấu.

Tôi đang cố gắng sử dụng java.net.URLConnection.guessContentTypeFromStream và chỉ thực hiện chuyển đổi dòng cuối nếu loại là văn bản/đồng bằng. Thật không may, "text/plain" dường như không có âm hưởng về giá trị trả về; tất cả những gì tôi nhận được là null cho các tệp văn bản phẳng của mình và có thể không an toàn để giả định rằng tất cả các tệp không xác định được đều có thể được sửa đổi.

Thư viện nào tốt hơn (tốt nhất là trong kho lưu trữ Maven công cộng và nguồn mở) tôi có thể sử dụng để thực hiện việc này không? Ngoài ra, làm thế nào tôi có thể làm cho guessContentTypeFromStream làm việc cho tôi? Tôi biết tôi đang mô tả một ứng dụng độc hại và không có giải pháp nào có thể hoàn hảo, nhưng tôi chỉ nên coi "null" có khả năng là "text/plain" và tôi chỉ cần viết nhiều mã hơn để tìm bằng chứng rằng nó không phải là 't?

+2

+1 cho "gamut". – skaffman

Trả lời

2

Dường như với tôi rằng những gì bạn đang hỏi là xác định xem tệp có phải là văn bản hay không. Cho rằng, có một giải pháp here mà dường như ngay:

Cấp, anh ta nói về unix, bash và perl nhưng khái niệm này là như nhau:

Trừ khi bạn kiểm tra từng byte của tập tin , bạn sẽ không nhận được điều này 100%. Và có một hiệu suất lớn nhấn với việc kiểm tra từng byte. Nhưng sau một số thử nghiệm, tôi đã giải quyết trên một thuật toán phù hợp với tôi. Tôi kiểm tra dòng đầu tiên và khai báo tệp là nhị phân nếu tôi gặp phải ngay cả một byte không phải văn bản. Có vẻ như một chút chùng, tôi biết, nhưng tôi dường như có được đi với nó.

EDIT # 1:
Mở rộng trên loại dung dịch, nó có vẻ như một cách tiếp cận hợp lý sẽ đảm bảo các tập tin không chứa các ký tự không ascii (trừ khi bạn đang làm việc với các tập tin mà không -Tiếng Anh ... đó là một giải pháp khác). Điều này có thể được thực hiện bằng cách kiểm tra nếu nội dung tập tin như là một String không phù hợp này:

// -- uses commons-io 
String fileAsString = FileUtils.readFileToString(new File("file-name-here")); 
boolean isTextualFile = fileAsString.matches(".*\\p{ASCII}+.*"); 

EDIT # 2
Bạn có thể muốn thử loại này như regex của bạn, hoặc một cái gì đó gần gũi với nó. Mặc dù, tôi sẽ thừa nhận nó có thể có khả năng sử dụng một số tinh chỉnh.

".*(?:\\p{Print}|\\p{Space})+.*" 
+0

Tôi sẽ sử dụng một cách tiếp cận tương tự như vậy nếu mọi thứ khác thất bại, ngoại trừ ít duyên dáng hơn một regex. (kiểm tra từng byte, ở đây tôi đến!) Thay vì một dòng, tôi có lẽ sẽ sử dụng một số char cố định, chủ yếu là để không có nguy cơ một overrun đánh dấu của tôi (...) vị trí trên BufferedReader của tôi.Đó là một lớp nhân vật gây đau đầu, mặc dù; hình thức Java là gì, đối với những người trong chúng ta không nói tiếng Perl? –

+1

Tôi tự hỏi làm thế nào mà hành vi trên textfiles với một BOM Unicode. – BalusC

+0

Các biểu thức thông thường được chỉ định hơi quá khoan dung, nhưng lấy ra hàng đầu và đuôi. * (Chúng tôi muốn các ký tự bên ngoài lớp bị loại!) Đã làm điều đó. Cảm ơn. –

Các vấn đề liên quan