Decompress the 7Zip special compression algorithm file in the Java Project
1. Problem Description
Java Web backend downloads a zip file compressed by a special algorithm. Because java itself cannot be used to decompress the file, you must use 7Zip to decompress the file. Therefore, this article mentioned the problem of calling external 7zip exe on the java web backend to decompress the file.
2. Implement 2.1 to define the buffer class
class StreamGobbler extends Thread { InputStream is; String type; public StreamGobbler(InputStream is, String type) { this.is = is; this.type = type; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ((line = br.readLine()) != null) { System.out.println(type + ">" + line); } } catch (IOException ioe){ ioe.printStackTrace(); } }}
2.2 execute the external exe process
String [] cmd = {"7za.exe", "x", zipPath, "-o" + outputPath}; Runtime rt = Runtime. getRuntime (); Process proc = rt.exe c (cmd); // listener error message StreamGobbler errorGobbler = new StreamGobbler (proc. getErrorStream (), "ERROR"); // listener output information StreamGobbler outputGobbler = new StreamGobbler (proc. getInputStream (), "OUTPUT"); // start the listener and input errorGobbler. start (); outputGobbler. start (); // make sure that the Runtime.exe c process has been executed. int exitVal = proc. waitFor (); System. out. println ("ExitValue:" + exitVal );
3. Solve the cause of 3.1 Process. waitFor stuck status 3.1.1 when running in tomcat.
Be sure to call Process. before waitFor (), read stdout and stderr of the program. Otherwise, the pipe buffer may be insufficient. The called system commands may be blocked on standard output and standard error output. Windows is more prone to this problem because the default value of this buffer zone is small.
Note that stdout and stderr of the read program are both blocked operations, which means that they must be read separately in two threads, rather than once in one thread. Otherwise, blocking may still occur.
[Http://www.dongliu.net/post/496142]
3.1.2 Other guesses
1. The main process of the program will wait for a certain amount of time for the process, but the time is very short. It may end when the process cannot complete the work. Therefore, the waitFor method needs to be called for a process that takes a long time to work. This method will cause the current Thread to wait until the process is interrupted. [Http://ccchhhlll1988-163-com.iteye.com/blog/4101497]
2. It may be because a process is started in tomcat, but you do not have the permission to kill the process.
4 others
4.1 decompress the library with Java
Java.util.zip
Due to inconsistent algorithms, the system prompts "invalid CEN header (bad compression method)" during decompression )"
4.2 download the 7Zip decompression Library
Download the sevenzipjbinding package from the sourceforge website. The downloaded files are not compressed.
However, the latest decompression algorithm cannot be canceled.
4.3 does tomcat have the permission to call external exe?
4.4 tomcat startup failed
The server can start the project normally, but the local computer cannot start. Message: "org. apache. catalina. LifecycleException: Failed to start component"
After the local tomcat6 test calls an external exe, you can check whether the project is successful in the actual project. The actual project uses tomcat7 and contains the corresponding jdk folder, some modifications were made. For example, you have modified the webapp folder path and deleted unnecessary files;
The final cause is that jdk of a local lower version is used at startup. Set JAVA_HOME to the built-in jdk folder.
5 References
1. waitfor usage in runtime.getruntime.exe c
During program design, the current thread can perform the next operation only after the called system program completes the operation. At this time, the Process-like method waitFor () can be used to implement the operation, it will block the first thread until the program running ends.
2. Call the system command correctly -- set timeout for Process. waitFor and other
Therefore, it is necessary to add timeout control to the code. However, Process. waitFor () does not support timeout settings,
One method is to use the non-blocking Process. exitValue () method, and then round-robin to check the Process status. This method consumes a lot of CPU, so that the polling interval cannot be set too small, which is always not perfect.
In addition, another thread is used to call the program. When timeout is found in the main thread, process. destroy () is called directly to terminate the process.
3. When Runtime.exe c () won't
This section describes why the Runtime function cannot be executed normally.