Question

this code is supposed to open a text file, skip the first line, copy the remaining lines to temp variable, clear the file and then rewrite the temp variable into the file.

I am suspecting that this piece of code is generating memory leakage, although I am clearing and closing all objects. Am I missing something here?

This piece of code is called more than 30 times a second.

            Scanner scanner_live = new Scanner(file_live);
            ArrayList<String> coll = new ArrayList<String>();
            scanner_live.nextLine();
            while (scanner_live.hasNextLine()) 
                                {
                String line = scanner_live.nextLine();
                coll.add(line);}
            scanner_live.close();

            PrintWriter writer_del = new PrintWriter(file_live);
            writer_del.print("");
            writer_del.close();

            for (String line : coll) {
            FileWriter writer = new FileWriter(file_live.getAbsoluteFile(),true);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.append(line);
            bufferedWriter.newLine();
            bufferedWriter.close(); 
            writer.close();
                                    }
            coll.clear();
Était-ce utile?

La solution

I suggest you avoid storing all the lines. Instead you can copy the data as you read it. You don't actually need to parse each line after the first, you just need to copy the rest of the data.

try(BufferedReader in = new BufferedReader(new FileReader(file_live);
   BufferedWriter out = new BufferedWriter(new FileWriter(file_live+".tmp"))) {
   // skip the first line
   in.readLine();
   char[] buffer = new char[8*1024];
   for(int len; (len = in.read(buffer)) > 0;)
       out.write(buffer, 0, len);
}
new File(file_live).delete();
new File(file_live+".tmp").renameTo(new File(file_live));

BTW: consuming one line at a time this way is very expensive, esp if the file is large. If you can I would suggest not re-writing the file at all and instead record separately which line you were up to.

Autres conseils

Your algorithm but more correct.

    File file = ...
    List<String> lines = new ArrayList<>();
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        // skip first
        String line = reader.readLine();
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    try (PrintWriter writer = new PrintWriter(new FileWriter(file))){
        for (String line : lines) {
            writer.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

Also I don't see memory leak if the file is small. But if the file is big it's just because you keep all lines in memory. And JVM memory != all ram on your computer. So JVM could exceed the limit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top