Подтвердить что ты не робот

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

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

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

Мне нужно знать, разделены ли строки '\n' или '\ r\n' есть способ, который я могу узнать?

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

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

Спасибо,

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

4b9b3361

Ответ 1

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

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

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 = "";
}

Ответ 2

Чтобы быть в фазе с классом 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;
}

Ответ 3

BufferedReader не принимает FileInputStreams

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

Несомненно, все приведенные ниже ответы неверны.

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

Ответ 4

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

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

Ответ 5

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

Я ищу, что может привести к завершению строки в той же функции. Посмотрев исходный код BufferedReader, я могу сказать, что BufferedReader.readLine заканчивает строку на '\ r' или '\n' и пропускает leftower '\ r' или '\n'. Hardcoded, не заботится о настройках.

Ответ 6

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

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

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

Ответ 7

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

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

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

Ответ 8

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

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