Guava的`Files#write`不写最后一个空行?

时间:2014-09-19 23:26:21

标签: java file-io guava

我有一个简单的方法,它读取文件,根据条件修改一些行,然后将修改后的字符串写回同一个文件。大纲如下:

import com.google.common.base.Joiner;
import com.google.common.io.Files;

import static java.nio.charset.Charset.defaultCharset;

static final DIR = ;
String enforceVerbTag(String inputfilename) {
    String predictedTags = Files.toString(new File(DIR, inputfilename),
                                          defaultCharset());
    String[] lines = predictedTags.split("\\r?\\n");
    List<String> modifiedLines = new ArrayList<>();
    for (String line : lines) {
        String[] fields = line.split("\\t");
        if (mycondition)
            fields[1] = "VB";
        String modifiedLine = Joiner.on('\t').join(fields);
        modifiedLines.add(modifiedLine);
    }
    modifiedLines.add("");
    Files.write(Joiner.on('\n').join(modifiedLines),
                new File(DIR, inputfilename),
                defaultCharset());
}

输入文件的最后一行是空的,我希望输出文件保留该行。但是,尽管modifiedLines.add("")后加入\n,但输出文件没有最后一个空行。据我所知,Guava的Files#write没有做任何修剪,为什么会这样呢?

我知道还有很多其他方法可以写出最后一个空行。但我想知道这个方法出了什么问题。

2 个答案:

答案 0 :(得分:2)

这很简单:joiner加入,你得到一个字符串而没有终止'\n'

first \n
second \n
third (no \n)

然后你添加一个空字符串,它只是使最后一行终止:

first \n
second \n
third \n
(nothing) (no \n)

您必须添加另一个""才能获得空行。

first \n
second \n
third \n
(nothing) \n
(nothing) (no \n)

您可以使用附加换行符而不是加入者的函数,但这会更长(至少使用Java&lt; 8)并且由于无关的字符串创建而变慢。

答案 1 :(得分:0)

对不起,一切都适合我。这些测试通过了JDK7和Guava 12.0.1

@RunWith(JUnit4.class)
public class GuavaTests {
    @Test
    public void testJoiner()  {
        assertEquals("a\nb", Joiner.on('\n').join(ImmutableList.of("a", "b")));
        assertEquals("a\nb\n", Joiner.on('\n').join(ImmutableList.of("a", "b", "")));
    }

    public void testFilesWrite() throws IOException {
        File f = new File("tests.txt");
        final String content="a\nb\n";
        Files.write(content, f, Charset.defaultCharset());
        assertEquals(content.length(), f.length());
    }
}

文本文件包含3行:

a
b
(empty)