【问题标题】:Console output to file using multithreading使用多线程将控制台输出到文件
【发布时间】:2015-12-02 23:54:51
【问题描述】:

有没有办法在多线程时将整个控制台输出保存到文件中?我正在使用 5 个线程。我有一个想法,我可以在运行方法中放置一个打印流。

示例:

public void run()  {
 try{
    PrintStream out = new PrintStream(file);
    stopExecute stop = new stopExecute();
    Thread t = new Thread(stop);
    Scanner in = new Scanner(System.in);
    t.start();

        while (!in.hasNextLine()) 
    {
        classThatUsingMultipleThrads();
        System.out.println("Finished");
        anotherClassThatUsingThreads(); 
        System.out.println("Finished"); 
    }
        System.out.prinln("User stopped the execution");
        stop.keepRunning = false;
        System.setOut(out);

       }
    catch(IOException e){System.out.println(e);}

这里的问题是它只保存输出“用户停止执行”,而 whileloop 中的所有内容都没有保存。或其他类的输出流。

我试着把

System.setOut(out);

在while循环中,但没有帮助。

编辑:拼写更正

【问题讨论】:

  • “完成”,而不是“完成” :) 哦。并且“停止”而不是“停止”。
  • 使用 Log4J 之类的日志框架会帮助您解决问题吗?
  • @C-Otto 谢谢指正,我每天都在学习新东西:)

标签: java multithreading file


【解决方案1】:
  try {
  System.setOut(new PrintStream(new File("output-file.txt")));
 } 
 catch (Exception e) {
  e.printStackTrace();
 }

感谢:System.out to a file in java

【讨论】:

    【解决方案2】:

    您可能应该考虑使用 Log4J 等日志库。但是,您也可以使用 TeeOutputStream 之类的东西。这种类型的输出流在调用时会写入其他 2 个流。一些库有很好的实现,但您也可以自己编写一个。我很快就把这个弄好了。

    您可以在main 方法中设置整个程序的输出流以使用此TeePrintStream,然后对System.out.* 的所有调用将数据写入通常的System.outFileOutputStream

    这里还有一个 TeePrintStream 的实现http://www.java2s.com/Code/Java/File-Input-Output/TeePrintStreamteesallPrintStreamoperationsintoafileratherliketheUNIXtee1command.htm

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.PrintStream;
    
    public class SO34042494 {
        public static void main(String[] args) throws FileNotFoundException {
            System.setOut(new TeePrintStream(System.out, new FileOutputStream(new File("x:\\output.txt"))));
    
            System.out.println("Check check");
            System.out.println("1");
            System.out.println(2);
            System.out.println(3L);
        }
    
        public static class TeePrintStream extends PrintStream {
            private final OutputStream tee;
    
            public TeePrintStream(PrintStream original, OutputStream tee) {
                super(original);
                this.tee = tee;
            }
    
            @Override
            public void write(byte[] b) throws IOException {
                super.write(b);
                tee.write(b);
            }
    
            @Override
            public void write(byte[] buf, int off, int len) {
                super.write(buf, off, len);
                try {
                    tee.write(buf, off, len);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
    
            @Override
            public void write(int b) {
                super.write(b);
                try {
                    tee.write(b);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
    
            @Override
            public synchronized void close() {
                try {
                    tee.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                } finally {
                    super.close();
                }
            }
        }
    }
    

    我这里的 TeePrintStream 是我刚刚拼凑起来的,如果你打算在生产项目中使用它,请完善它并彻底测试它

    【讨论】:

      【解决方案3】:

      Okej 我想我解决了。我主要是这样做的:

      public static void main(String[] args) {
      Prinstream out = new Prinststream(file);
      
      /*   
         Do some things like start threads, call objects etc..
         .
         .
         .
         .
      */
        System.setOut(out);
      

      我认为,当所有线程都启动并执行其操作时(我确实为每个线程分配了一个对象),打印流将捕获其他类中出现的每个控制台输出。 在我编辑我的 stopExecute 类之前,这不起作用。

      public class stopExecute implements Runnable {
        Scanner scan = new Scanner(System.in);    
        private Object[] obj;
      
      public stopExecute(Object[] obj)
      {
          this.obj = obj;
      }
      
      public void run() {
          while(true){
              stop();
          }
      }
      public void stop() {
          if(scan.hasNextLine()){
              System.out.println("Stopped");
              System.exit(0); 
          }
        }
      }
      

      感谢你们的帮助。我会研究你的建议并尝试一下。在这个解决方案中,我无法使用 Log4J。但我一定会去看看的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-26
        • 2021-10-21
        • 2010-09-30
        • 2023-03-27
        • 2017-03-18
        • 2021-06-05
        • 2022-12-04
        相关资源
        最近更新 更多