1

I am trying to make a change log and so I need a single line between some sentences. All I have is this but it doesn't seem to work. Can anyone help me please?

@Test
public void addLine() {
    File temp;
    try {
        temp = File.createTempFile("app.log", ".tmp", new File("."));
        File appLog = new File("app.log");
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
                BufferedReader br = new BufferedReader(new FileReader(
                        appLog))) {
            String line;
            while ((line = br.readLine()) != null) {
                bw.write(line);
                bw.newLine();
                if ("2 A".equals(line)) {
                    bw.write("New Line!");
                    bw.newLine();
                }
            }
            appLog.delete();
            temp.renameTo(appLog);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
BSteurful
  • 63
  • 9
  • 4
    I beg to differ: this works. Now please, give enough detail to disprove me. – Marko Topolnik Dec 17 '13 at 14:55
  • This will work correctly... – Rakesh KR Dec 17 '13 at 14:56
  • 3
    If you need an empty line, that would be two new line separators – Paolo Falabella Dec 17 '13 at 14:57
  • If you need to append to a log, I suggest you use the append mode (set in the constructor) – Peter Lawrey Dec 17 '13 at 14:58
  • An easy way to see what's going on with whitespace (like '\n') is to put some characters before and after it. – MadConan Dec 17 '13 at 14:58
  • maybe out.writeLine(""); instead of out.newLine();, didn't tried this. – Zemzela Dec 17 '13 at 15:00
  • This is the prove for it that is doesn't work ChangeLog v 1.3.0 Features: + Added a changelog! + You can add anyone to the DisplayNames file when you want to! + You can change you're name with /name! + Added /perms : shows al the permissions -- It is totally bugged an I have no clue but the main thing is that the command is there :p + Working on the permissions... + Added the command /muskie + Fixed some permissions isues - Removed /compass Fixed Bugs: + Display names won't save!!!!! Known Bugs: - Music doesn't stop playing while playing a new one - Command "/spawner" doesn't work anymor – BSteurful Dec 17 '13 at 15:07
  • Oke, that is not very helpful.. :) but thanks – BSteurful Dec 17 '13 at 15:08

5 Answers5

2

The problem that you might be encountering might be because of the "line separator" used by the BufferedWriter (it gets set when you create said class). I think it would be best to use instead:

System.getProperty("line.separator");

This way you use the System's line separator rather than a hard coded one.

So that your code would look like this:

    public void addLine() {
       String lineseparator=System.getProperty("line.separator");
   // I'd suggest putting this as a class variable, so that it only gets called once rather
   // than
   // everytime you call the addLine() method
    try {
        FileWriter stream = new FileWriter(this.log, true);
        //If you don't add true as the second parameter, then your file gets rewritten
       // instead of appended to
        BufferedWriter out = new BufferedWriter(stream);

        out.write(lineseparator); //This substitutes your out.newline(); call

       out.close();
       stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
##############################################################################.

I will try to be as brief and clear as possible.

I assume that you are opening a file that in my code I call "test.txt" and it's got about a paragraph or so. And that you want that outputted to another file, but with "empty lines" at some points.

Because File() is read line by line, it is much easier to open your main file read a line, and then write it to your log file, then analyse if an empty line is necessary and place it.

Let's see some code then.

// Assume you have a private class variable called
private String lineseparator=System.getProperty("line.separator");

// This method is in charge of calling the method that actually carries out the 
// reading and writing. I separate them both because I find it is much cleaner
// to have the try{}catch{} blocks in different methods. Though sometimes for
// logging purposes this is not the best choice
public void addLines() {
    try {
        readAndWrite();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// This method is in charge of reading one file and output to another. 
public void readAndWrite() throws IOException {
    File test = new File("test.txt");
 FileWriter writer = writer = new FileWriter(new File("log.txt"), true);
     //This FileWriter is in charge of writing to your log file

 String line;
 boolean conditionToWriteNewLine=true;
      //Obviously this needs to be changed to suit your situation
      // I just added it for show

 BufferedReader reader = new BufferedReader( new FileReader (test));
 BufferedWriter out = new BufferedWriter(writer);

     //It is in this while loop that you read a line
     // Analyze whether it needs to have a new line or not
    // and then write it out to log file
 while( ( line = reader.readLine() ) != null ) {
        out.write(line); 
        if(conditionToWriteNewLine){
           out.write(this.lineseparator); 
           out.write(this.lineseparator);
               //You need to write it twice for an EMPTY LINE
        }     
 }
 reader.close();
 out.close();   
 }

One of the big differences from this code is that I only open the files once, while in your code you open the log file every time you want to add a new file. You should read the documentation, so you'll know that every time you open the file, your cursor is pointing to the first line, so anything you add will be added to first line.

I hope this helped you understand some more.

Chayemor
  • 3,577
  • 4
  • 31
  • 54
  • Oke, so I've done that and now I have the lines. But the lines are at the begin of the file and totally not where I want them – BSteurful Dec 17 '13 at 15:28
  • I'll try to expand my answer to guide you in the right direction. – Chayemor Dec 17 '13 at 15:40
  • If this worked you should consider setting it as the answer so that other people with a similar problem know what answer helped you. Glad it helped! – Chayemor Dec 17 '13 at 23:36
1

I need a single line between some sentences

I guess you mean a new line between other lines of the same file.

To do so you have to read the whole file, locate the place where you want to insert a line, insert the line then write the new content to the file.

This should work fine for small files but if you have large files you might get in trouble.

So you need a more scaleable way of doing it: Read line by line, and write write to a temp file. if you indentify the location where a new line should be inserted, write that line. Continue with the rest of the file. After you are done delete the original file and rename the temp file with the original name.

Pseudocode:

Open actual file
Open temp file
while not end of actual file
    Read one line from actual file
    Check if new line has to inserted now
        Yes:  write new line to temp
    write line from actual to temp
Close actual file
Close temp file
Delete actual
Rename temp to actual

Code example: (unlike the pseudo code, the new line is inserted after)

Here the line "New Line!" is inserted after each line which is equal to "2 A".

@Test
public void insertNewLineIntoFile() throws IOException {
    File temp = File.createTempFile("app.log", ".tmp", new File("."));
    File appLog = new File("app.log");
    try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp)); 
            BufferedReader br = new BufferedReader(new FileReader(appLog))) {
        String line;
        while((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
            if("2 A".equals(line)) {
                bw.write("New Line!");
                bw.newLine();
            }
        }
        appLog.delete();
        temp.renameTo(appLog);
    }
}

Note that File#delete() and File#renameTo both return a boolean value that is true onyl if the operation was successfull. You absolutely need to check those retuned values and handle accordingly.

A4L
  • 17,353
  • 6
  • 49
  • 70
  • Yes, that is exactly what I mean but I have no clue on how to do this :( – BSteurful Dec 17 '13 at 15:10
  • @BSteurful heh, then just follow the steps I've shown above, do a try using the speudo code I posted (see edit). – A4L Dec 17 '13 at 15:17
  • I don't really get it – BSteurful Dec 17 '13 at 15:31
  • @BSteurful I have added a smale code example, check my edit! – A4L Dec 17 '13 at 15:46
  • Oke, so it does work but I still don't get the line in the file – BSteurful Dec 17 '13 at 16:02
  • How can you say it works when the line does not get in the file?? Did you refrsch the file? try closing and re-opening it from the explorer. If this does'nt help, then edit your question and post the code you have now. – A4L Dec 17 '13 at 16:06
  • With it works I mean it is creating the .tmp and .log file and yes I've done that and it still doesn't work – BSteurful Dec 17 '13 at 16:10
  • @BSteurful did you check the return values of `File#delete()` and `File#renameTo` as a stated in the note above? If the `app.log` file is still open in any application then you might not be able to delete it and to renane the temp file. Please make sure that `app.log` is not opened/locked by any other application and make sure you check the results of the method renameTo and delete, if only one of then returned `false` then it hasn't worked! It will work only if both return true! – A4L Dec 17 '13 at 16:33
  • @BSteurful, heh finally! You're welcome. If this answer was helpful then you might want to mark it as accepted and probably upvote it too ;) – A4L Dec 17 '13 at 17:04
1

I'm not totally sure what you are asking for, but have you tried setting the "append" flag on true, so the FileWriter will not start a new file, but append content to it at the end? This is done by calling the FileWriter(File, boolean) constructor:

public void addLine() {
    try {
        FileWriter stream = new FileWriter(this.log, true); // Here!
        BufferedWriter out = new BufferedWriter(stream);

        out.write("New Extra Line Here");
        out.newLine();

        out.close();
        stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
0

out.println("\n");

(instead of out.newLine();)

\n in java declares a new line. If you dont add any text before it then it should just print a blank line like you want.

Joehot200
  • 1,070
  • 15
  • 44
0

This will work Correctly.

Suggestion:

out.close(); and stream.close(); should write inside finally block ie they should close even if some exceptions occured.

Rakesh KR
  • 6,357
  • 5
  • 40
  • 55