I'm trying to send the output of my program to a text file called results.txt . Here's my attempt
public void writeFile(){
try{
PrintStream r = new PrintStream(new File("Results.txt"));
PrintStream console = System.out;
System.setOut(r);
} catch (FileNotFoundException e){
System.out.println("Cannot write to file");
}
But everytime I run the code and open the file the file is blank. This is what i want to output:
public void characterCount (){
int l = all.length();
int c,i;
char ch,cs;
for (cs = 'a';cs <='z';cs++){
c = 0;
for (i = 0; i < l; i++){
ch = all.charAt(i);
if (cs == ch){
c++;
}
}
if (c!=0){
//THIS LINE IS WHAT I'M TRYING TO PRINT
System.out.println("The character"+ " "+ cs + " "+ "appears --> "+" "+c+" "+ "times");
}
}
}
Where am I going wrong that it keeps creating the file but not writing to it?
(Btw i do have a main method)
use:
PrintWriter writer = new PrintWriter("Results.txt");
writer.print("something something");
don't forget to add:
writer.close();
when you are done!
As you found, System.out IS-A PrintStream and you can create a PrintStream, passing it a File to have it write to that file. This is the beauty of polymorphism --- your code writes to a PrintStream and it doesn't matter what kind it is: console, file, even network connection, or zipped encypted network file.
So instead of messing with System.setOut (usually a bad idea, as it may have unintended side effects; do this only if you absolutely have to (e.g., in some tests)), just pass the PrintStream of your choice to your code:
public void characterCount (PrintStream writeTo) {
// (your code goes here)
writeTo.println("The character"+ " "+ cs + " "+ "appears --> "+" "+c+" "+ "times");
// (rest of your code)
}
Then you call your method as you want:
public static void main(String[] args) throws FileNotFoundException {
new YourClass().characterCount(System.out);
new YourClass().characterCount(new PrintStream(new File("Results.txt")));
}
(Note that I declared that main may throw a FileNotFoundException, as new File("...") can throw that. When that happens, the program will exit with an error message and stack trace. You could also handle it like you did before in writeFile.)
JAVADOC: "A PrintStream adds functionality to another output stream, namely the ability to print representations of various data values conveniently."
PrintStream can be used to write to an OutputStream, not directly to a file. So you can use PrintStream to write to a FileOutputStream and then write to the file with that.
If you just want to simply write to a file though, you can use Cans answer easily!
Related
I am working on a program that uses Dijkstra's algorithm and records the results to a text file. The bit of code I have that writes to the file looks like this:
try (PrintWriter pr = new PrintWriter(filename + "Out.txt")) {
pr.println("Adjacency Matrix: " + (endTime - startTime) + " ms ");
pr.println("Min-Heap: ");
pr.println("Fibonnaci Heap:");
pr.println("Dijkstra Adjacency Matrix");
pr.println(g.printPath(END));
}
} catch (Exception e) {
}
I have no problems with this bit of code, except for the line g.printPath(END). The error I receive is "void type not allowed here". I fully understand what this means. It occurs because the printPath method is void. It looks like this:
public void printPath(String end) {
if (!graph.containsKey(end)) {
System.err.printf("End vertex is not contained within graph \"%s\"\n", end);
return;
}
graph.get(end).printPath();
System.out.println();
}
Since I need access to the variable it would print, I tried to modify it to have a return type that I could write to the text file. What I came up with was this:
public String printPath(String end) {
if (!graph.containsKey(end)) {
System.err.printf("End vertex is not contained within graph \"%s\"\n", end);
return null;
}
graph.get(end).printPath();
System.out.println();
return graph.get(end).printPath();
}
This again has errors, since the method is of type string but graph.get(end).printPath() is void (the get method is also void). I have attempted returning other variables such as graph and graph.get(end) but they do not return the actual variables inside the graph. I know that graph.get(end).printPath() prints out the correct values I want. I am just struggling to find a way to store them. Is there an easy way I can write this to the text file that I am overlooking without having to go back and edit all of my methods to make them not void? Thanks!
There is a way to do it by redirectSystem.out.print:
public String printPath(Graph graph, String end) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(bos);
//set output stream to bos to capture output
System.setOut(printStream);
graph.get(end).printPath(); //your output
System.out.println();
//reset output stream to file descriptor
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
return bos.toString();
}
Redirect the System.out to ByteArrayOutputStream,
Start print
Reset the System.out to FileDescriptor
Finally, Really don't suggestion do it, it's dirty code and important it's not thread-safe, and it's confusing. There is a suggestion about how to deal this:
Create a method to formatt graph.get(end) and return correct String type path
With your current usage, printPath shouldn't be printing anything: maybe you could even rename it to getPath. You need to build a string with the correct value and return it, so that the returned value can be passed to println.
public String printPath(String end) {
if (!graph.containsKey(end)) {
return "End vertex is not contained within graph \"%s\"\n", end);
}
// Also rework this to return a string instead of printlning stuff.
return graph.get(end).printPath();
}
Alternatively, don't pass the value to println and just call g.printPath(END); directly.
try (PrintWriter pr = new PrintWriter(filename + "Out.txt")) {
pr.println("Adjacency Matrix: " + (endTime - startTime) + " ms ");
pr.println("Min-Heap: ");
pr.println("Fibonnaci Heap:");
pr.println("Dijkstra Adjacency Matrix");
g.printPath(END);
} catch (Exception e) {
}
I have some simple class that is DataInputStream stream to read from file.
I have surrounded this stream with EOFException try-catch block.
It has some strange behavior coz sometimes it throws EOFException into text that is read.
Output to console:
"The vessel was in as good condition as I am, and as, I hope
you ar#End of streame#, M. Morrel, and this day and a half was lost from
pure whim, for the pleasure of going ashore, and nothing
else."
I couldn't figure out what is cause of this strange behavior...
Here is code snippet:
public class FormattedMemoryInput {
public static void main(String[] args) throws IOException {
boolean done = false;
try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(
BufferedInputFile.read("./gutenberg/cristo.txt").getBytes()));) {
while (!done) {
System.out.print((char) in.readByte());
}
} catch (EOFException e) {
System.err.println("#End of stream#");
}
}
}
It uses static method BufferedInputFile.read() to read first 500 lines:
public class BufferedInputFile {
// Throw exceptions to console:
public static String read(String filename) throws IOException {
// Reading input by lines:
BufferedReader in = new BufferedReader(new FileReader(filename));
StringBuilder sb = new StringBuilder();
String s;
int i = 0;
while ((s = in.readLine()) != null && (i < 500)) {
sb.append(s + "\n");
i++;
}
in.close();
return sb.toString();
}
Why EOFException is thrown into text?
Solution:
It was at adding one line:
while (!done) {
System.out.print((char) in.readByte());
System.out.flush(); // this one
}
Well, you're getting an EOFException because you're reading forever - you never change the value of done.
The reason it's appearing in the middle of the text instead of at the end is that you're using System.err to print in the exceptional case, and System.out to print the main text. Those are separate streams, flushed separately. If you flush System.out before writing to System.err, I suspect you'll see the main text before the error message. (Note that you're using println on System.err, which will flush automatically, but just print on System.out, which won't.)
There are various other things I'd change about the code - particularly the use of String.getBytes() without specifying an encoding - but assuming I've understood your question correctly, the difference in streams is the reason you're looking for.
System.out is buffered by default; System.err isn't. If you redirect one of the output streams, either in your program or from the shell, you should see the output in the expected order. You can force System.out to print its output by calling System.out.flush();; try inserting that at the end of your while loop.
The following code writes an array into the file, but my problem that it writes it on onto one line when instead I needs it to be on a newline every time that it writes and I can't figure out how to make this part of the code work. I tried adding in the code for a newline as you would for strings but I'm assuming this is not the correct way as it doesn't work.
private class SaveButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent event)
{
String [] data = dataSource.getList();
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("/home/me/Documents"));
int retrival = chooser.showSaveDialog(null);
if (retrival == JFileChooser.APPROVE_OPTION) {
try {
FileWriter fw = new FileWriter(chooser.getSelectedFile()+".txt");
for (int i=0; i<data.length ; i++)
{
fw.write(data[i] + " \n");
}
//fw.write(data.toString());
fw.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
Have you tried
fw.write(data[i] + System.getProperty("line.separator"));
Technically it is writing newlines, but it's likely you're viewing the text file with a text editor that doesn't recognize newline by itself (notepad for instance).
Try:
fw.write(data[i] + " \r\n");
You can use a PrintWriter to easily print individual lines
PrintWriter fw = new PrintWriter(new FileWriter(chooser.getSelectedFile()+".txt"));
for (int i=0; i<data.length ; i++) {
fw.println(data[i]);
}
fw.close();
Note, you should put the close in a finally as otherwise there can be situations when close is not called. In fact you should use the new Java 7 try-with-resources synatx:
try(PrintWriter fw = new PrintWriter(new FileWriter(chooser.getSelectedFile()+".txt"))) {
// stuff
} catch (IOException ex) {
ex.printStackTrace();
}
Note that this will output platform specific linebreaks, so \r\n on windows and \n on Unix. One problem that you will run into time and time again when creating files is opening a file created on one platform on another platform.
FileWriter fw = new FileWriter(chooser.getSelectedFile()+".txt");
chooser.getSelectedFile() should already return a file name with extension so trying adding an extension ".txt" to it isn't making much sense to me.
File writing might be a lengthy operation. So you should run the file writing operation inside a separate thread to avoid blocking EDT thread inside which Swing does it's event management and GUI rendering task. Otherwise your application might get FREEZED.
You might be interested with FileWriter(File file, boolean append) to append your data to a existing file.
Try using System.getProperty("line.separator") to get the correct newline separator for your platform.
I am working through an assignment and have run into a few snags.
My program prints output to the screen, (not how I need it yet) but only prints the first entry to the file. Below is a snippet of the code. The file appears to be reading in the data from the input file, but the loop does not output to the file past the first entry.
Scanner in = new Scanner(System.in); //Scanner object to read input from the file
System.out.println("Enter filename to read "); //file name prompt
String inputFileName = in.nextLine(); //line input reads next line
/*
* TODO 2) Use an unbuffered file input stream to open listings.txt file
* and read in property listings.
*/
Scanner reader = null;
try {
reader = new Scanner(new File(inputFileName));
} catch (FileNotFoundException e) {
System.out.println("Try Again"); //error window if name is null
JOptionPane.showMessageDialog(null, "You must enter a filename", "File input error", JOptionPane.ERROR_MESSAGE);
return;
}
PrintWriter out = new PrintWriter("agentreport.txt"); //This method prints out the file readfile.txt a word at a time
while (reader.hasNextLine()) { //It needs to output to the text file. Currently a file is created, but it is empty?
Scanner s2 = new Scanner(reader.next());
#SuppressWarnings("unused")
boolean b;
while (b = s2.hasNext()) {
String output = s2.next();
String output2 = output.toUpperCase(); //converts output to upper case
System.out.println(output2);
out.print(output2); //only printing the first entry to the agentsreport.txt file. Not stepping thru the file for some reason?
}
Even if you are using automatic flushing, which you aren't in this case, the PrintWriter object would output anything in its internal buffer unless you do one of two things:
1) Use the println(), printf(), or format() to methods
2) Make a call to the flush() method every time you print, this way all of the data in the internal buffer gets written out.
Note: The print() method does not cause the PrintWriter object to flush() its buffer.
try adding a call to flush() after you call print()
Example of split()
PrintWriter out = new PrintWriter("agentreport.txt");
while (reader.hasNextLine()) {
String words = reader.nextLine().split();
#SuppressWarnings("unused")
boolean b;
for(String word : words) {
String output = word ;
String output2 = output.toUpperCase(); //converts output to upper case
System.out.println(output2);
out.print(output2);
}
One thing that immediately jumps out is that you aren't handling your resources properly.
Any time you use an IO resource such as a reader/database connection/etc., you should always close it using a finally block, using this sort of pattern:
Reader reader = /* construct it however */
try {
/* do something with the reader */
}
finally {
reader.close();
}
If you don't do this, there's no guarantee that the reader will actually be closed, and your application will leak file descriptors/connection pool connections/etc., until eventually it won't be able to get hold of any more and your app crashes. (This won't always have fatal consequences, but it's such a straightforward pattern you should use it every time until it becomes automatic).
In this case, you aren't closing your writer at all, which means that it's not guaranteed that it ever actually flushes its output to the file. It would be perfectly in accordance with the Writer interface for it to write everything or nothing - without the flush, you have no guarantees. Note that closing the writer will automatically call flush, so that's the best bet once you're done with it.
So the latter part of your code should look like:
PrintWriter out = new PrintWriter("agentreport.txt");
try {
// Existing code here
}
finally {
// This closes the file and frees the descriptor, but also flushes the buffers
out.close();
}
Also, how are you handling the IOExceptions that can be thrown by the reading and writing? Are you catching them and swallowing them somewhere? If so, it's possible that your code is throwing an exception telling you exactly why it can't write, and you're just ignoring it and then looking puzzled.
Not to put too fine a point on it, error handling is probably the most significant part of good software development. It's not too hard to write software that works when everything's fine; the most challenging part is handling things well when you run out of space on the hard drive, or the network is temporarily down, etc.
In this case the most pragmatic approach would be to just let the exception be thrown out of the top of your main method. In this case your application will "crash", and you'll get a stacktrace + error message on the console, which will make it immediately clear that something went wrong, and give you a very good idea of what it was.
try
out.println(output2);
http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html
also I'd use a var other than "out" as when system.out is imported to use the shortcode 'out.println()', this could cause variable confusion
edit: good point #Hunter McMillen, changed to println as append is for a CharSequence.
try (
Scanner reader = new Scanner(new File(inputFileName));
PrintWriter writer = new PrintWriter(new FileOutputStream("agentreport.txt"), true);
) {
while (reader.hasNextLine()) {
String output = reader.nextLine().toUpperCase();
System.out.println(output);
writer.println(output);
}
} catch (FileNotFoundException e) {
System.out.println("Try Again"); //error window if name is null
JOptionPane.showMessageDialog(null, "You must enter a filename", "File input error", JOptionPane.ERROR_MESSAGE);
}
I have a function "a()" that calls another function "b()" that writes to stdout. I cannot modify "b()", but I want to be able to read what "b" is writing and write back to stdout for "b" to read, meaning:
public void a() {
// start a thread that listens to stdout.
// the thread should print a name to stdout after "b" print "Please enter your name"
b();
}
public void b() { // I cannot modify this function
System.out.println("Welcome! The time is " + System.currentTimeMillis());
System.out.println("Please enter your name");
String name = ...
// ... b reads here the name that the thread from function a() will write
// ...
System.out.println("This is the name that was entered: " + name);
}
I thought about starting "b" in a new process but I wasn't sure how unless I wrap "b" in a main function and run it using a command line - I'd be happy for suggestions.
If it's not a process, I'm not sure how to implement the thread that will be activated by "a()".
I tried using:
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = stdin.readLine()) != null) {
...
}
but it doesn't catch what "b" is writing.
Thanks for the help
You can run b() in another process but you don't need to do so.
System.out is a PrintStream. If you read the javadoc carefully you will notice System.setOut method. With it you can replace System.out with another PrintStream.
Example (not tested):
PrintStream originalOut = System.out; // To get it back later
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream newOut = new PrintStream(baos);
System.setOut(newOut);
b();
System.out.flush();
System.setOut(originalOut); // So you can print again
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
// Now you can read from bais what b() wrote to System.out
This solution has the problem of not being thread safe. If any other thread write to System.out when it is 'changed' the output will get redirected too. To get rid of this problem I think you need to run b() on another JVM or use a PrintStream that split (deMux) the output depending on the thread or context.
Unfortunately there is not easy way of doing this in Java. The biggest problem is that System.out and System.in are two separate files, created from FileDescriptor.out and FileDescriptor.in respectively. They are not connected in any way, and therefore you can't write to System.out and expect to see it in System.in.
Your options are:
Run b() in external process somehow. Yes, you'll need to put it in a class with main() function and do lots of complicated process setup, like getting the path to java.exe and setting up classpaths etc. The good part is that writing to and reading from the process will work as you expect.
Create two custom Input and Output streams that can duplicate all traffic to another in/out stream, as well as sending it to System.{in,out}, and set them using System.set{In,Out}. This way you can monitor those streams without affecting other code that might by using System.{in,out}.
As an example of the custom OutputStream mentioned in 2, try something like this:
class CopyOutputStream extends OutputStream {
private final OutputStream str1;
private final OutputStream str2;
public CopyOutputStream(OutputStream str1, OutputStream str2) {
this.str1 = str1;
this.str2 = str2;
}
#Override
public void write(int b) throws IOException {
str1.write(b);
str2.write(b);
}
// ...
#Override
public void close() throws IOException {
try {
str1.close();
} finally {
str2.close();
}
}
}
// then in a() do
public void a(){
//Create a pipe to capture data written to System.out
final PipedInputStream pipeIn = new PipedInputStream();
final PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);
OutputStream out = new CopyOutputStream(System.out, pipeOut);
//From now on everything written to System.out will be sent to
// System.out first and then copied to pipeOut and will be available
// to read from pipeIn.
System.setOut(new PrintStream(out));
// In another thread: read data from System.out
BufferedReader reader = new BufferedReader(new InputStreamReader(pipeIn));
String name = reader.readLine();
}
Unfortunately you will have to repeat the above process for System.in, which means more crazy code, but I don't think it will get easier than this.
If you are ready for some really crazy action, maybe you can get hold of some java library (most likely with native code), that can give you the Process object of the currently running JVM, and then use get{Input,Output}Stream() methods to do the job.
How about setting System.out with System.setOut