【问题标题】:Java - Capturing System.err.println or Capturing a PrintStreamJava - 捕获 System.err.println 或捕获 PrintStream
【发布时间】:2010-10-05 04:26:10
【问题描述】:

Java新手问题:

我需要捕获由第 3 方组件写入 printStream 的文本。

PrintStream 默认为 System.err,但可以更改为另一个 PrintStream。

查看文档,我找不到将 PrintStream 的内容定向到字符串写入器/缓冲区的简单方法。

有人可以帮忙吗?

【问题讨论】:

  • 你试过 ByteArrayOutputStream 吗?

标签: java io stream


【解决方案1】:
PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream(pipeOut);
System.setOut(new PrintStream(pipeOut));
// now read from pipeIn

【讨论】:

  • 不建议这样做,文档指出“数据由一个线程写入 PipedOutputStream 对象,数据由其他线程从连接的 PipedInputStream 读取。尝试从单个线程使用这两个对象是不推荐,因为它可能会使线程死锁。” docs.oracle.com/javase/1.4.2/docs/api/java/io/…
【解决方案2】:

您可以围绕任何其他 OutputStream 创建一个 PrintStream。

创建一个进入内存缓冲区的最简单方法是:

PrintStream p = new PrintStream( new ByteArrayOutputStream() )

然后你可以在任何你喜欢的点读取和重置字节数组的内容。

另一种可能是使用管道。

InputStream third_party_output = new PipedInputStream();
PrintStream p = new PrintStream( new PipedOutputStream( third_party_output ) );

然后您可以从third_party_output 流中读取以获取库写入的文本。

