【问题标题】:Java code optimization, replacing all chars in a fileJava代码优化,替换文件中的所有字符
【发布时间】:2016-08-23 04:00:08
【问题描述】:

我试过这样做:

import java.io.*;

public class ConvertChar {
    public static void main(String args[]) {
        Long now = System.nanoTime();
        String nomCompletFichier = "C:\\Users\\aahamed\\Desktop\\test\\test.xml";
        Convert(nomCompletFichier);
        Long inter = System.nanoTime() - now;
        System.out.println(inter);
    }

    public static void Convert(String nomCompletFichier) {
        FileWriter writer = null;
        BufferedReader reader = null;
        try {
            File file = new File(nomCompletFichier);
            reader = new BufferedReader(new FileReader(file));

            String oldtext = "";
            while (reader.ready()) {
                oldtext += reader.readLine() + "\n";
            }
            reader.close();
            // replace a word in a file
            // String newtext = oldtext.replaceAll("drink", "Love");

            // To replace a line in a file
            String newtext = oldtext.replaceAll("&(?!amp;)", "&");

            writer = new FileWriter(file);
            writer.write(newtext);
            writer.close();

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

}

但是,上面的代码比创建两个不同的文件需要更多的时间来执行:

import java.io.*;

public class ConvertChar {
    public static void main(String args[]) {
        Long now = System.nanoTime();
        String nomCompletFichier = "C:\\Users\\aahamed\\Desktop\\test\\test.xml";
        Convert(nomCompletFichier);
        Long inter = System.nanoTime() - now;
        System.out.println(inter);
    }

    private static void Convert(String nomCompletFichier) {

        BufferedReader br = null;
        BufferedWriter bw = null;

        try {
            File file = new File(nomCompletFichier);
            File tempFile = File.createTempFile("buffer", ".tmp");

            bw = new BufferedWriter(new FileWriter(tempFile, true));
            br = new BufferedReader(new FileReader(file));

            while (br.ready()) {
                bw.write(br.readLine().replaceAll("&(?!amp;)", "&") + "\n");
            }

            bw.close();
            br.close();

            file.delete();
            tempFile.renameTo(file);

        } catch (IOException e) {
            // writeLog("Erreur lors de la conversion des caractères : " + e.getMessage(), 0);
        } finally {
            try {
                bw.close();
            } catch (Exception ignore) {
            }
            try {
                br.close();
            } catch (Exception ignore) {
            }
        }
    }

}

有没有办法在不创建临时文件并减少执行时间的情况下执行第二个代码?我正在做代码优化。

【问题讨论】:

  • 第二个例子,为什么不直接写入目标文件呢?为什么需要临时文件?
  • “在不创建临时文件的情况下执行第二个代码”:您的意思是使用临时文件而不创建临时文件?
  • @Henry:我的意思是在不使用临时文件的情况下替换文件中的所有字符。直接在文件中进行更改。
  • @Mifeet:当我直接在目标文件中写入时,一切都会翻倍。我的意思是它读取一行,替换值,然后将其写入文件而不删除原始行。

标签: java optimization


【解决方案1】:

您的第一个示例中的主要罪魁祸首是您使用字符串连接效率低下地构建oldtext,正如here 所解释的那样。这为每个连接分配一个新字符串。 Java 为您提供StringBuilder 用于构建字符串:

    StringBuilder builder = new StringBuilder;
    while(reader.ready()){
        builder.append(reader.readLine());
        builder.append("\n");
    }
    String oldtext = builder.toString();

您也可以在 StringBuilder 中构建文本时进行替换。您的代码的另一个问题是您 shouldn't use ready() 检查文件中是否还有一些内容 - 检查 readLine() 的结果。最后,关闭流应该在 finally 或 try-with-resources 块中。结果可能如下所示:

    StringBuilder builder = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        String line = reader.readLine();
        while (line != null) {
            builder.append(line.replaceAll("&(?!amp;)", "&"));
            builder.append('\n');
            line = reader.readLine();
        }
    }
    String newText = builder.toString();

不过,写入临时文件也是一个很好的解决方案。处理最慢的 I/O 量在两种情况下是相同的 - 一次读取完整内容,一次写入结果。

【讨论】:

  • 注意:将append拆分为2个调用,以避免在进行连接时为每一行创建一个新字符串。
  • @AndyTurner:你能举例说明你的意思吗?
  • @Mifeet 几点 1) 不要像 try-with-resources 那样创建内联资源:如果在创建 @987654334 时出现异常,您的 FileReader 将不会关闭@:创建一个单独的资源变量; 2) while ((line = reader.readLine()) != null) { 的重复性稍差。
【解决方案2】:

您的第一个程序运行缓慢的主要原因可能是它正在逐步构建字符串oldtext。问题在于,每次您向其中添加另一行时,都可能需要对其进行复制。由于每次复制所花费的时间与被复制字符串的长度大致成正比,因此您的执行时间将像输入文件大小的平方一样缩放。

您可以通过尝试使用不同长度的文件并查看运行时如何取决于文件大小来检查这是否是您的问题。

如果是这样,解决此问题的一种简单方法是 Java 的 StringBuilder class,它的目的正是为了完成这项任务:逐步构建大字符串。

【讨论】:

    猜你喜欢
    • 2021-07-14
    • 2018-06-06
    • 2017-12-09
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2013-12-31
    相关资源
    最近更新 更多