从csv文件中删除重复的行而不写入新文件

时间:2015-01-10 11:10:34

标签: java csv hashset

这是我现在的代码:

File file1 = new File("file1.csv");
File file2 = new File("file2.csv");
HashSet<String> f1 = new HashSet<>(FileUtils.readLines(file1));
HashSet<String> f2 = new HashSet<>(FileUtils.readLines(file2));
f2.removeAll(f1);

使用removeAll()我从file1中删除file2中的所有重复项,但现在我想避免创建新的csv文件来优化该过程。只想从file2中删除重复的行。

这可能或我必须创建一个新文件吗?

2 个答案:

答案 0 :(得分:1)

  

现在我想避免创建一个新的csv文件来优化该过程。

嗯,当然,你可以这样做......如果你不介意丢失文件!

不要这样做

因为你使用Java 7,use java.nio.file。这是一个例子:

final Path file1 = Paths.get("file1.csv");
final Path file2 = Paths.get("file2.csv");
final Path tmpfile = file2.resolveSibling("file2.csv.new");

final Set<String> file1Lines 
    = new HashSet<>(Files.readAllLines(file1, StandardCharsets.UTF_8));

try (
    final BufferedReader reader = Files.newBufferedReader(file2,
        StandardCharsets.UTF_8);
    final BufferedWriter writer = Files.newBufferedWriter(tmpfile,
        StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
) {
    String line;
    while ((line = reader.readLine()) != null)
        if (!file1Lines.contains(line)) {
            writer.write(line);
            writer.newLine();
        }
}

try {
    Files.move(tmpfile, file2, StandardCopyOption.REPLACE_EXISTING,
        StandardCopyOption.ATOMIC_MOVE);
} catch (AtomicMoveNotSupportedException ignored) {
    Files.move(tmpfile, file2, StandardCopyOption.REPLACE_EXISTING);
}

如果您使用Java 8,则可以使用此try-with-resources块:

try (
    final Stream<String> stream = Files.lines(file2, StandardCharsets.UTF_8);
    final BufferedWriter writer = Files.newBufferedWriter(tmpfile,
        StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
) {
    stream.filter(line -> !file1Lines.contains(line))
        .forEach(line -> { writer.write(line); writer.newLine(); });
}

答案 1 :(得分:0)

我用这行代码解决了:

FileUtils.writeLines(file2, f2);

这是一个覆盖,可以很好地解决中小型文件, 但对于非常大的数据集,我真的不知道。