Cụ thể là, làm thế nào bạn sẽ nói một tệp lưu trữ (jar/rar/etc.) Từ một tệp văn bản (xml/txt, độc lập với mã hóa)?Xác định loại tệp nhị phân/văn bản trong Java?
Trả lời
Không có cách nào đảm bảo, nhưng dưới đây là một vài khả năng:
1) Tìm tiêu đề trên tệp. Thật không may, tiêu đề là tập tin cụ thể, do đó, trong khi bạn có thể tìm ra rằng đó là một tập tin RAR, bạn sẽ không nhận được câu trả lời chung chung hơn cho dù đó là văn bản hoặc nhị phân.
2) Đếm số ký tự so với các loại không phải ký tự. Các tệp văn bản sẽ chủ yếu là các ký tự chữ cái trong khi các tệp nhị phân - đặc biệt là các tệp nén như rar, zip và như vậy - sẽ có xu hướng có các byte được biểu diễn đồng đều hơn.
3) Tìm kiếm mẫu lặp lại thường xuyên của các dòng mới.
Bạn có thể thử công cụ DROID.
Nếu tập tin bao gồm các byte 0x09 (tab), 0x0A (feed line), 0x0c (mẫu thức ăn chăn nuôi), 0x0D (carriage return), hoặc 0x20 qua 0x7E, sau đó nó có thể là ASCII text .
Nếu tệp chứa bất kỳ ký tự điều khiển ASCII nào khác, 0x00 đến 0x1F không bao gồm ba ký tự ở trên, thì đó có thể là dữ liệu nhị phân.
Văn bản UTF-8 tuân theo một mẫu rất cụ thể cho bất kỳ byte nào có bit thứ tự cao, nhưng mã hóa có độ dài cố định như ISO-8859-1 thì không. UTF-16 thường có thể chứa byte rỗng (0x00), nhưng chỉ ở mọi vị trí khác.
Bạn sẽ cần một heuristic yếu hơn cho bất kỳ điều gì khác.
Hãy xem thư viện JMimeMagic.
jMimeMagic là thư viện Java dành cho xác định loại tệp MIME hoặc luồng.
Thư viện thú vị, nhưng làm cách nào để giúp đỡ? Nó cho bạn biết loại mime, nhưng không cho dù đó là nhị phân hay văn bản. – Adam
@Adam Tôi không hiểu câu hỏi của bạn? Bạn có thể suy ra từ chính loại MIME cho dù tệp đó là nhị phân hay không, phải không? I E. nếu kiểu là 'text/plain', nó phải là một tệp văn bản. – dhiller
OK, tôi đã bị cùn. Những gì tôi có nghĩa là bạn vẫn phải viết thêm logic để giải thích các loại mime như nhị phân hoặc văn bản. 'văn bản/đồng bằng' không phải là loại mime dựa trên văn bản duy nhất. – Adam
Để cho bạn biết, tôi đã chọn một con đường hoàn toàn khác. Tôi trường hợp của tôi, chỉ có 2 loại tập tin, cơ hội mà bất kỳ tập tin nhất định sẽ là một nhị phân là cao. Vì vậy,
- đoán rằng tập tin được nhị phân, cố gắng làm những gì là nghĩa vụ phải được thực hiện (ví dụ deserialize)
- bắt ngoại lệ
- điều trị tập tin như văn bản
- nếu thất bại, cái gì là sai với tập tin bản thân
Tôi nghĩ rằng đây là cách tiếp cận tốt nhất. Bạn có thực sự quan tâm đến loại tệp không? Hay bạn có quan tâm liệu bạn có thể làm những việc nhất định với nó hay không. Trong nhiều trường hợp, nếu bạn có thể làm những điều đó, bạn không cần phải thực sự biết loại đó là gì. – stackexchanger
Chạy file -bi {filename}
. Nếu bất cứ điều gì nó trả về bắt đầu bằng 'text /', thì nó không phải là nhị phân, nếu không nó sẽ là. ;-)
Có vẻ như có "ứng dụng/javascript" và "ứng dụng/xml" cũng vậy. Nhìn vào đây http://en.wikipedia.org/wiki/Internet_media_type gợi ý rằng nó không đơn giản như vậy. – Aaron
Bạn có thể kiểm tra bằng 'file -i {filename}' và kiểm tra ở đó không có 'charset = binary'. –
Tôi phải nói rằng tôi không hoàn toàn nghiêm túc khi tôi trả lời câu hỏi trên. Tệp văn bản chỉ là các tệp nhị phân được diễn giải theo một cách cụ thể. Nếu bạn có nghĩa là nếu một cái gì đó là US-ASCII, sau đó bạn có thể kiểm tra mỗi byte và xem nếu nó phù hợp với định nghĩa của bạn về văn bản. Nhưng có lẽ bạn có nghĩa là * bất kỳ loại * mã hóa ký tự nào. Điều đó sẽ khó hơn rất nhiều. Đặc biệt là nếu bạn yếu tố trong những người đang sử dụng nói entropy dựa trên mã hóa (ký tự xảy ra thường đòi hỏi ít bit). Mặt khác, nếu bạn có nghĩa là tất cả mọi thứ US-ASCII, thì một hình ảnh được mã hóa Base64 cũng sẽ là văn bản? –
tôi đã sử dụng đoạn mã này và nó hoạt động cho tiếng Anh và văn bản tiếng Đức khá tốt:
private boolean isTextFile(String filePath) throws Exception {
File f = new File(filePath);
if(!f.exists())
return false;
FileInputStream in = new FileInputStream(f);
int size = in.available();
if(size > 1000)
size = 1000;
byte[] data = new byte[size];
in.read(data);
in.close();
String s = new String(data, "ISO-8859-1");
String s2 = s.replaceAll(
"[a-zA-Z0-9ßöäü\\.\\*!\"§\\$\\%&/()=\\[email protected]~'#:,;\\"+
"+><\\|\\[\\]\\{\\}\\^°²³\\\\ \\n\\r\\t_\\-`´âêîô"+
"ÂÊÔÎáéíóàèìòÁÉÍÓÀÈÌÒ©‰¢£¥€±¿»«¼½¾™ª]", "");
// will delete all text signs
double d = (double)(s.length() - s2.length())/(double)(s.length());
// percentage of text signs in the text
return d > 0.95;
}
Ý tưởng thú vị, nhưng thay vì replaceAll, thứ không cần thiết tạo ra một chuỗi mới, tôi chỉ đơn giản sử dụng vòng lặp for để đếm văn bản so với các ký tự không phải văn bản. Đặt giới hạn ở 1000 ký tự có nghĩa là nó sẽ không được * quá * tốn kém anyway, nhưng nó vẫn là một chi phí vô ích – miniBill
tôi làm thế này. Một chút đơn giản hơn, nhưng đối với các ngôn ngữ dựa trên tiếng Latinh, nó sẽ hoạt động tốt, với điều chỉnh tỷ lệ.
/**
* Guess whether given file is binary. Just checks for anything under 0x09.
*/
public static boolean isBinaryFile(File f) throws FileNotFoundException, IOException {
FileInputStream in = new FileInputStream(f);
int size = in.available();
if(size > 1024) size = 1024;
byte[] data = new byte[size];
in.read(data);
in.close();
int ascii = 0;
int other = 0;
for(int i = 0; i < data.length; i++) {
byte b = data[i];
if(b < 0x09) return true;
if(b == 0x09 || b == 0x0A || b == 0x0C || b == 0x0D) ascii++;
else if(b >= 0x20 && b <= 0x7E) ascii++;
else other++;
}
if(other == 0) return false;
return 100 * other/(ascii + other) > 95;
}
Cảm ơn chức năng này. Một điều tôi gặp khó khăn trong việc tìm ra những gì đang xảy ra với giá trị trả về: 'return (ascii + other) * 100/other> 95;' , trừ khi tôi thiếu thứ gì đó, sẽ luôn trả về true: Chủ yếu, kích thước sẽ là '1024', như' data.length' và do đó '(ascii + other)'. Vì vậy, nếu '(ascii + khác) * 100 == 102400' thì' 102400/khác> 95' => '102400> 95 * other' =>' other <1078' Có nghĩa là cần phải lớn hơn 1078 (trong số 1024) "khác" cho điều này để trả về false, rõ ràng là không thể. Ý của bạn là gì ?: '(khác/size * 100> 95)' Hoặc tôi có thiếu gì đó không? – Inversus
Tôi nghĩ bạn nói đúng. Sửa mã. –
Mát mẻ. Ya, tôi đã kết thúc với điều đó. Cảm ơn lần nữa :) – Inversus
Sử dụng Java 7 tập tin lớp http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType(java.nio.file.Path)
boolean isBinaryFile(File f) throws IOException {
String type = Files.probeContentType(f.toPath());
if (type == null) {
//type couldn't be determined, assume binary
return true;
} else if (type.startsWith("text")) {
return false;
} else {
//type isn't text
return true;
}
}
- 1. Xác định loại tệp trong Windows
- 2. Làm cách nào để xác định tệp nhị phân và tệp văn bản bằng Python?
- 3. Java Generic Class - Xác định Loại
- 4. Xác định loại tệp bằng C#
- 5. Xác định phiên bản Linux từ java
- 6. Xác định loại được xác định
- 7. Lỗi loại tệp không xác định với tệp .pyx
- 8. Java: làm cách nào để xác định loại tệp ổ đĩa được đặt trên?
- 9. Java: Cách ghi tệp nhị phân?
- 10. Xác định số lượng dòng trong một tệp văn bản
- 11. xác định định dạng hệ thống tệp của một loại đĩa trong java như ntfs, fat16/32 hoặc ext
- 12. Tách và nối lại một tệp nhị phân trong java
- 13. cách truy cập loại được xác định trong một tệp .ml trong tệp .ml khác
- 14. Xác định loại nội dung không xác định bằng tệp Html5 api
- 15. javax.xml.ws.WebServiceException: Không xác định loại cổng Java Struts SOAP WSDL
- 16. Xác định kiểu truyền trong Java
- 17. Phân loại các bản ghi trong Java
- 18. Android: Cách mở một loại tệp không xác định
- 19. Xác định chuỗi không đổi trong Java?
- 20. Cách xác định loại tệp MIME theo nội dung?
- 21. svn diff: tệp được đánh dấu là loại nhị phân
- 22. Java không xác định?
- 23. Xác định loại biến trong Netbeans PHP
- 24. Xác định loại biến trong TCL
- 25. Emacs: Xác định hàm tải tệp mà bản thân hàm được xác định
- 26. Phân tích tệp văn bản trong Java
- 27. Cách xác định có thể chuyển nhượng loại giao diện trong tệp .aidl?
- 28. C# xác định loại chung
- 29. Số phiên bản Maven trong tệp java
- 30. linux + xác minh xem tệp có phải là văn bản hoặc nhị phân
Lừa câu hỏi - chúng tất cả các file nhị phân. – duffymo