You can do something like:
System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt"))));
To write something to a file there a number of ways, you can take a look at Reading, Writing, and Creating Files tutorial. In your case, if you would like to print exactly what is on the screen in a file too, even the user input, you can do something like:
void func() < try < PrintStream out=new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt"))); System.out.println("Enter a value:"); out.println("Enter a value:"); Scanner in1=new Scanner(System.in); int i= in1.nextInt(); out.println(i); System.out.println("i="+i); out.println("i="+i); out.close(); >catch (FileNotFoundException e) < System.err.println("An error has occurred "+e.getMessage()); e.printStackTrace(); >>
Источник
how to redirect stdin and stdout to a text file in java
What have you tried yet? Have you tried to read the file, parse it, etc.? If yes, could you provide your code snippets?
If this is some kind of homework or assignment, please tag the question accordingly, so you get appropriate answers.
3 Answers 3
You can set the System.out and System.in to a file path. Then your existing code should work
System.setIn(new FileInputStream(new File("input.txt"))); . //read from file . System.setOut(new PrintStream(new File("filename.txt"))); System.out.println(sum); // will be printed to the file
You don't have to do that in Java, you can do it from the shell that runs your Java application:
# cat input.txt | java -jar myapp.jar > output.txt
The Java code can then just read from System.in and write to System.out.
How would I get a File object then to take a file name from stdin? E.g. File newFile = new File(. ) when I have java compiled < afile.txt ?
There would not be a file there. The contents of afile.txt will be piped into System.in , you can read from that.
This is a reflection based solution incorporating part of code from @sidgate's answer:
import java.lang.reflect.Method; public class Driver < public static void main(String[] args) throws Exception < runSolution("utopiantree"); >private static void runSolution(String packageName) throws Exception< System.setIn(Driver.class.getClassLoader().getResourceAsStream(packageName + ".tc")); Method mainMethod = Class.forName(packageName + ".Solution").getMethod("main", new Class[]); mainMethod.setAccessible(true); mainMethod.invoke(null, new Object[]); > >
Linked
Hot Network Questions
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.27.43548
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Источник
Redirect Selected Console Output to File
I have a small Java program that is being invoked with java -jar via a bash script. The program calls a SOAP webservice and I want to capture the SOAP messages in a file for future troublshooting. The only way I've found to do this in a standalone Java app is by adding this to my client class:
This outputs the SOAP messages to system out. I could just redirect system out to a file, but I have other messages going to system out that I want to be displayed on the console. It's okay to include these messages in the file but the SOAP messages are just way too much to be displayed on the console. Is there a way I can do some sort of selective redirect on console output?
If the other messages going to the console are your own then you could prepend them with a special symbol and then filter the output through an appropriate script. It seems unlikely that you'll be able to do this in-app the SOAP code will be calling System.out.print.
@selig Yes, that's what I ended up doing. If you add your comment as an answer, I'd gladly accpet it.
3 Answers 3
Depends on the SOAP library you are using, but generally most SOAP libraries have some sort of logging facility they use when writing things out to the console. Typically when you use these logging facilities the SOAP library itself doesn't write directly to System.out. The logging facility is configured to write that data to System.out by default. So if you figure out which SOAP lib you're using, then figure out what logging facility it uses, then you can configure logging to write to a file instead of System.out, but still send other messages to System.out.
I think you're using Metro which is using Java Util Logging. Not as easy to configure, but it can be configured with multiple appenders and loggers. I think this will be helpful for you:
Thanks for the suggestion. However, I looked into if Metro actually logs the SOAP messages or simply writes them them to System.out. Couldn't find the source code, but all referecences I could find state it's to System.out. To double check, I changed my program to use java.util.Logging directly (vice SLFJ) and the SOAP still doesn't get logged to the log file.
The docs aren't specific about how to configure the logging system, but I did find evidence that if you can figure out how to configure logging using a new logging.properties file it will redirect it. Changing your program to use java.util.Logging won't affect the configuration of the logging in SOAP per se. You have to change the logging.properties config file to do that.
It was an interesting/frustrating experiment for me to use java.util.logging as I've always used Log4J and now Logback. So, it's quite possible that it could be done, but it isn't worth the hassle for me when I've found a solution as per above.
Why not write the messages you want to capture to stderr and redirect that appropriately? One thin you should consider is that stdout is [usually] buffered and stderr is not.
You're looking for shell redirection and piping. Assuming you're using a standard-ish shell like shell, bash, csh, etc. .
- command >foo.txt will redirectstdout to the file foo.txt . Any existing content in the fill will be replaced.
- command >>foo.txt will redirectstdout, appending it to the file foo.txt to the existing content, if any, of foot.txt .
- foo | bar will pipe the content of command foo 's stdout through command bar 's stdin.
A *nix process has three standard i/o handles open:
- stdin is standard input. It is file handle 0.
- stdout is standard output. It is filehandle 1.
- stderr is standard error. It is filehandle 2.
The redirection and pipe operators can hook specific file handles as well. So.
- Redirects standard output to the file foo.txt
- Redirects stderr to file handle 1, stderr, which is now opened as foo.txt .
Other shells can (and do) use different, but generally similar syntax.
You should also learn about some useful commands:
tee(1) . This takes the stdin given it and writes it to file specified on the command line as well as to stdout, so a chain like this:
some-command 2>&1 | tee some-command.log.2013-05-31.txt | less
This page describes the usual piping/redirection operators for the C and Bourne shell families: http://www.mathinfo.u-picardie.fr/asch/f/MeCS/courseware/users/help/general/unix/redirection.html
You should also read the appropriate O'Reilly Nutshell book:
Edited To Note: As I mentioned in the comment below, you can replace System.Out and System.Err with your own PrintStream , along these lines:
PrintStream originalStdOut = System.Out ; PrintStream newStdout = CreateNewOutputSink() ; System.Out.flush() ; System.Out.setOut( newStdout ) ; invokeSome3rdPartyCode() ; System.Out.flush() ; System.Out.setOut( originalStdout ) ;
This will let you hook the output from your 3rd party library and redirect it to the data sink of your choice, whilst not affecting your ordinary output. If you hook both System.Out and System.Err and redirect them to the same PrintStream you'll catch both standard and error output in the process.
Источник
Print java output to a file
Most logging facilities support this kind of thing. For example, adding a ConsoleAppender and a FileAppender with Log4J will do this. Somebody mentioned SLF4J - which is true although its just a facade. As far as I know, you still need to configure which logging facility it will use behind the scenes.
5 Answers 5
You can include the following lines at the start of your program:
final PrintStream origout = System.out; final PrintStream fileout = new PrintStream(file); System.setOut(new PrintStream(new OutputStream() < @Override public void write(int b) throws IOException < origout.write(b); fileout.write(b); >>));
I am putting this at the beginning of my main method but I'm getting all sorts of errors, including undefined constructors etc. I imported all the appropriate packages. Please help
I got it to work by replacing new OutputStream with fileout. However, this is causing me to not be able to see any output in the console, rather I can only see output in the .txt file. How can I output to both?
You can use System.setOut() to redirect System.Out to a custom OutputStream that duplicates its output to both the console and a file.
You can write to a console. And write to a file. You can thread them seperately so they're not dependent upon each other.
There isn't an API for doing both at the same time that I'm aware of (not that that says too much, it should be trivial to write one).
Edit: Have I misunderstood? Do you mean from Java code or just piping the output of the java binary to console and a file? In which case you could do something like:
java Main 2>&1 | tee -a Load.log
Источник