0

我目前正在研究 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]
4

2 回答 2

0

你有反对使用扫描仪类的东西吗?

使用 Scanner,您可以逐行读取文件,然后在 = 处拆分结果字符串。如果在一行上拆分失败(结果 String[] 的长度为 1),那么您知道该行的格式不正确,如果该行的长度为 1 并且与 "\n" 匹配,则它是一个空行,如果扫描仪.hasNextLine() == 假,EOF。

于 2012-12-29T23:29:32.343 回答
0

lastLine""如果文件中的最后一行只不过是\n(或),则将为空(\r\n)。readLine去除行尾字符。

如果不为空,则仅在写入文件时lastLine添加空格所以……这不是问题。

然而:

  1. 您没有考虑最后一行可能没有行尾字符。
  2. 带有“额外”行的源文件......没有行尾字符,但有一个空格。

这是唯一会生成您显示的输出的东西。当您添加两个换行符时,您将在缺少它的额外行中添加一个,然后创建第二个“空白”行;没有行尾字符。

这也是为什么在以结尾的文件中添加两个换行符key=java只会产生一个“空白行”的原因。

您需要在阅读文件时考虑到这一点。也许是一个正则表达式?

老实说,每次编写整个文件更容易。这就是内置Properties对象在 java 中的作用。

于 2012-12-30T00:10:32.907 回答