1

I am trying to write many lines read from a file to a second file. I am able to loop through lines (sout can print all lines) of text but it's not possible to write all lines in the new file. It writes only the last line.

Any help:

 lines.forEach(line -> {
                // Append the line separator
                String lineToWrite = line; // + System.lineSeparator(); //


                // Write every line to the output file
                try {
                    //Files.write(output, lineToWrite.getBytes(StandardCharsets.UTF_8));
                    //Files.write(output, Collections.singleton(lineToWrite),StandardCharsets.UTF_8);

                    PrintWriter writer = new PrintWriter(outputdir, "UTF-8");
                    writer.println(lineToWrite);
                    System.out.println(lineToWrite);
                    writer.close();


                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("error lines linewrite:"+e);
                }
            });
5
  • You are opening wting an closing many times. Do you expect to append? Commented Aug 27, 2020 at 14:07
  • 3
    Move PrintWriter writer = new PrintWriter(outputdir, "UTF-8"); outside the loop, you are creating a new writer for each line. Commented Aug 27, 2020 at 14:07
  • You're writing over the same line each time. That's why it seems like it's only writing the last one Commented Aug 27, 2020 at 14:13
  • What's outputdir? Commented Aug 27, 2020 at 14:13
  • Yes pulling writer outside the loop is the solution. Thank you all, you are great Commented Aug 27, 2020 at 14:22

2 Answers 2

1

You're opening the file for reading, writing one line, and then closing it, for every line? That is incredibly inefficient.

Also, writing causes (checked) exceptions, and exceptions + lambdas don't work well.

.forEach here is silly; the problem with lambdas are that they are not exception transparent, not mutable local variable transparent, and not control flow transparent. These are bad things. The use of the lambda needs to have enough positives to outweigh these negatives, OR the lambda needs to be separated in context (at which point those 3 downsides turn into upsides). Neither is the case here, so don't use this old shoe to fasten than nail, use a hammer. Thus:

public static void main(String[] args) throws Exception {
    List<String> lines = ...;
    String file = "example.txt";

    try (PrintWriter out = new PrintWriter(file, "UTF-8")) {
        for (String line : lines) {
            out.println(line);
            System.out.println(line);
        }
    }
}

The above also fixes other errors in your code, such as not properly closing the resource, and deplorable exception management, by letting the system handler print the error, which does a better job generally. If somehow you can't, the 'best' "I don't know what to do with this" handler is not what you wrote, but this:

catch (IOException iCantHandleThis) {
    throw new RuntimeException("Uncaught", iCantHandleThis);
}

- but prefer throwing the exception onwards as is done in the example above.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the explanations. You are right. And pulling file.write out of the loop resolved the issue
0

I pulled File out of the loop and obviously this was my mistake.

           String outputdir = "C:\\merged\\Merged.txt";
        Path output = Paths.get(outputdir);
        Path directory = Paths.get("C:\\scan");
        Stream<Path> filesToProcess = Files.list(directory);

        // first delete previous merged and create a new on//
        File file = new File("C:\\merged\\Merged.txt");
        try {
            boolean result = Files.deleteIfExists(file.toPath());
        } catch (IOException e) {
            System.out.println("error deleteprev file:"+e);
            e.printStackTrace();
        }


    PrintWriter writer = new PrintWriter(outputdir, "UTF-8");
        // Iterate all files
        filesToProcess.forEach(path -> {
            // Get all lines of that file
            Stream<String> lines = null;
            try {
                lines = Files.lines(path);

            } catch (IOException e) {
                System.out.println("error lines path:"+e);
                e.printStackTrace();
            }


            // Iterate all lines
            lines.forEach(line -> {
                // Append the line separator
                String lineToWrite = line; // + System.lineSeparator(); Nese duhet  //


                // Write every line to the output file

                    //Files.write(output, lineToWrite.getBytes(StandardCharsets.UTF_8));
                    //Files.write(output, Collections.singleton(lineToWrite),StandardCharsets.UTF_8);
                    writer.println(lineToWrite);
                    System.out.println(lineToWrite);

            });
        });
    writer.close();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.