System.setout redirects the standard output. For instance,
FileOutputStream f = new FileOutputStream("file.txt");
System.setOut(new PrintStream(f));
Every System.out.print will write in the file. My question is, how to set the output back to the standard once this has been done?
Just save it and restore it:
final PrintStream oldStdout = System.out;
System.setOut(newStdout);
// ...
System.setOut(oldStdout);
Related
I'm writing a Java program which uses Lua scripts to determine what to output to certain areas of the program. Currently, my code looks as such:
Globals globals = JsePlatform.standardGlobals();
LuaValue chunk = globals.loadfile(dir.getAbsolutePath() + "/" + name);
chunk.call();
String output = chunk.tojstring();
The problem is that calling tojstring() appears to return return values from the Lua script. This is fine, but I need to get print calls, as that's what will be displayed on the screen. As of now, the print calls get sent directly to the Console (printed to console), and I cannot figure out a way to retrieve these print calls.
I've tried digging through the documentation but have had little success. Will change from LuaJ if needed.
Expanding on Joseph Boyle's answer (a few years later): You can also set up a printStream to a ByteArrayOutputStream (no need to do it to a file on disk) if that's your poison. I did this in a JUnit test with LuaJ and it works:
#Test
public void testPrintToStringFromLuaj() throws IOException {
String PRINT_HELLO = "print (\"hello world\")";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(baos, true, "utf-8");
Globals globals = JsePlatform.standardGlobals();
globals.STDOUT = printStream;
LuaValue load = globals.load(PRINT_HELLO);
load.call();
String content = new String(baos.toByteArray(), StandardCharsets.UTF_8);
printStream.close();
assertThat(content, is("hello world\n"));
}
I actually was able to solve the problem by changing the STDOUT variable in the globals object to a temporary file, and then reading the data from the temporary file.
Probably not the best solution, but works perfectly fine.
I've tried using BufferWriter format as well as FileWriter and PrintWriter each with a boolean true statement but they both behave the same as if I simply used a simple new File. Each time I get to the end of my program run, I call the function that writes the saved data to be appended. What ends up happening is that it overwrites the last saved data. I also have other code blocks that handle that text file as well and reformating them did nothing either.
//saves user information to "Users.txt" which will be called in the finally block after choice switch
public void writeUsers()
{
try{
File userFile = new File("Users.txt");
PrintWriter output = new PrintWriter(userFile);
for(User i: userList) {
output.append("Name:");
output.println(i.getrealName());
output.append("UID:");
output.println(i.getidName());
output.append("Password:");
output.println(i.getpassword());
output.println(" ");
}
output.close();
System.out.print("Information has been saved to Users.txt\n");
}
catch(FileNotFoundException fnf) {
System.err.println("FileNotFoundException: File Users.txt does not exist " + fnf);
}
catch(IOException eyeoh) {
System.err.println("IOException: Error writing to Users.txt " + eyeoh);
}
}
The constructor PrintWriter(File) truncates the output file by default. The fact that PrintWriter's method append() is called doesn't mean that it changes the mode of the file being opened. The behavior for append is described as:
An invocation of this method of the form out.append(csq) behaves in exactly the same way as the invocation
out.write(csq.toString())
Here, you could use the constructor for PrintWriter that takes a FileOutputStream for appending
PrintWriter output =
new PrintWriter(new FileOutputStream(userFile, true /* append = true */));
You have to create the PrintWriter in append mode. Otherwise, when it first opens the file, it will clear it out. You can open it in append mode using:
new PrintWriter(new FileWriter(userFile,true)) // the `true` argument opens it in append mode
PrintWriter by defualt truncates all existing data. To append you could, as other answers suggest, add a "true" argument to the constructor, which denotes "append = true,"
However, this is done more elegantly using java.nio.file.Files along with java.nio.file.StandardOpenOption, in which you can specify StandardOpenOption.APPEND as opposed to StandardOpenOption.TRUNCATE_EXISTING
You can also specify things such as StandardOpenOption.CREATE which creates the file if it does not exist.
Additionally, remember to either place your output.close() statement in a finally block, or use try-with-resources. Otherwise if the flow of the program is interrupted (i.e. an Exception is thrown), output would remain unclosed. I personally use try-with-resources as it is less of a hassle: just declare all your resources, and they are closed automatically for you, whether or not the flow of the program is disrupted.
Also, as a general tip, print or pass the actual Exception object in your catch block, as opposed to just a "custom string" so as to not lose the original content of the Exception thrown. You can then concatenated that with whatever string you also want to print.
try(BufferedWriter bufWriter =
Files.newBufferedWriter(Paths.get("Users.txt"),
Charset.forName("UTF8"),
StandardOpenOption.WRITE,
StandardOpenOption.APPEND, //Makes this BufferedWriter append to the file, not truncate
StandardOpenOption.CREATE);
PrintWriter output = new PrintWriter(bufWriter, true);)
{
output.println("Text to be appended.");
}catch(FileNotFoundException e){
System.err.println(e + "Custom string");
}catch(IOException e){
System.err.println(e + "Something eyeoh occurred...");
}
This uses a try-with-resources statement to declare and create a BufferedWriter using java.nio.file.Files, which accepts StandardOpenOption parameters, and an auto-flushing PrintWriter (denoted by "true" in the constructor) from the resultant BufferedWriter. PrintWriter's println() method, can then be called to write to the file.
The StandardOpenOption parameters used in this code: opens the file for writing, only appends to the file, and creates the file if it does not exist.
Paths.get("path here") can be replaced with new File("path here").toPath(), if you are working exclusively with File objects (i.e. if you are using JFileChooser.getSelectedFile())
And Charset.forName("charset name") can be modified to accommodate the desired Charset.
I am new to Java and I am stuck at this part :
I am trying to output the console output into a text file using JAVA .
But the problem is I have a While loop running and my code writes the output to the file but deletes the previous one .
I want to append the while loop output to file .
Any help is appreciated . Thanks In advance :)
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
You need to append the new data to the previous data in the file, try this...
try{
File f = new File("d:\\t.txt");
FileWriter fw = new FileWriter(f,true); // true is for append
BufferedWriter bw = new BufferedWriter(fw);
bw.append(Your_data);
}catch(Exception ex){
ex.printStackTrace();
}
You should perform the redirection once, and before you do anything else. i.e. before you enter your loop.
Note (also) that your shell can redirect to a file, and that might be preferable to changing the destination of System.out. That's feasible but perhaps unexpected for someone who's going to debug your code in the future and wonder where their output is going...
Or perhaps consider a logging framework ?
Do it like this:
FileOutputStream fout=new FileOutputStream("output.txt",true);
while(condition)
{
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
}
where second argument to FileOutputStream will open it in appendable mode.
I have a file (file.txt), and I need to empty his current content, and then to append some text multiple times.
Example: file.txt current content is:
aaa
bbb
ccc
I want to remove this content, and then to append the first time:
ddd
The second time:
eee
And so on...
I tried this:
// empty the current content
fileOut = new FileWriter("file.txt");
fileOut.write("");
fileOut.close();
// append
fileOut = new FileWriter("file.txt", true);
// when I want to write something I just do this multiple times:
fileOut.write("text");
fileOut.flush();
This works fine, but it seems inefficient because I open the file 2 times just for remove the current content.
When you open up the file to write it with your new text, it will overwrite whatever is in the file already.
A good way to do this is
// empty the current content
fileOut = new FileWriter("file.txt");
fileOut.write("");
fileOut.append("all your text");
fileOut.close();
The first answer is not correct. If you create a new filewriter with the true flag for the second parameter, it will open in append mode. This will cause any write(string) commands to "append" text to the end of the file, not wipe out whatever text is already there.
I'm just stupid.
I only needed to do this:
// empty the current content
fileOut = new FileWriter("file.txt");
// when I want to write something I just do this multiple times:
fileOut.write("text");
fileOut.flush();
And AT THE END close the stream.
I see that this question was answered quite a few Java versions ago...
Starting from Java 1.7 and using the new FileWriter + BufferWriter + PrintWriter for appending (as recommended in this SO answer ), my suggestion for file erasing and then appending:
FileWriter fw = new FileWriter(myFilePath); //this erases previous content
fw = new FileWriter(myFilePath, true); //this reopens file for appending
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
pw.println("text");
//some code ...
pw.println("more text"); //appends more text
pw.flush();
pw.close();
Best I could think of is :
Files.newBufferedWriter(pathObject , StandardOpenOption.TRUNCATE_EXISTING);
and
Files.newInputStream(pathObject , StandardOpenOption.TRUNCATE_EXISTING);
In both the cases if the file specified in pathObject is writable, then that file will be truncated.
No need to call write() function. Above code is sufficient to empty/truncate a file.This is new in java 8.
Hope it Helps
I need to write something into a text file's beginning. I have a text file with content and i want write something before this content. Say i have;
Good afternoon sir,how are you today?
I'm fine,how are you?
Thanks for asking,I'm great
After modifying,I want it to be like this:
Page 1-Scene 59
25.05.2011
Good afternoon sir,how are you today?
I'm fine,how are you?
Thanks for asking,I'm great
Just made up the content :) How can i modify a text file like this way?
You can't really modify it that way - file systems don't generally let you insert data in arbitrary locations - but you can:
Create a new file
Write the prefix to it
Copy the data from the old file to the new file
Move the old file to a backup location
Move the new file to the old file's location
Optionally delete the old backup file
Just in case it will be useful for someone here is full source code of method to prepend lines to a file using Apache Commons IO library. The code does not read whole file into memory, so will work on files of any size.
public static void prependPrefix(File input, String prefix) throws IOException {
LineIterator li = FileUtils.lineIterator(input);
File tempFile = File.createTempFile("prependPrefix", ".tmp");
BufferedWriter w = new BufferedWriter(new FileWriter(tempFile));
try {
w.write(prefix);
while (li.hasNext()) {
w.write(li.next());
w.write("\n");
}
} finally {
IOUtils.closeQuietly(w);
LineIterator.closeQuietly(li);
}
FileUtils.deleteQuietly(input);
FileUtils.moveFile(tempFile, input);
}
I think what you want is random access. Check out the related java tutorial. However, I don't believe you can just insert data at an arbitrary point in the file; If I recall correctly, you'd only overwrite the data. If you wanted to insert, you'd have to have your code
copy a block,
overwrite with your new stuff,
copy the next block,
overwrite with the previously copied block,
return to 3 until no more blocks
As #atk suggested, java.nio.channels.SeekableByteChannel is a good interface. But it is available from 1.7 only.
Update : If you have no issue using FileUtils then use
String fileString = FileUtils.readFileToString(file);
This isn't a direct answer to the question, but often files are accessed via InputStreams. If this is your use case, then you can chain input streams via SequenceInputStream to achieve the same result. E.g.
InputStream inputStream = new SequenceInputStream(new ByteArrayInputStream("my line\n".getBytes()), new FileInputStream(new File("myfile.txt")));
I will leave it here just in case anyone need
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (FileInputStream fileInputStream1 = new FileInputStream(fileName1);
FileInputStream fileInputStream2 = new FileInputStream(fileName2)) {
while (fileInputStream2.available() > 0) {
byteArrayOutputStream.write(fileInputStream2.read());
}
while (fileInputStream1.available() > 0) {
byteArrayOutputStream.write(fileInputStream1.read());
}
}
try (FileOutputStream fileOutputStream = new FileOutputStream(fileName1)) {
byteArrayOutputStream.writeTo(fileOutputStream);
}