2

我正在尝试用 Java 编写一个删除文件第一行的方法。

第一个想法(被拒绝,因为调用 .exec 不是一个好习惯)

public void removeHeader(String fileName) throws IOException, InterruptedException {
    if (StringUtils.isBlank(fileName)) {
        throw new IllegalArgumentException("fileName was empty");
    }

    Process p = Runtime.getRuntime().exec("sed -i 1d " + fileName);

    if (p.waitFor() != 0) {
        throw new IOException("Failed to remove the header from " + fileName);
    }
}

第二个想法(在 CR 中被拒绝,因为遍历每一行并将其写入新文件很慢且不时尚)。

public void removeHeader(String fileName) throws IOException, InterruptedException {
    if (StringUtils.isBlank(fileName)) {
        throw new IllegalArgumentException("fileName was empty");
    }

    File inFile = new File(fileName);
    File tempFile = new File(inFile.getAbsolutePath() + ".tmp");

    BufferedReader br = null;
    PrintWriter pw = null;

    try {
        br = new BufferedReader(new FileReader(fileName));
        pw = new PrintWriter(new FileWriter(tempFile));

        String line = null;
        boolean first = true;
        while ((line = br.readLine()) != null) {
            if (!first) {
                pw.println(line);
                pw.flush();
            }

            first = false;
        } 
    }
    finally {
        pw.close();
        br.close();
    }

    if (inFile.exists() && tempFile.exists()) {
        inFile.delete();
        tempFile.renameTo(inFile);
    }
}

无论换行格式如何,我都希望我的解决方案能够正常工作并且易于阅读。是否有满足所有这些需求的解决方案?

4

3 回答 3

9

我不是 Java 人,但没有办法(Java 或其他方式)在不重写剩余内容的情况下从文件开头删除内容(除非您可以访问底层文件系统来移动文件的起始块,即会破坏您的“易于阅读”的要求)。

我在这里感觉到过早的优化,除非文件真的很大。

于 2012-04-26T02:05:22.610 回答
2

你必须阅读和复制任何你想保留的东西(甚至sed正在这样做)。

第二个版本可以通过简单地在循环之前通过单独读取跳过第一行来稍微改进,然后您不必在每次循环时检查您是否在第一行。

第二个也可以通过编写一个跳过第一行的FilterReader来获得一些优雅。为此目的可能不值得麻烦,但学习实现这样的过滤器是值得的。

于 2012-04-26T02:14:56.893 回答
0

您的代码可以像这样缩短(需要 Java7):

  • 打开一个FileInputStream
  • 读到第一个换行符
  • 使用Files.copy复制其余部分

但除此之外,正如其他人所说,没有简单的方法可以删除文件的第一部分。

于 2012-09-11T04:56:06.750 回答