Как узнать, какой разделитель строк 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" )) не может использоваться, поскольку файл может быть написан другим приложением в другой операционной системе.
Ответы
Ответ 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'