Как узнать, какой разделитель строк BufferedReader#readLine () используется для разделения строки?

Я читаю файл через BufferedReader

String filename = ...
br = new BufferedReader( new FileInputStream(filename));
while (true) {
   String s = br.readLine();
   if (s == null) break;
   ...
}

Мне нужно знать, разделены ли строки на 'n ' или 'rn' есть способ узнать ?

Я не хочу открывать FileInputStream, чтобы сканировать его изначально. В идеале я хотел бы спросить BufferedReader, так как он должен знать.

Я рад переопределить BufferedReader, чтобы взломать его, но я действительно не хочу открывать filestream дважды.

спасибо,

Примечание: текущий разделитель строк (возвращается системой.метод getproperty("линии.разделитель")) не может использоваться, так как файл мог быть написан другим приложением в другой операционной системе.

8 ответов


после прочтения java docs (Я признаюсь, что я питонист), похоже, что нет чистого способа определить кодировку конца строки, используемую в определенном файле.

лучшее, что я могу рекомендовать, это использовать BufferedReader.read() и перебрать каждый символ в файле. Что-то вроде этого:--5-->

String filename = ...
br = new BufferedReader( new FileInputStream(filename));
while (true) {
   String l = "";
   Char c = " ";
   while (true){
        c = br.read();
        if not c == "\n"{
            // do stuff, not sure what you want with the endl encoding
            // break to return endl-free line
        }
        if not c == "\r"{
            // do stuff, not sure what you want with the endl encoding
            // break to return endl-free line
            Char ctwo = ' '
            ctwo = br.read();
            if ctwo == "\n"{
                // do extra stuff since you know that you've got a \r\n
            }
        }
        else{
            l = l + c;
        }
   if (l == null) break;
   ...
   l = "";
}

чтобы быть в фазе с классом BufferedReader, вы можете использовать следующий метод, который обрабатывает \n, \r,\n \r и\r \ n разделители конечных строк:

public static String retrieveLineSeparator(File file) throws IOException {
    char current;
    String lineSeparator = "";
    FileInputStream fis = new FileInputStream(file);
    try {
        while (fis.available() > 0) {
            current = (char) fis.read();
            if ((current == '\n') || (current == '\r')) {
                lineSeparator += current;
                if (fis.available() > 0) {
                    char next = (char) fis.read();
                    if ((next != current)
                            && ((next == '\r') || (next == '\n'))) {
                        lineSeparator += next;
                    }
                }
                return lineSeparator;
            }
        }
    } finally {
        if (fis!=null) {
            fis.close();
        }
    }
    return null;
}

BufferedReader не принимаются FileInputStreams

нет, вы не можете узнать символ Терминатора строки, который использовался в файле, считываемом BufferedReader. Эта информация теряется при чтении файла.

Unfornunately все ответы неверны.

Edit: и да, вы всегда можете расширить BufferedReader, чтобы включить дополнительную функциональность, которую вы хотите.


BufferedReader.readLine() не предоставляет никаких средств для определения того, что такое разрыв линии. Если вам нужно знать, вам нужно будет прочитать символы в себе и найти разрывы строк самостоятельно.

вас может заинтересовать внутренний LineBuffer класс гуавы (а также общественности LineReader класс, в котором он используется). LineBuffer обеспечивает метод обратного вызова void handleLine(String line, String end) здесь end - Это символы разрыва строки. Возможно, вы могли бы основать что-то, чтобы делай, что хочешь. API может выглядеть как public Line readLine() здесь Line - это объект, который содержит как текстовые строки и конца строки.


ответ был бы вы не можете узнать, что было окончание строки.

Я ищу, что может вызвать окончание строки в том же funcion. После просмотра исходного кода BufferedReader я могу saz, что BufferedReader.с readline строка заканчивается на '\р' или '\n' и пропускает leftower значение '\R' или '\П'. Жестко, не заботясь о настройках.


Если Вы читаете этот файл в текстовый компонент Swing, вы можете просто использовать JTextComponent.читать.(..) метод загрузки файла в документ. Тогда вы можете использовать:

textComponent.getDocument().getProperty( DefaultEditorKit.EndOfLineStringProperty );

чтобы получить фактическую строку EOL, которая использовалась в файле.


Не уверен, что полезно, но иногда мне нужно узнать разделитель строки после того, как я прочитал файл уже далеко вниз по дороге.

в данном случае я использую этот код:

/**
* <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$
    }
}

Если вы используете groovy, вы можете просто сделать:

def lineSeparator = new File('path/to/file').text.contains('\r\n') ? '\r\n' : '\n'