Hướng dẫn nén và giải nén trong Java
1. Đọc ghi file zip sử dụng java.util.zip
Để xử lý các công việc liên quan tới nén và giải nén, JDK cung cấp cho bạn package java.util.zip với một số class để làm việc này.
Đáng tiếc là thư viện này không thể đọc và giải nén các định dạng phổ biến khác như rar, hoặc 7zip. Để giải sử lý các định dạng rar, 7zip, .. bạn cần có một thư viện khác. Trong tài liệu này tôi có để cập tới các thư viện để làm việc này.
Đáng tiếc là thư viện này không thể đọc và giải nén các định dạng phổ biến khác như rar, hoặc 7zip. Để giải sử lý các định dạng rar, 7zip, .. bạn cần có một thư viện khác. Trong tài liệu này tôi có để cập tới các thư viện để làm việc này.
Đây là hình ảnh một file zip được mở bằng công cụ Winrar.
java.util.zip coi các file trong file zip là các ZipEntry.
ListZipEntriesDemo.java
package org.o7planning.tutorial.javaiozip;
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ListZipEntriesDemo {
public static void main(String[] args) {
String FILE_PATH = "C:/test/datas.zip";
ZipInputStream zipIs = null;
try {
// Tạo đối tượng ZipInputStream để đọc file zip.
zipIs = new ZipInputStream(new FileInputStream(FILE_PATH));
ZipEntry entry = null;
// Duyệt từng Entry (Từ trên xuống dưới cho tới hết)
while ((entry = zipIs.getNextEntry()) != null) {
if (entry.isDirectory()) {
System.out.print("Directory: ");
} else {
System.out.print("File: ");
}
System.out.println(entry.getName());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
zipIs.close();
} catch (Exception e) {
}
}
}
}
Kết quả chạy ví dụ:
Ví dụ giải nén file zip vào một thư mục nào đó:
UnZipDemo.java
package org.o7planning.tutorial.javaiozip;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnZipDemo {
public static void main(String[] args) {
final String OUTPUT_FOLDER = "C:/output";
String FILE_PATH = "C:/test/datas.zip";
// Tạo thư mục Output nếu nó không tồn tại.
File folder = new File(OUTPUT_FOLDER);
if (!folder.exists()) {
folder.mkdirs();
}
// Tạo một buffer (Bộ đệm).
byte[] buffer = new byte[1024];
ZipInputStream zipIs = null;
try {
// Tạo đối tượng ZipInputStream để đọc file từ 1 đường dẫn (path).
zipIs = new ZipInputStream(new FileInputStream(FILE_PATH));
ZipEntry entry = null;
// Duyệt từng Entry (Từ trên xuống dưới cho tới hết)
while ((entry = zipIs.getNextEntry()) != null) {
String entryName = entry.getName();
String outFileName = OUTPUT_FOLDER + File.separator + entryName;
System.out.println("Unzip: " + outFileName);
if (entry.isDirectory()) {
// Tạo các thư mục.
new File(outFileName).mkdirs();
} else {
// Tạo một Stream để ghi dữ liệu vào file.
FileOutputStream fos = new FileOutputStream(outFileName);
int len;
// Đọc dữ liệu trên Entry hiện tại.
while ((len = zipIs.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
zipIs.close();
} catch (Exception e) {
}
}
}
}
Kết quả chạy ví dụ:
Nén thư mục
ZipDirectory.java
package org.o7planning.tutorial.javaiozip;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipDirectory {
public ZipDirectory() {
}
// Phương thức dùng để nén một thư mục.
public void zipDirectory(File inputDir, File outputZipFile) {
// Tạo thư mục cha cho file đầu ra (output file).
outputZipFile.getParentFile().mkdirs();
String inputDirPath = inputDir.getAbsolutePath();
byte[] buffer = new byte[1024];
FileOutputStream fileOs = null;
ZipOutputStream zipOs = null;
try {
List<File> allFiles = this.listChildFiles(inputDir);
// Tạo đối tượng ZipOutputStream để ghi file zip.
fileOs = new FileOutputStream(outputZipFile);
//
zipOs = new ZipOutputStream(fileOs);
for (File file : allFiles) {
String filePath = file.getAbsolutePath();
System.out.println("Zipping " + filePath);
// entryName: is a relative path.
String entryName = filePath.substring(inputDirPath.length() + 1);
ZipEntry ze = new ZipEntry(entryName);
// Thêm entry vào file zip.
zipOs.putNextEntry(ze);
// Đọc dữ liệu của file và ghi vào ZipOutputStream.
FileInputStream fileIs = new FileInputStream(filePath);
int len;
while ((len = fileIs.read(buffer)) > 0) {
zipOs.write(buffer, 0, len);
}
fileIs.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
closeQuite(zipOs);
closeQuite(fileOs);
}
}
private void closeQuite(OutputStream out) {
try {
out.close();
} catch (Exception e) {
}
}
// Phương thức này trả về danh sách các file,
// bao gồm tất cả các file con, cháu,.. của thư mục đầu vào.
private List<File> listChildFiles(File dir) throws IOException {
List<File> allFiles = new ArrayList<File>();
File[] childFiles = dir.listFiles();
for (File file : childFiles) {
if (file.isFile()) {
allFiles.add(file);
} else {
List<File> files = this.listChildFiles(file);
allFiles.addAll(files);
}
}
return allFiles;
}
public static void main(String[] args) {
ZipDirectory zipDir = new ZipDirectory();
File inputDir = new File("C:/datas");
File outputZipFile = new File("C:/output/datas.zip");
zipDir.zipDirectory(inputDir, outputZipFile);
}
}
Kết quả chạy ví dụ:
2. Đọc ghi file jar sử dụng java.util.jar
Về cơ bản việc đọc ghi file jar không có gì khác biệt so với file Zip.
- JarInputStream mở rộng từ ZipInputStream hỗ trợ thêm tính năng đọc các thông tin MANIFEST.
- JarOutputStream mở rộng từ ZipOutputStream hỗ trợ thêm tính năng ghi thông tin MANIFEST.
Các file thư viện jar thông thường của java thường có thông tin MANIFEST rất đơn giản.
Ví dụ đây là một file MANIFEST.MF đóng gói trong file jar của 1 ứng dụng RAP có nhiều thông tin hơn:
Ví dụ đây là một file MANIFEST.MF đóng gói trong file jar của 1 ứng dụng RAP có nhiều thông tin hơn:
META-INF/MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: RAPWorkbenchTutorial
Bundle-SymbolicName: RAPWorkbenchTutorial;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: rapworkbenchtutorial.Activator
Require-Bundle: org.eclipse.rap.ui;bundle-version="2.3.0",
org.apache.felix.gogo.command;bundle-version="0.10.0",
org.apache.felix.gogo.runtime;bundle-version="0.10.0",
org.apache.felix.gogo.shell;bundle-version="0.10.0",
org.eclipse.equinox.console;bundle-version="1.1.0",
org.eclipse.equinox.http.jetty;bundle-version="3.0.200",
org.eclipse.equinox.ds;bundle-version="1.4.200",
org.eclipse.rap.rwt.osgi;bundle-version="2.3.0",
org.eclipse.rap.design.example;bundle-version="2.3.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Ví dụ một file jar mở với Winrar:
Các thực thể trong file jar được coi là các JarEntry.
Một ví dụ đơn giản đọc thông tin MANIFEST của file jar. Dưới đây là hình ảnh nội dung của một file Manifest đơn giản.
ReadJarFileDemo.java
package org.o7planning.tutorial.jar;
import java.io.FileInputStream;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
public class ReadJarFileDemo {
public static void main(String[] args) {
String FILE_PATH = "C:/DevPrograms/Java/jdk1.7.0_45/lib/dt.jar";
JarInputStream zipIs = null;
try {
// Tạo đối tượng JarInputStream để đọc file jar.
zipIs = new JarInputStream(new FileInputStream(FILE_PATH));
// Đọc thông tin Manifest:
Manifest manifest = zipIs.getManifest();
Attributes atts = manifest.getMainAttributes();
String version = atts.getValue("Manifest-Version");
String createdBy = atts.getValue("Created-By");
System.out.println("Manifest-Version:" + version);
System.out.println("Created-By:" + createdBy);
System.out.println("========================");
JarEntry entry = null;
// Duyệt từng Entry (Từ trên xuống dưới cho tới hết)
while ((entry = zipIs.getNextJarEntry()) != null) {
if (entry.isDirectory()) {
System.out.print("Folder: ");
} else {
System.out.print("File: ");
}
System.out.println(entry.getName());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
zipIs.close();
} catch (Exception e) {
}
}
}
}
Kết quả chạy ví dụ:
3. Xử lý file RAR
Để xử lý file RAR bạn cần một thư viện mã nguồn mở. Bạn có thể sử dụng một trong các thư viện sau, được đánh giá tốt theo thứ tự giảm dần.
Trong tài liệu này tôi sẽ hướng dẫn bạn sử dụng JUnRar (Phiên bản tại thời điểm 9-2014 đang là 0.7)
Download junrar:
Java cơ bản
- Tùy biến trình biên dịch java xử lý Annotation của bạn (Annotation Processing Tool)
- Lập trình Java theo nhóm sử dụng Eclipse và SVN
- Hướng dẫn và ví dụ Java WeakReference
- Hướng dẫn và ví dụ Java PhantomReference
- Hướng dẫn nén và giải nén trong Java
- Cấu hình Eclipse để sử dụng JDK thay vì JRE
- Phương thức String.format() và printf() trong Java
- Cú pháp và các tính năng mới trong Java 5
- Cú pháp và các tính năng mới trong Java 8
- Hướng dẫn sử dụng biểu thức chính quy trong Java
- Hướng dẫn lập trình đa luồng trong Java - Java Multithreading
- Thư viện điều khiển các loại cơ sở dữ liệu khác nhau trong Java
- Hướng dẫn sử dụng Java JDBC kết nối cơ sở dữ liệu
- Lấy các giá trị của các cột tự động tăng khi Insert một bản ghi sử dụng JDBC
- Hướng dẫn và ví dụ Java Stream
- Functional Interface trong Java
- Giới thiệu về Raspberry Pi
- Hướng dẫn và ví dụ Java Predicate
- Abstract class và Interface trong Java
- Access modifier trong Java
- Hướng dẫn và ví dụ Java Enum
- Hướng dẫn và ví dụ Java Annotation
- So sánh và sắp xếp trong Java
- Hướng dẫn và ví dụ Java String, StringBuffer và StringBuilder
- Hướng dẫn xử lý ngoại lệ trong Java - Java Exception Handling
- Hướng dẫn và ví dụ Java Generics
- Thao tác với tập tin và thư mục trong Java
- Hướng dẫn và ví dụ Java BiPredicate
- Hướng dẫn và ví dụ Java Consumer
- Hướng dẫn và ví dụ Java BiConsumer
- Bắt đầu với Java cần những gì?
- Lịch sử của Java và sự khác biệt giữa Oracle JDK và OpenJDK
- Cài đặt Java trên Windows
- Cài đặt Java trên Ubuntu
- Cài đặt OpenJDK trên Ubuntu
- Cài đặt Eclipse
- Cài đặt Eclipse trên Ubuntu
- Học nhanh Java cho người mới bắt đầu
- Lịch sử của bit và byte trong khoa học máy tính
- Các kiểu dữ liệu trong Java
- Các toán tử Bitwise
- Câu lệnh rẽ nhánh (if else) trong Java
- Câu lệnh rẽ nhánh switch trong Java
- Vòng lặp trong Java
- Mảng (Array) trong Java
- JDK Javadoc định dạng CHM
- Thừa kế và đa hình trong Java
- Hướng dẫn và ví dụ Java Function
- Hướng dẫn và ví dụ Java BiFunction
- Ví dụ về Java encoding và decoding sử dụng Apache Base64
- Hướng dẫn và ví dụ Java Reflection
- Hướng dẫn gọi phương thức từ xa với Java RMI
- Hướng dẫn lập trình Java Socket
- Các nền tảng nào bạn nên chọn để lập trình ứng dụng Java Desktop?
- Hướng dẫn và ví dụ Java Commons IO
- Hướng dẫn và ví dụ Java Commons Email
- Hướng dẫn và ví dụ Java Commons Logging
- Tìm hiểu về Java System.identityHashCode, Object.hashCode và Object.equals
- Hướng dẫn và ví dụ Java SoftReference
- Hướng dẫn và ví dụ Java Supplier
- Lập trình Java hướng khía cạnh với AspectJ (AOP)
Show More
- Hướng dẫn lập trình Java Servlet/JSP
- Các hướng dẫn Java Collections Framework
- Java API cho HTML & XML
- Các hướng dẫn Java IO
- Các hướng dẫn Java Date Time
- Các hướng dẫn Spring Boot
- Các hướng dẫn Maven
- Các hướng dẫn Gradle
- Các hướng dẫn Java Web Services
- Các hướng dẫn lập trình Java SWT
- Các hướng dẫn lập trình JavaFX
- Các hướng dẫn Java Oracle ADF
- Các hướng dẫn Struts2 Framework
- Các hướng dẫn Spring Cloud