2010-12-14 12 views
6

Wszystko,java.net.URLConnection.guessContentTypeFromStream i text/plain

Próbuję zidentyfikować pliki tekstowe z zakończeń linii komputerów Mac, a wewnątrz InputStream, cicho konwertować je do zakończeń linii Windows lub Linux (ważne część to naprawdę postać LF). W szczególności pracuję z kilkoma interfejsami API, które pobierają InputStreams i są trudne do znalezienia \ n jako nowe linie.

Czasami dostaję pliki binarne. Oczywiście plik, który nie jest tekstem, nie powinien mieć tej zamiany, ponieważ wartość, która odpowiada \ r, oczywiście nie może po cichu być śledzona przez \ n bez poważnych problemów.

Próbuję użyć java.net.URLConnection.guessContentTypeFromStream i wykonuję tylko konwersje końcowe, jeśli typem jest tekst/zwykły. Niestety, "text/plain" nie wydaje się być w swojej gamie wartości zwracanych; wszystko, co dostaję, to null dla moich płaskich plików tekstowych i prawdopodobnie nie jest bezpiecznie założyć, że wszystkie niemożliwe do zidentyfikowania pliki można zmodyfikować.

Jaką lepszą bibliotekę (najlepiej w publicznym repozytorium Maven i open-source) mogę użyć, aby to zrobić? Ewentualnie, jak mogę sprawić, aby guessContentTypeFromStream działał dla mnie? Wiem, że opisuję z natury niebezpieczną aplikację i żadne rozwiązanie nie może być idealne, ale czy powinienem po prostu traktować "zerowy" jako "tekst/zwykły" i po prostu muszę napisać sam kod, żeby szukać dowodów, że to nie jest "t?

+2

+1 dla "gamy". – skaffman

Odpowiedz

2

Wydaje mi się, że to, o co prosisz, polega na ustaleniu, czy plik jest tekstowy czy nie. Biorąc pod uwagę, że istnieje rozwiązanie here że wydaje się słuszne:

prawda, mówi o UNIX bash i Perl ale idea jest ta sama:

Jeśli nie sprawdzać każdy bajt pliku , nie dostaniesz tego 100%. I jest ogromna wydajność hit z inspekcji każdego bajtu. Ale po kilku eksperymentach zdecydowałem się na algorytm, który działa dla mnie. I zbadaj pierwszy wiersz i zadeklaruj, że plik ma być binarny, jeśli napotkam nawet jeden nietekstowy bajt. . Wygląda na to, że trochę luzu, wiem, ale wydaje mi się, że mogę uciec z nim .

EDIT # 1:
Rozszerzenie na tego typu rozwiązania, wydaje się rozsądnym podejściem byłoby zapewnienie plik nie zawiera znaki spoza ASCII (chyba, że ​​masz do czynienia z plikami, które nie są -English ... to kolejne rozwiązanie). Można to zrobić poprzez sprawdzenie, czy zawartość pliku jako łańcuch nie pasuje to:

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

EDIT # 2
Możesz spróbować tego jako regex lub coś podobnego do niego. Chociaż muszę przyznać, że najprawdopodobniej użyje jakiegoś udoskonalenia.

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

Miałem zamiar użyć podejścia podobnego do tego, gdyby wszystko inne zawiodło, z wyjątkiem znacznie mniej wdzięku niż regex. (Inspekcja bajt po bajcie, oto nadchodzę!) Zamiast linii, prawdopodobnie użyję stałej liczby znaków, głównie aby nie ryzykować przekroczenia mojej pozycji znaku (...) na moim buforze podręcznym.To jednak wywołująca ból klasa postaci; jaka jest forma Java dla tych z nas, którzy nie mówią w Perlu? –

+1

Zastanawiam się, jak to działa na plikach tekstowych z BOM Unicode. – BalusC

+0

Określone wyrazy regularne były trochę zbyt tolerancyjne, ale usunięcie ich z początku i końca. * (Chcemy, aby postacie spoza klasy dyskwalifikowały!) Zrobiły to. Dzięki. –

Powiązane problemy