Redirect java output to file

System.out to a file in java

I’m running an application from inside another one for testing purposes. I want to redirect the output for the tested app to a file, so I can have a log after each test. Is there a way to redirect the output of an app to a file from the command line in java?

it’s most likely going to be a solution external with respect to Java VM, like file descriptors redirection in bash/sh (e.g. «app.exe > file.log 2>&1»), unless you use some configurable logging library

7 Answers 7

You can use the output stream redirector that is supported by the Windows command line, *nix shells , e.g.

java -jar myjar.jar > output.txt 

Alternatively, as you are running the app from inside the vm, you could redirect System.out from within java itself. You can use the method

Which replaces the standard output stream, so all subsequent calls to System.out go to the stream you specify. You could do this before running your wrapped application, e.g. calling System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(«output.txt»))));

If you are using a wrapper that you can’t modify, then create your own wrapper. So you have FEST wrapper -> stream redirector wrapper -> tested app.

For example, you can implement a simple wrapper like this:

public class OutputRedirector < /* args[0] - class to launch, args[1]/args[2] file to direct System.out/System.err to */ public static void main(String[] args) throws Exception < // error checking omitted for brevity System.setOut(outputFile(args(1)); System.setErr(outputFile(args(2)); Class app = Class.forName(args[0]); Method main = app.getDeclaredMethod("main", new Class[] < (new String[1]).getClass()>); String[] appArgs = new String[args.length-3]; System.arraycopy(args, 3, appArgs, 0, appArgs.length); main.invoke(null, appArgs); > protected PrintStream outputFile(String name) < return new PrintStream(new BufferedOutputStream(new FileOutputStream(name)), true); >> 

You invoke it with 3 additional params — the Main class to run, and the output/error directs.

Читайте также:  Php search matched with

Источник

How to redirect the output of an interactive program to a file?

I have an interactive java program which takes input from user. now i need to redirect whatever output that has been printed on the screen to a file? Is is possible. From the java docs I got the method «System.setOut(PrintStream ps);» but i am not getting as to how to use this method? E.g. I have a program as:

public class A < int i; void func() < System.out.println("Enter a value:"); Scanner in1=new Scanner(System.in); i= in1.nextInt(); System.out.println("i mt24 mb12">
    java
)" data-controller="se-share-sheet" data-se-share-sheet-title="Share a link to this question" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="question" data-se-share-sheet-social="facebook twitter devto" data-se-share-sheet-location="1" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Share
)" title="">Improve this question
)">edited Nov 3, 2012 at 18:21
asked Nov 3, 2012 at 18:14
3
    if you don't need to do it programmatically, you can redirect the output from the command line (while interacting, you won't see the output anyway, if you want to, you can use tee or similar)
    – ShinTakezou
    Nov 3, 2012 at 18:18
    @Jannat Arora, are you aware that if you redirect the standard output to a file then the user won't have a clue what he is supposed to do (e.g. Enter a value:)? Also, redirecting the input was not even contemplated in your initial question
    – Alexander
    Nov 3, 2012 at 18:27
    @Alexander Sorry for the initial question. but this is my actual question. can someone pls help
    – Jannat Arora
    Nov 3, 2012 at 18:38
Add a comment|

3 Answers 3

Reset to default
2

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

Subscribe to RSS

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.

  1. Redirects standard output to the file foo.txt
  2. 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.

Источник

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 

Источник

Оцените статью