2010-10-27 10 views
6

Używam Java SE 6.Czy istnieje standardowy interfejs API do sprawdzania separatorów linii w języku Java?

Mój program czyta kilka rodzajów plików od DOS-a do Uniksa i ASCII do Unicode, i muszę się upewnić, że separatory linii dla pliku wyjściowego pasują do plików wejściowych.

Sposób, w jaki to robię, to odczytanie linii próbnej za pomocą funkcji BufferedReader read() w celu wyszukania pierwszego separatora linii i zapisania tego separatora linii w łańcuchu. W ten sposób można go użyć później, gdy potrzebuję nowej linii.

Mam sprawdzony klasę skanera i zauważył, że ewentualne separatory linii może zawierać następujące elementy:

\r\n 
\r 
\n 
\u2028 
\u2029 
\u0085 

Czy istnieje funkcja biblioteki w celu sprawdzenia tych znaków? Albo jeszcze lepiej, czy istnieje już funkcja biblioteczna do sprawdzenia, jak wygląda separator linii wejściowych?

Czy są na to inne sposoby?

EDYTOWANIE: Jeśli to możliwe, chciałbym użyć standardowego interfejsu API języka Java zamiast bibliotek zewnętrznych, ale wszystkie sugestie są mile widziane.

EDYTOWANIE: Tylko w celu wyjaśnienia.
1) Pliki wejściowe nie zależą od miejsca, w którym uruchomiony jest ten program. Na przykład, jeśli uruchamiam ten program w Dos, nadal mogę uzyskać plik wejściowy systemu Unix.
2) Moim celem nie jest odczytanie linii rozdzielonych separatorami linii - to proste. Naprawdę potrzebuję napisać plik wyjściowy z tymi samymi separatorami liniowymi co plik wejściowy. Na przykład, jeśli uruchamiam ten program w programie Dos, a otrzymuję plik wejściowy systemu Unix, chcę mieć możliwość napisania pliku wyjściowego za pomocą separatorów linii Unix. Właśnie dlatego pytam, czy istnieje standardowy interfejs API do wykrywania separatorów linii na podstawie plików wejściowych, a nie systemu operacyjnego.

Dzięki.

Odpowiedz

3

Poprzednie trzy odpowiedzi w rzeczywistości nie odpowiadają na pytanie. OP chce określić z danego pliku: jaki jest separator linii używany w tym pliku?

Na to pytanie nie można jednoznacznie odpowiedzieć na dany plik, ponieważ plik może mieć kilka zakończeń linii. To może wydawać się wymyślone, ale jest to możliwe.

Najlepszym podejściem do mnie wydaje się samodzielne sparsowanie pliku wejściowego, liczenie wystąpień możliwych sekwencji kończących znaki i wybór tego, który pojawia się najczęściej jako separator linii tego pliku.

Nie natknąłem się na bibliotekę, która mogłaby zaimplementować tę funkcję.

+1

"może wydawać się wymyślonym" - na przykład nie jest to przypadek skrajny - pliki logów unix java z odpowiedziami na komputer mainframe lub skopiowane teksty z różnych źródeł. Nigdy bym nie założył, że plik ma tylko jeden typ separatora linii. –

1

BufferedReader i readLine() automatycznie obsługują przynajmniej trzy pierwsze warianty znaczników końca linii.

+0

Myślę, że to jest lepsze rozwiązanie, nie trzeba hardcode tych \ n i \ r rzeczy. – user1686407

0

Szukałem bardzo długiego czasu na api do tego. Ale nie mogłem znaleźć.

Używam podobnego podejścia do czytania dla pierwszego ogranicznika linii z wyrażeniem regularnym.

Musiałem poświęcić trochę czasu na dobranie odpowiedniego Regexa do pracy i żałowałem, że ta odpowiedź nie zawiera kodu. Więc napisałem coś sam:

/** 
* <h1> Identify which line delimiter is used in a string </h1> 
* 
* This is useful when processing files that were created on different operating systems. 
* 
* @param str - the string with the mystery line delimiter. 
* @return the line delimiter for windows, {@code \r\n}, <br> 
*   unix/linux {@code \n} or legacy mac {@code \r} <br> 
*   if none can be identified, it falls back to unix {@code \n} 
*/ 
public static String identifyLineDelimiter(String str) { 
    if (str.matches("(?s).*(\\r\\n).*")) {  //Windows //$NON-NLS-1$ 
     return "\r\n"; //$NON-NLS-1$ 
    } else if (str.matches("(?s).*(\\n).*")) { //Unix/Linux //$NON-NLS-1$ 
     return "\n"; //$NON-NLS-1$ 
    } else if (str.matches("(?s).*(\\r).*")) { //Legacy mac os 9. Newer OS X use \n //$NON-NLS-1$ 
     return "\r"; //$NON-NLS-1$ 
    } else { 
     return "\n"; //fallback onto '\n' if nothing matches. //$NON-NLS-1$ 
    } 
} 
Powiązane problemy