【讨论】:

    【解决方案3】:

    你在寻找这样的东西吗?

        OutputStream redirect = System.err;
        PrintStream myPrintStream = new PrintStream(redirect);
        myPrintStream.println("hello redirect");
    

    如果您可以将myPrintStream 传递给第 3 方应用程序,您可以将其重定向到任何您想要的位置。

    【讨论】:

      【解决方案4】:
      import java.io.*;
      
      public class Test {
          public static void main(String[] args) {
              FileOutputStream fos = null;
              try {
                  fos = new FileOutputStream("errors.txt");
              } catch(IOException ioe) {
                  System.err.println("redirection not possible: "+ioe);
                  System.exit(-1);
              }
              PrintStream ps = new PrintStream(fos);
              System.setErr(ps);
              System.err.println("goes into file");
          }
      }
      

      【讨论】:

        【解决方案5】:

        我使用以下类将 System.out 和 System.err 记录到一组循环文件(其中 xxx-001.log 是最新的)。它包含一些对实用程序方法的调用,您需要在它编译之前实现它们 - 它们应该是不言自明的。

        import java.io.*;
        import java.lang.reflect.*;
        
        public class LoggerOutputStream
        extends OutputStream
        {
        
        // *****************************************************************************
        // INSTANCE PROPERTIES
        // *****************************************************************************
        
        private FileOutputStream                log=null;                               // the base output stream
        private String                          fnmBase,fnmExt;                         // filename base, file extension
        private int                             fnmCount,fnmLast;                       // count for filename index, last filename used
        private int                             logSize,totWritten;                     // max log size, current number of bytes written
        
        // *****************************************************************************
        // INSTANCE CONSTRUCTORS/INIT/CLOSE/FINALIZE
        // *****************************************************************************
        
        public LoggerOutputStream(String baseFilename) throws IOException {
            this(baseFilename,".log",2,1024000);
            }
        
        public LoggerOutputStream(String baseFilename, String extension) throws IOException {
            this(baseFilename,extension,2,1024000);
            }
        
        public LoggerOutputStream(String baseFilename, String extension, int numberOfFiles, int maxFileSize) throws IOException {
            fnmBase=baseFilename;
            if(Character.isLetterOrDigit(fnmBase.charAt(fnmBase.length()-1))) { fnmBase=(fnmBase+"-"); }
            fnmExt=extension;
            if(!fnmExt.startsWith(".")) { fnmExt=('.'+fnmExt); }
            fnmCount=numberOfFiles;
            logSize=maxFileSize;
            if(fnmCount>MAXLOGS) { fnmCount=MAXLOGS; }
        
            fnmLast=0;
            for(int xa=1; xa<=MAXLOGS; xa++) {
                if(!new File(constructFilename(xa)).exists()) {
                    while((--xa)>fnmCount) { IoUtil.deleteFile(constructFilename(xa)); }
                    fnmLast=xa;
                    break;
                    }
                }
            log=null;
        
            openFile(false);
        
            if(numberOfFiles>MAXLOGS) { System.out.println("** Log File Count Limited To "+MAXLOGS); }
            }
        
        public void close() throws IOException {
            close(false);
            }
        
        private void openFile(boolean ovrflw) throws IOException {
            close(true);
        
            if     (fnmLast< fnmCount) { fnmLast++;                                      }
            else if(fnmLast==fnmCount) { IoUtil.deleteFile(constructFilename(fnmCount)); }
            for(int xa=fnmLast; xa>0; xa--) { IoUtil.renameFile(constructFilename(xa-1),constructFilename(xa)); }
            log=new FileOutputStream(constructFilename(1));
            totWritten=0;
            }
        
        private String constructFilename(int index) {
            return constructFilename(fnmBase,index,fnmExt);
            }
        
        private synchronized void close(boolean ovrflw) throws IOException {
            if(log!=null) {
                log.flush();
                log.close();
                log=null;
                }
            }
        
        // *****************************************************************************
        // INSTANCE METHODS - ACCESSORS
        // *****************************************************************************
        
        public String getFilename() {
            return constructFilename(1);
            }
        
        public String getFilename(int idx) {
            return constructFilename(idx);
            }
        
        public synchronized void cycleLogFile() throws IOException {
            openFile(true);
            }
        
        // *****************************************************************************
        // INSTANCE METHODS
        // *****************************************************************************
        
        public synchronized void flush() throws IOException {
            if(log!=null) {
                log.flush();
                }
            }
        
        public synchronized void write(int val) throws IOException {
            if(log!=null) {
                log.write(val);
                totWritten++;
                if(val=='\n') {
                    if(totWritten>logSize) { openFile(true); }
                    else                   { log.flush();    }
                    }
                }
            }
        
        public synchronized void write(byte[] bytes) throws IOException {
            if(log!=null) {
                log.write(bytes);
                totWritten+=bytes.length;
                if(bytes.length>0 && bytes[bytes.length-1]=='\n') {
                    if(totWritten>logSize) { openFile(true); }
                    else                   { log.flush();    }
                    }
                }
            }
        
        public synchronized void write(byte[] bytes, int str, int len) throws IOException {
            if(log!=null) {
                log.write(bytes,str,len);
                totWritten+=len;
                if(bytes.length>(str+len-1) && bytes[str+len-1]=='\n') {
                    if(totWritten>logSize) { openFile(true); }
                    else                   { log.flush();    }
                    }
                }
            }
        
        // *****************************************************************************
        // STATIC PROPERTIES
        // *****************************************************************************
        
        static public final int                 MAXLOGS=999;                            // maximum log files allowed
        
        // *****************************************************************************
        // STATIC METHODS
        // *****************************************************************************
        
        static public String constructFilename(String bas, int idx, String ext) {
            if(!bas.endsWith("-") && !bas.endsWith("_") && !bas.endsWith(".")) { bas=(bas+"-"); }
            if(!ext.startsWith(".")                                          ) { ext=('.'+ext); }
            return (bas+TextUtil.raZeros(idx,3)+ext);
            }
        
        } /* END PUBLIC CLASS */
        

        【讨论】:

          猜你喜欢
          • 2019-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-08
          • 2017-03-06
          • 2012-06-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多