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

Java代码优化,替换文件中的所有字符,java,optimization,Java,Optimization,我试过这样做: 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(nomCompletFichi

我试过这样做:

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();
        }
    }

}
    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();
但是,执行上述代码比创建两个不同的文件需要更多的时间:

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

}

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

第一个示例中的主要罪魁祸首是,如前所述,您正在使用字符串连接低效地构建
oldtext
。这将为每个连接分配一个新字符串。Java为您提供了构建字符串的功能:

    StringBuilder builder = new StringBuilder;
    while(reader.ready()){
        builder.append(reader.readLine());
        builder.append("\n");
    }
    String oldtext = builder.toString();
StringBuilder
中构建文本时,也可以进行替换。代码的另一个问题是,您需要检查文件中是否还有一些内容-检查
readLine()
的结果。最后,关闭流应该在
Finally
或try with resources块中。结果可能如下所示:

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();
        }
    }

}
    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量是相同的—读取完整内容一次,写入结果一次。

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

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


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

在第二个示例中,为什么不直接写入目标文件?你为什么需要临时文件?“执行第二个代码而不创建临时文件”:你的意思是使用临时文件而不创建临时文件?@Henry:我的意思是在不使用临时文件的情况下替换文件中的所有字符。直接在文件中进行更改。@Mifeet:当我直接在目标文件中写入时,它会使所有内容加倍。我的意思是它读了一行,替换这些值,然后在不删除原始行的情况下将其写入文件。注意:将
append
拆分为两个调用,以避免在进行连接时为每行创建新字符串。@AndyTurner:您能举一个示例说明您的意思吗?@Mifeet几点1)不要像使用尝试使用资源:如果在创建
BufferedReader
时出现异常,您的
文件读取器将不会关闭:创建一个单独的资源变量;2) 
while((line=reader.readLine())!=null){
的重复性稍低一些。