Java 写入控制台和文本文件

Java 写入控制台和文本文件,java,file-io,console,fileoutputstream,printstream,Java,File Io,Console,Fileoutputstream,Printstream,我从互联网上找到了下面的代码,可以工作,但它不会将打印的控制台写入omt.txt,它只会在第二个catch块之后写入System.out.println语句。如果您运行代码,您就会明白我的意思。我只想将控制台上的内容写入“omt.txt”文件,这就是全部 在回答了一些问题后,我发现我的问题不清楚,对此表示抱歉。 我想将控制台输出保存到omt.txt文本文件中。如果在控制台上打印“Hello 123”,它也应该在omt.txt文件中。换句话说,控制台上打印的任何内容都应该同时写入om.txt文件,

我从互联网上找到了下面的代码,可以工作,但它不会将打印的控制台写入omt.txt,它只会在第二个catch块之后写入
System.out.println
语句。如果您运行代码,您就会明白我的意思。我只想将控制台上的内容写入“omt.txt”文件,这就是全部

在回答了一些问题后,我发现我的问题不清楚,对此表示抱歉。 我想将控制台输出保存到omt.txt文本文件中。如果在控制台上打印“Hello 123”,它也应该在omt.txt文件中。换句话说,控制台上打印的任何内容都应该同时写入om.txt文件,也可以在控制台执行后写入,但应该是1对1

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class Wrt_file {

    public static void main(String[] args) {
        System.out.println("THIS is what I see on the console. but not on TEXT file"); 

          File f = new File("omt.txt");
          if(!f.exists())
          {
            try {
                       f.createNewFile();
                } catch (Exception e) {
                    e.printStackTrace();
                }
          }

        try {
                FileOutputStream fos = new FileOutputStream(f);
                PrintStream ps = new PrintStream(fos);
                System.setOut(ps);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("THIS is what I see on the text file, but not on CONSOLE");      

        for (int i=0; i<10; i++){

            System.out.println("Testing");  
        }

    }

}
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.PrintStream;
公共类Wrt_文件{
公共静态void main(字符串[]args){
System.out.println(“这是我在控制台上看到的,但不是在文本文件上看到的”);
文件f=新文件(“omt.txt”);
如果(!f.exists())
{
试一试{
f、 createNewFile();
}捕获(例外e){
e、 printStackTrace();
}
}
试一试{
FileOutputStream fos=新的FileOutputStream(f);
打印流ps=新打印流(fos);
系统放样(ps);
}捕获(例外e){
e、 printStackTrace();
}
System.out.println(“这是我在文本文件上看到的,但不是在控制台上看到的”);

对于
System.java
中的(int i=0;i),这是
out
属性的声明:

public final static PrintStream out
您将看到,它一次只能是一个PrintSteam对象,因此它要么是控制台,要么是文件,但不是两者都是

在这一行,您有效地重新引导了目的地:

System.setOut(ps);
因此,您的输出停止显示在控制台上。

原因是:

java.lang.System.setOut()方法重新分配“标准”输出流

因此,当您使用
System.out.println
时,它将只在文本文件中打印

因此,如果要在文本文件和控制台上打印,请尝试以下操作:

FileOutputStream fos=新的FileOutputStream(f);
打印流ps=新打印流(fos);
ps.println(“这是我在文本文件上看到的,但不是在控制台上看到的”);
System.out.println(“这是我在文本文件上看到的,但不是在控制台上看到的”);
对于(int i=0;i<4;i++){
ps.println(“测试”);
系统输出打印(“测试”);
} 
了解到OP想要复制流后更新了答案 由于要在两个流中写入数据,请尝试使用from。请在第二秒内更改代码,然后尝试使用

try {
    FileOutputStream fos = new FileOutputStream(f);
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        try {
            fos.flush();
        }
        catch (Throwable t) {
            // Ignore
        }
    }, "Shutdown hook Thread flushing " + f));
    //we will want to print in standard "System.out" and in "file"
    TeeOutputStream myOut=new TeeOutputStream(System.out, fos);
    PrintStream ps = new PrintStream(myOut, true); //true - auto-flush after println
    System.setOut(ps);
} catch (Exception e) {
    e.printStackTrace();
}

现在,来自
系统的结果。out
也将放在您的文件中。

我解决此问题的方法是简单地定义您自己的PrintStream,它将覆盖您正在使用的方法:

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class DualStream extends PrintStream {
    public PrintStream consoleOutput = null;
    public PrintStream fileOutput = null;

    public DualStream(final PrintStream consoleOutput, final PrintStream fileOutput) throws FileNotFoundException {
        super(fileOutput, true);
        this.consoleOutput = consoleOutput;
        this.fileOutput = fileOutput;
    }

    @Override
    public void println() {
        consoleOutput.println();
        super.println();
    }

    @Override
    public void println(final Object output) {
       consoleOutput.println(output);
        super.println(output);
    }

    @Override
    public void println(final String output) {
        consoleOutput.println(output);
        super.println(output);
    }

    @Override
    public PrintStream printf(final String output, final Object... variables) {
        consoleOutput.printf(output, variables);
        super.printf(output, variables);
        return this;
    }
}
我们不重写的每个方法都将默认为仅将输出写入文件。(要默认为控制台,您可以在构造函数中切换1行或在构造函数调用中切换两个printstreams位置)

现在只需定义2个printstreams,其中一个将写入您的文件,让我们将其设置为bufferedoutputstream以确保良好的性能:

public static void outputFile(final String file) {
    PrintStream CombinedOutput = null;
    try {
        CombinedOutput = new DualStream(System.out, new PrintStream(new BufferedOutputStream(new FileOutputStream(file))));
    } catch (final FileNotFoundException e) {
        e.printStackTrace();
    }
    System.setOut(CombinedOutput);
}

我知道代码是有效的,测试…被写入文本文件,但测试..循环不在java控制台上,java控制台上打印的文本也不在文本文件中…我想要的是如果我在控制台上打印“Hello 123”,Hello 123应该在omt中。TXT没有镜像控制台的方法吗?我认为在java中它不应该这么复杂:/你所说的
镜像控制台是什么意思
?你想同时打印到控制台和文件中吗?这正是我想要的…如果不能同时执行,我希望他们至少显示same results…我认为在java中应该可以将控制台上显示的输出保存到文本文件中…这就是我想要的。@Ronixus Yeah Apache Commons rules:)@Anarkie您几乎没有向项目添加JAR的方法。“添加外部JAR”方法2(您需要打开java视图)或者3是您正在寻找的:
右键单击项目
->
构建路径
->
添加外部库
。从下载
commons-io-2.4-bin.zip
。当您解包时,您将看到
commons-io-2.4.jar
。将其添加到您的项目中。@Anarkie如果您希望该行也在您的文件中,那么您需要将标准输出流更改为
System.setOut(ps)后,移动打印它的代码
。在您重定向输出流之前,我看不到任何方法可以将已打印的消息包含到文件中。虽然我认为他希望一次写入两个位置,但我认为这是最接近的可行解决方案。+1对您而言。啊哈,但他在问题中没有这样说:)
public static void outputFile(final String file) {
    PrintStream CombinedOutput = null;
    try {
        CombinedOutput = new DualStream(System.out, new PrintStream(new BufferedOutputStream(new FileOutputStream(file))));
    } catch (final FileNotFoundException e) {
        e.printStackTrace();
    }
    System.setOut(CombinedOutput);
}