简体   繁体   English

ProcessBuilder和FileHandler之间的区别

[英]Difference between ProcessBuilder and FileHandler

Can any one please explain difference between ProcessBuilder and FileHandler , which one should be used in which situation. 谁能解释一下ProcessBuilderFileHandler之间的区别,在这种情况下应该使用哪一种。

For example if we want to redirect the output of a command to a text file say " logfile.txt ", ProcessBuilder takes few seconds to get the output to the file. 例如,如果我们要将命令的输出重定向到文本文件“ logfile.txt ”,则ProcessBuilder需要花费几秒钟的时间将输出输出到文件。

What can this FileHandler do in situations like 100 processes has to send their output to same " logfile.txt "? 在100个进程必须将其输出发送到相同的“ logfile.txt ”的情况下,此FileHandler可以做什么?

Is there a way to get output of all the hundred records to same " logfile.txt " without using process.waitFor() method in ProcessBuilder ? 有没有一种方法可以在不使用ProcessBuilder process.waitFor()方法的情况下将所有一百条记录的输出输出到相同的“ logfile.txt ”? This is my code, but if 100 records are scheduled at same time then p.waitfor() method will not help me because it takes few seconds to execute command and get output to logfile for every process and for 100 processes means it will take more time to execute same commands for all the records in DB. 这是我的代码,但是如果同时安排了100条记录,那么p.waitfor()方法将无济于事,因为执行命令并为每个进程和100个进程获取输出到日志文件需要几秒钟的时间,这将花费更多时间是时候对数据库中的所有记录执行相同的命令了。 but my application will start for every minute. 但我的应用程序将每分钟启动一次。 Thats the problem, process.waitFor() helps me in getting exact output but for more number of records means it takes more time. 就是这个问题,process.waitFor()可以帮助我获得准确的输出,但是更多的记录意味着需要更多的时间。 I want another method where it shouldn't wait but all outputs should append synchronously into file. 我想要另一种方法,它不应该等待,但所有输出应同步添加到文件中。

while(rs1.next())
    {
        instance_id = rs1.getString(1);
        startdate = rs1.getString(2);
        starttime = rs1.getString(3);
        endtime = rs1.getString(4);
        enddate = rs1.getString(5);
        if(presentdate.equals(startdate) || presentdate.equals(enddate))
        {
            if(presenttime.equals(starttime))
            {
                String[] s1 = new String[]{"cmd", "/c","ec2-start-instances",instance_id,">>","D:\\logfile.log"};
                ProcessBuilder builder1 = new ProcessBuilder(s1);
                Process p1 = builder1.start();
                p1.waitFor();
            }
            else if(presenttime.equals(endtime))
            {
                String[] s1 = new String[]{"cmd", "/c","ec2-stop-instances",instance_id,">>","D:\\logfile.log"};
                ProcessBuilder builder1 = new ProcessBuilder(s1);
                Process p1 = builder1.start();
                p1.waitFor();
            }
        }
    }

For ProcessBuilder according to documentation: 对于ProcessBuilder根据文档:

Note that this class is not synchronized. 请注意,此类未同步。 If multiple threads access a ProcessBuilder instance concurrently, and at least one of the threads modifies one of the attributes structurally, it must be synchronized externally. 如果多个线程同时访问ProcessBuilder实例,并且至少有一个线程在结构上修改了其中一个属性,则必须在外部对其进行同步。

Example

Process p = new ProcessBuilder("myCommand", "myArg").start(); 进程p = new ProcessBuilder(“ myCommand”,“ myArg”)。start();

From my understanding, ProcessBuilder is used to communicate with other software on the OS. 据我了解, ProcessBuilder用于与OS上的其他软件进行通信。 (Which could be an outside logging script or some form of logging software) (这可能是外部日志记录脚本或某种形式的日志记录软件)


FileHandler is a more of a standard file logging system. FileHandler更像是一个标准的文件记录系统。 However, to avoid the problems from multiple calls, make your logging code static to make sure when it gets called that it finishes it's process. 但是,为了避免多次调用带来的问题,请使您的日志记录代码静态,以确保在调用它时完成处理过程。 FileHandler flushes by default (according to documentation). FileHandler默认情况下刷新(根据文档)。

Hope that helps a little bit 希望能有所帮助

They are two mostly unrelated objects and areas. 它们是两个最不相关的对象和区域。

Yes a Process Builder gives us a standard output and error output stream which can be saved to a file, but it could also be saved to a data base or discarded. 是的,Process Builder为我们提供了标准的输出和错误输出流,可以将其保存到文件中,但也可以保存到数据库中或丢弃。

ava.util.logging.FileHandler on the other hand is an appendar part of the logging system. 另一方面,ava.util.logging.FileHandler是日志记录系统的附加部分。 We generally use logging for our own code, though nothing wrong with logging the output of external processes we have called in there too. 我们通常使用日志记录自己的代码,尽管记录在其中调用的外部流程的输出也没错。

But if other classes log while process is logging then will get mixed up logs. 但是,如果其他类在进程正在记录日志的同时进行日志记录,则将得到混淆的日志。

Similarly if your running 50 processes I suggest you dont log to the same file. 同样,如果您正在运行50个进程,我建议您不要登录到同一文件。 But log to 50 different files - using 50 threads. 但是使用50个线程记录到50个不同的文件。 Each thread would check the eroror and output streams and save when you have a new line or end of that stream. 每个线程都会检查错误和输出流,并在有新行或流的末尾时保存。

When all are done can copy to log file or to a new file as preferred.T 完成所有操作后,可以复制到日志文件或作为首选文件复制到新文件。

Posting your code actually gives much more idea what is going on. 实际上,发布代码可以使您更多地了解发生了什么。 Now I see you are using the windows cmd.exe redirection capabilities instead of reading the outputs from the spawned processes with java and doing something with them. 现在,我看到您正在使用Windows cmd.exe重定向功能,而不是使用java从生成的进程中读取输出并对其进行处理。 If you like any different behavior, you have to: 如果您喜欢任何其他行为,则必须:

  1. if possible execute process without cmd.exe (to avoid buffering from it) - new String[]{"ec2-start-instances",instance_id) 如果可能的话,在没有cmd.exe的情况下执行进程(以避免从中缓冲)- new String[]{"ec2-start-instances",instance_id)
  2. combine process stdout and stderr (easier to catch all output) processBuilder.redirectErrorStream(true) 结合流程stdout和stderr(更容易捕获所有输出) processBuilder.redirectErrorStream(true)
  3. close process stdin (just a precaution) - process.getOutputStream().close() 关闭进程标准输入(只是预防措施) process.getOutputStream().close()
  4. spawn threads to read all concurrent processes output streams 产生线程以读取所有并发进程输出流
  5. have those threads write what they are reading to a file in a thread safe way 让那些线程以线程安全的方式将正在读取的内容写入文件

Now #4 and #5 are not trivial but there is plenty of information in the internet how to achieve. 现在,#4和#5并非无关紧要,但是互联网上有很多信息可以实现。 In Java 7 you have also the option to redirect to file without any code from your part - processBuilder.redirectOutput(File file) , but I think it is not thread safe so your multiple processes wont play well with each other. 在Java 7中,您还可以选择不带任何代码的情况下重定向到文件processBuilder.redirectOutput(File file) ,但是我认为它不是线程安全的,因此您的多个进程不能很好地相互配合。

Here are two questions that give some examples how to achieve #4 and #5: 这是两个问题,提供了一些有关如何实现#4和#5的示例:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM