Как определить, есть ли в конце файла пустая строка с BufferedReader?
В настоящее время я работаю над библиотекой синтаксического анализа файла INI, но у меня только одна проблема, когда я пытаюсь создать категорию с помощью метода, который я создал.
Содержимое INI-файла, которое я использую, выглядит следующим образом:
; Format example
[Category]
key=value
; Just a test to see if setting the same key in a different category
; would mess up the reading, which it didn't.
[Language]
cplusplus=C++
key=java
(No extra line; file ends at "key=java")
Когда я создаю категорию с помощью метода, он попытается добавить достаточно новых строк, чтобы у каждой категории была 1 пустая строка между концом предыдущей категории и той, которую вы создаете. Если я сохраню файл как есть, то есть без лишней пустой строки в конце файла, он будет работать нормально. Но если я изменю содержимое файла на это:
; Format example
[Category]
key=value
; Just a test to see if setting the same key in a different category
; would mess up the reading, which it didn't.
[Language]
cplusplus=C++
key=java
(File has extra line; file ends after the "key=java" line)
Он создает две пустые строки между двумя категориями... Но я не понимаю почему, так как я проверяю, если последняя строка уже пуста. Я кое-что новое в Java, поэтому, пожалуйста, скажите мне, если я делаю очевидную ошибку.
/**
* Adds a category to the current INI file.
*
* @param category The category to be added to the file
*/
public void addCategory(String category) {
if (iniFile == null) return;
// Checking to see if the file already contains the desired category
boolean containsCategory = false;
String lastLine = "";
String string;
try (BufferedReader in = new BufferedReader(new FileReader(iniFile))) {
while ( (string = in.readLine()) != null) {
// Line is a comment or is empty, ignoring
if (!string.equals(""))
if (string.charAt(0) == ';' || string.charAt(0) == '#')
continue;
lastLine = string;
// Line is a category, checking if it is the category that is
// about to be created
if (!string.equals("") && string.charAt(0) == '[') {
String thisCategory = string.substring(1, string.length() - 1);
if (thisCategory.equals(category))
containsCategory = true;
}
}
} catch (IOException e) {}
// The file does not contain the category, so appeanding it to the end
// of the file.
if (!containsCategory) {
try (BufferedWriter out = new BufferedWriter(new FileWriter(iniFile, true))) {
if (!lastLine.equals("")) {
System.out.println("Adding extra whitespace");
out.newLine();
out.newLine();
}
out.write('[' + category + ']');
out.close();
} catch (IOException e) {}
}
}
Если вы хотите увидеть полный источник файла, вот ссылка на GitHub, на который он загружен.
РЕДАКТИРОВАТЬ:
Я просто подумал, что должен предоставить то, как файлы выглядят после того, как я addCategory(String)
метод.
После того как я позвоню addCategory("Example")
в первом файле (без лишней пустой строки):
; Format example
[Category]
key=value
; Just a test to see if setting the same key in a different category
; would mess up the reading, which it didn't.
[Language]
cplusplus=C++
key=java
[Example]
После того как я позвоню addCategory("Example")
во втором файле (с дополнительной пустой строкой в конце файла):
; Format example
[Category]
key=value
; Just a test to see if setting the same key in a different category
; would mess up the reading, which it didn't.
[Language]
cplusplus=C++
key=java
[Example]
2 ответа
lastLine
будет пустым (""
) если последняя строка в файле не более чем \n
(или же \r\n
). readLine
удаляет символы конца строки.
Вы добавляете пробелы только при записи файла, если lastLine
не пусто Так что... это не проблема.
Тем не мение:
- Вы не учитываете последнюю строку, возможно, не имея символа конца строки.
- Ваш исходный файл с "дополнительной" строкой... не имеет символа (ов) конца строки, но содержит пробел.
Это единственное, что будет генерировать вывод, который вы показываете. Когда вы добавляете две строки новой строки, вы добавляете одну к дополнительной строке, в которой она отсутствует, а затем создаете вторую "пустую" строку; там не было символов конца строки.
Это также, почему добавление двух новых строк в файл, который заканчивается key=java
производит только одну "пустую строку".
Вы должны учитывать это при чтении файла. Регулярное выражение возможно?
Если честно, проще каждый раз писать весь файл. Это то, что встроено в Properties
Объект делает в Java.
Есть ли у вас что-то против использования класса сканера?
С помощью сканера вы можете читать файл построчно, а затем разбивать полученную строку на =. Если разделение завершается неудачно в строке (результирующая строка [] имеет длину 1), то вы знаете, что строка имеет неправильный формат, если эта строка имеет длину 1 и соответствует "\n", то это пустая строка, если scanner.hasNextLine() == false, EOF.