有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java代码优化,替换文件中的所有字符

我试过这样做:

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) {
            }
        }
    }

}

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


共 (2) 个答案

  1. # 1 楼答案

    第一个例子中的罪魁祸首是,如here所述,使用字符串连接来低效地构建oldtext。这将为每个串联分配一个新字符串。Java为构建字符串提供^{}

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

    StringBuilder中构建文本时,也可以进行替换。代码的另一个问题是shouldn't use ^{}要检查文件中是否还有一些内容,请检查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量是相同的——读取完整内容一次,写入结果一次

  2. # 2 楼答案

    第一个程序运行缓慢的主要原因可能是它正在以增量方式构建字符串oldtext。问题是,每次你给它添加另一行时,它可能需要复制一份。由于每次复制所需的时间大致与被复制字符串的长度成正比,因此执行时间将按输入文件大小的平方进行缩放

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

    如果是这样的话,解决这个问题的一个简单方法就是Java的^{} class,它正是为了完成这个任务:以增量的方式构建一个大字符串