技术咨询:如何用Java Spring MVC解压.rar及Java解压各类归档文件
Hey there! Let's break down how to handle unzipping various archive files (like .zip and .rar) in Java, plus how to integrate RAR extraction into a Spring MVC app. I've got you covered with practical code snippets and explanations below.
一、Java原生实现Zip文件解压
Zip files are natively supported in Java, so this part is straightforward. We'll use java.util.zip classes, and leverage try-with-resources to ensure we don't leave any open streams hanging around:
import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public class ZipExtractor { public static void extractZip(String zipFilePath, String destinationDir) throws IOException { // Create destination directory if it doesn't exist File destDir = new File(destinationDir); if (!destDir.exists()) { destDir.mkdirs(); } // Use try-with-resources to auto-close ZipFile try (ZipFile zipFile = new ZipFile(zipFilePath)) { zipFile.stream().forEach(entry -> { try { extractZipEntry(entry, zipFile, destDir); } catch (IOException e) { throw new RuntimeException("Failed to extract entry: " + entry.getName(), e); } }); } } private static void extractZipEntry(ZipEntry entry, ZipFile zipFile, File destDir) throws IOException { File entryFile = new File(destDir, entry.getName()); // If entry is a directory, create it if (entry.isDirectory()) { entryFile.mkdirs(); return; } // Create parent directories for the file File parentDir = entryFile.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } // Read entry content and write to file try (InputStream in = zipFile.getInputStream(entry); OutputStream out = new FileOutputStream(entryFile)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } } }
二、处理RAR文件:依赖第三方库
Java doesn't have native support for RAR files, so we'll need to use a third-party library. Two popular options are Junrar and Apache Commons Compress.
方式1:使用Junrar库
Junrar is a lightweight library specifically for RAR files. First, add the Maven dependency to your pom.xml:
<dependency> <groupId>com.github.junrar</groupId> <artifactId>junrar</artifactId> <version>0.7</version> </dependency>
Then, here's a practical extraction implementation:
import com.github.junrar.Archive; import com.github.junrar.exception.RarException; import com.github.junrar.rarfile.FileHeader; import java.io.*; public class RarExtractor { public static void extractRar(String rarFilePath, String destinationDir) throws IOException, RarException { File destDir = new File(destinationDir); if (!destDir.exists()) { destDir.mkdirs(); } try (Archive archive = new Archive(new FileInputStream(rarFilePath))) { FileHeader header; while ((header = archive.nextFileHeader()) != null) { // Skip directories (Junrar handles them automatically when extracting files) if (header.isDirectory()) { continue; } File entryFile = new File(destDir, header.getFileNameString().trim()); File parentDir = entryFile.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } try (OutputStream out = new FileOutputStream(entryFile)) { archive.extractFile(header, out); } } } } }
方式2:使用Apache Commons Compress
Apache Commons Compress supports a wide range of archive formats, including RAR. Add this dependency to your pom.xml:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.24.0</version> </dependency>
Then implement extraction like this:
import org.apache.commons.compress.archivers.rar.RARArchiveEntry; import org.apache.commons.compress.archivers.rar.RARArchiveInputStream; import java.io.*; public class CommonsCompressRarExtractor { public static void extractRar(String rarFilePath, String destinationDir) throws IOException { File destDir = new File(destinationDir); if (!destDir.exists()) { destDir.mkdirs(); } try (RARArchiveInputStream rarIn = new RARArchiveInputStream(new FileInputStream(rarFilePath))) { RARArchiveEntry entry; while ((entry = rarIn.getNextRAREntry()) != null) { if (entry.isDirectory()) { new File(destDir, entry.getName()).mkdirs(); continue; } File entryFile = new File(destDir, entry.getName()); File parentDir = entryFile.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } try (OutputStream out = new FileOutputStream(entryFile)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = rarIn.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } } } } }
三、Spring MVC中实现RAR文件解压处理
If you're building a Spring MVC app and need to handle RAR file uploads + extraction, here's a step-by-step implementation:
1. Configure File Upload Settings
First, set up file upload limits in your application.properties (or application.yml):
# File upload configuration spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB
2. Create a Controller to Handle Uploads
This controller will accept a uploaded RAR file, validate it, and trigger extraction:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import com.github.junrar.exception.RarException; @RestController public class RarExtractionController { // Define a temporary directory for extraction (adjust this to your needs) private static final String EXTRACT_DIR = "./extracted-files/"; @PostMapping("/extract-rar") public ResponseEntity<String> extractRarFile(@RequestParam("rarFile") MultipartFile rarFile) { // Validate the uploaded file if (rarFile.isEmpty()) { return new ResponseEntity<>("Please upload a non-empty RAR file", HttpStatus.BAD_REQUEST); } String fileName = rarFile.getOriginalFilename(); if (fileName == null || !fileName.toLowerCase().endsWith(".rar")) { return new ResponseEntity<>("Uploaded file is not a RAR archive", HttpStatus.BAD_REQUEST); } try { // Save the uploaded file temporarily (or process it directly without saving) File tempRarFile = new File(System.getProperty("java.io.tmpdir") + "/" + fileName); rarFile.transferTo(tempRarFile); // Extract the RAR file RarExtractor.extractRar(tempRarFile.getAbsolutePath(), EXTRACT_DIR); // Clean up the temporary file (optional, but good practice) tempRarFile.delete(); return new ResponseEntity<>("RAR file extracted successfully to: " + EXTRACT_DIR, HttpStatus.OK); } catch (IOException | RarException e) { return new ResponseEntity<>("Extraction failed: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } }
3. Reuse the Extraction Utility Class
Just use the RarExtractor class we wrote earlier (or the Commons Compress version) to keep your controller clean and focused on handling HTTP requests.
4. Handle Edge Cases
Don't forget to:
- Validate file types and sizes to prevent malicious uploads
- Handle exceptions gracefully (e.g., corrupted RAR files, permission issues)
- Clean up temporary files after extraction to avoid disk bloat
内容的提问来源于stack exchange,提问作者Naveen

