2010-06-22 38 views
5

Tôi đã viết phương pháp sau đây để xem liệu tệp cụ thể có chứa các ký tự văn bản ASCII chỉ hoặc kiểm soát các ký tự ngoài điều đó. Bạn có thể lướt qua đoạn mã này, đề xuất các cải tiến và chỉ ra sự giám sát?Cách kiểm tra xem tệp có phải là nhị phân không?

Logic là như sau: "Nếu 500 byte đầu tiên của một tập tin chứa 5 hoặc nhiều ký tự điều khiển - báo cáo nó như là tập tin nhị phân"

cảm ơn bạn.

public boolean isAsciiText(String fileName) throws IOException { 

    InputStream in = new FileInputStream(fileName); 
    byte[] bytes = new byte[500]; 

    in.read(bytes, 0, bytes.length); 
    int x = 0; 
    short bin = 0; 

    for (byte thisByte : bytes) { 
     char it = (char) thisByte; 
     if (!Character.isWhitespace(it) && Character.isISOControl(it)) { 

      bin++; 
     } 
     if (bin >= 5) { 
      return false; 
     } 
     x++; 
    } 
    in.close(); 
    return true; 
} 

Trả lời

3

Vì bạn gọi lớp này là "isASCIIText", bạn biết chính xác những gì bạn đang tìm kiếm. Nói cách khác, nó không phải là "isTextInCurrentLocaleEncoding". Vì vậy bạn có thể chính xác hơn với:

if (thisByte < 32 || thisByte > 127) bin++; 

chỉnh sửa, một thời gian dài sau — nó chỉ ra trong một chú thích rằng kiểm tra đơn giản này sẽ được vấp lên bởi một file văn bản mà bắt đầu với rất nhiều dòng mới. Nó có thể tốt hơn để sử dụng một bảng "ok" byte, và bao gồm các ký tự có thể in (bao gồm cả vận chuyển trở lại, dòng mới và tab, và có thể tạo nguồn cấp dữ liệu mặc dù tôi không nghĩ nhiều tài liệu hiện đại sử dụng chúng), và sau đó kiểm tra cai ban.

+0

Đó là một bi kịch được đánh dấu là câu trả lời đúng, khi thuật toán này phân loại tệp chứa "this \ r \ nis \ r \ nonly \ r \ ntext" dưới dạng nhị phân. – Ingo

+1

@Đúng đúng; nó sẽ là tốt hơn để kiểm tra một số tỷ lệ kiểm soát ký tự để không kiểm soát, và cũng để kiểm tra các trường hợp đặc biệt như ký tự kiểm soát phổ biến trong văn bản. Tôi còn rất trẻ khi tôi gõ câu trả lời này :) – Pointy

3

x dường như không làm gì cả.

Điều gì xảy ra nếu tệp nhỏ hơn 500 byte?

Một số tệp nhị phân có tình huống mà bạn có thể có tiêu đề cho N byte đầu tiên của tệp chứa một số dữ liệu hữu ích cho ứng dụng nhưng thư viện nhị phân không quan tâm. Bạn có thể dễ dàng có hơn 500 byte ASCII trong phần mở đầu như sau, theo sau là dữ liệu nhị phân trong gigabyte sau.

nên xử lý ngoại lệ nếu các tập tin không thể mở được hoặc đọc vv

1

Điều đầu tiên tôi nhận thấy - không liên quan đến câu hỏi thực tế của bạn, nhưng bạn nên đóng input stream của bạn trong một khối finally để đảm bảo nó luôn luôn được thực hiện. Thông thường, điều này chỉ xử lý các trường hợp ngoại lệ, nhưng trong trường hợp của bạn, bạn thậm chí sẽ không đóng các luồng tệp khi trả lại false.

Ngoài ra, tại sao so sánh với các ký tự điều khiển ISO? Đó không phải là tệp "nhị phân", đó là "tệp chứa 5 ký tự điều khiển trở lên". Một cách tốt hơn để tiếp cận tình huống theo ý kiến ​​của tôi, sẽ đảo ngược kiểm tra - viết một hàm isAsciiText thay vào đó xác nhận rằng tất cả các ký tự trong tệp (hoặc trong 500 byte đầu tiên nếu bạn muốn) nằm trong một bộ byte đó là được biết là tốt. Về mặt lý thuyết, chỉ kiểm tra vài trăm byte đầu tiên của một tập tin có thể khiến bạn gặp rắc rối nếu nó là một tệp tổng hợp các loại (ví dụ: văn bản có ảnh nhúng), nhưng trong thực tế tôi nghi ngờ mọi tệp đó sẽ có dữ liệu đầu trang nhị phân ngay từ đầu nên có thể bạn đã OK.

0
  1. Bạn bỏ qua những gì read() trả về, điều gì sẽ xảy ra nếu các tệp ngắn hơn 500 byte?
  2. Khi bạn trả về false, bạn không đóng tệp.
  3. Khi chuyển đổi byte thành char, bạn cho rằng tệp của mình là ASCII 7 bit.
0

Điều này sẽ không hoạt động với gói cài đặt jdk cho linux hoặc solaris.chúng có khởi chạy shell-script và sau đó là blob dữ liệu bi.

lý do tại sao không kiểm tra loại mime bằng cách sử dụng một số thư viện như jMimeMagic (http://http://sourceforge.net/projects/jmimemagic/) và dựa trên mimetype cách xử lý tệp.

3
  1. Thất bại nặng nề nếu kích thước tập tin nhỏ hơn 500 byte

  2. Dòng char it = (char) thisByte; là khái niệm mơ hồ, nó pha trộn byte và ký tự khái niệm, tức là. giả định rằng mã hóa là một byte = một ký tự (chúng, nó loại trừ mã hóa unicode). Đặc biệt, nó không thành công nếu tập tin được mã hóa UTF-16.

  3. Trả lại bên trong vòng lặp (thực hành hơi xấu IMO) quên đóng tệp.

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