1
z
2
BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI - CS 2
----------
BÀI TẬP LỚN MÔN
CÔNG NGHỆ JAVA
Đề Tài : PHẦN MỀM NÉN VÀ GIẢI NÉN
Lớp : CÔNG NGHỆ THÔNG TIN – K54
Giảng viên hướng dẫn: KS. LÊ NHẬT TÙNG
Hồ Chí Minh, 5/2015
3
4
z
5
BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI - CS 2
----------
BÀI TẬP LỚN MÔN
CÔNG NGHỆ JAVA
Đề Tài : PHẦN MỀM NÉN VÀ GIẢI NÉN
Lớp : CÔNG NGHỆ THÔNG TIN – K54
Giảng viên hướng dẫn: KS. LÊ NHẬT TÙNG
Hồ Chí Minh, 5/2015
6
LỜI MỞ ĐẦU
Công nghệ thông tin ngày càng có vai trò quan trọng trong trong cuộc sống
hằng ngày của chúng ta.Việc ứng dụng CNTT vào các lĩnh vực trong đời sống giúp
công việc được tiến hành nhanh chóng và hiệu quả hơn.Ngày nay nhu cầu trao đổi
thông tin qua mạng rất phổ biến nhưng việc trao đổi dữ liệu có kích thước lớn rất khó
khăn, đòi hỏi phải có phương pháp hỗ trợ để việc trao đổi trở nên thuật tiện hơn.
Từ nhu cầu trên, chúng em sử dụng vốn kiến thức đã học từ thầy cô, bạn bè và
sự tìm hiểu của bản thân mỗi cá nhân trong nhóm để đi tới việc tạo phần mềm
“ Nén Và Giải Nén File’’. Mục đích cơ bản là nén tập tin lại sao cho thuận tiện cho
việc trao đổi cũng như lưu trữ, ngoài ra chương trình còn có một mục con nữa là cắt và
nối file. Ngày nay, không chỉ có nén file có thể giúp cho quá trình trao đổi thuận tiện
mà cắt và nối file cũng góp phần không nhỏ vào quá trình đó. Đối với một tập tin lớn
thì việc chia nhỏ chúng ra rồi nén lại và thực hiện quá trình trao đổi vận chuyển trở
nên dễ dàng hơn nhiều. Đó cũng chính là mục tiêu cuối cùng mà phần mềm này muốn
hớng tới. Trải qua các công đoạn thì phần mềm đã được xây dựng xong và được đúc
kết lại trong bài báo cáo này. Phần mềm chỉ mang tính chất thử nghiệm để học hỏi ,
trao đổi kinh nghiệm.
Đề tài gồm các chương:
Chương I: TỔNG QUAN ĐỀ TÀI
Chương II : CHƯƠNG TRÌNH
Tuy đã rất cố gắng học hỏi dựa trên kiến thức đã học nhưng phần mềm vẫn
không thể tránh khỏi những sai sót. Kính mong quý thấy cô cùng bạn bè thông cảm và
góp ý để nhóm kịp thời lấp kín những lỗ hỏng kiến thức và phần mềm đạt hiệu quả
cao hơn.
TP.HCM,tháng 5/2015
Nhóm thực hiện
7
Mục Lục
8
CHƯƠNG I:
TỔNG QUAN ĐỀ TÀI
1. Nhiệm vụ của đề tài:
• Tìm hiểu cơ cấu nén và giải nén tập tin bằng thư viện java.util.zip
• Tìm hiểu cơ cấu cắt và nối tập tin
• Hiện thực hoá code.
2. Mục tiêu và yêu cầu của đề tài:
• Một phần mềm nén và giải nén cần các chức năng cơ bản sau:
o Đối với nén file:
Cho phép tạo mới lại chương trình qua thao tác new.
Thêm tập tin vào danh sách các tập tin để nén.
Xoá khỏi danh sách tập tin không muốn nén
Phải nén được các tập tin yêu cầu và dung lượng có thể
nhỏ hơn hoặc bằng dung lượng của tập tin gốc.
Giao diện rõ ràng dễ sử dụng.
Có hướng dẫn cụ thể.
Thông báo khi hoàn tất.
o Đối với giải nén:
Cho phép tạo mới lại chương trình qua thao tác new.
Thêm tập tin vào danh sách muốn giải nén.
Giải nén ra đầy đủ các file
Yêu cầu phải là file có đuôi .zip vì chương trình chỉ hỗ trợ
tập tin có đuôi .zip
Giao diện rõ ràng.
Có hướng dẫn cụ thể.
Thông báo khi hoàn tất chương trình.
• Một phần mềm cắt nối file cần có các chức năng sau:
o Đối với cắt:
Cho phép tạo mới chương trình qua thao tác new.
Giao diện rõ ràng dễ sử dụng.
Cắt được tất cả các file có dung lượng lớn và nhỏ.
Được phép chọn thể loại cắt như: cắt theo số phần hoặc
dung lượng.
Có hướng dẫn cụ thể.
Thông báo khi hoàn tất chương trình.
o Đối với nối:
Cho phép tạo mới.
Giao diện rỗ ràng.
Nối các file đc đánh dấu bằng số 1 đầu tiên.
Tự động tìm và nối các part tiếp theo cho tới khi hoàn tất.
Trả lại dung lượng bằng đúng dung lượng của file gốc.
Không bị hư hỏng.
Có hướng dẫn cụ thể.
9
CHƯƠNG II:
CHƯƠNG TRÌNH
I.
1.
a)
•
•
•
CƠ SỞ LÝ THUYẾT.
Cơ chế nén và giải nén tập tin Zip.
Cơ sở nén tập tin.
Về bản chất thì File nén là khá phức tạp và khó hiểu, là kết quả của khá nhiều
công đoạn được sáng chế bởi những con người rất thông minh. Zip sử dụng cơ
chế Lossless để sử lý các vấn đề về nén và giải nén.
Về cơ bản, kiểu nén Lossless sẽ dùng thuật toán đơn giản các phần dữ liệu dư
thừa, không cần thiết và không làm mất dữ liệu. Để dễ hình dung hơn, bạn có
thể tưởng tượng chồng gạch xếp hình dưới đây đại diện cho một dữ liệu đầy đủ.
Bạn có thể thấy ở đây chúng ta có hai khối gạch màu đỏ, năm cái màu vàng và
ba màu xanh. Các viên gạch cùng màu đại diện cho các phần dữ liệu giống nhau
và lặp lại. Tuy nhiên đó không phải cách thức duy nhất để đại diện cho dữ liệu,
có thể thay đổi chúng như hình dưới.
10
• Trong hình này, bạn chỉ cần một thuật toán chú thích và ba khối gạch để đại diện
cho 10 khối gạch ở trên. Bạn vẫn có đầy đủ thông tin về các loại gạch bao gồm
màu đỏ, vàng và xanh và số lượng của chúng. Trong khi không gian đã được
giảm đi đáng kể. Ví dụ đơn giản này cho bạn một khái niệm cơ bản về kiểu nén
Lossless, các thông tin giống nhau được thay thế bằng một thông tin đại diện và
thuật toán cho biết số lượng của chúng.
• Một ví dụ đơn giản khác: bạn có một đoạn dữ liệu như sau
"fffffffuuuuuuuuuuuucc" và sau khi nén kiểu Lossless nó sẽ thành "f7u12c2".
• Tuy nhiên có rất nhiều dạng nén Lossless được sử dụng các thuật toán khác nhau,
trên đây chỉ là một dạng đơn giản trong số đó. Nhưng về bản chất, các dữ liệu
11
sau khi được nén đều có thể tái tạo lại toàn bộ như dữ liệu ban đầu sau khi giải
nén, không có mất mát và thay đổi gì.
• Các phần mềm như WinZip đều dựa trên kiểu nén Lossless này, các file dữ liệu
sau khi bị nén sẽ có dung lượng nhỏ hơn, tuy nhiên sau khi giải nén dữ liệu sẽ
được khôi phục lại như ban đầu, không có phần dữ liệu nào bị mất đi. Trong các
file hình ảnh, PNG cũng là một định dạng được nén theo kiểu Lossless.
b) Trong java.
• Java hỗ trợ nén file thông qua thư viện java.util.zip và java.util.jar
• Đá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, .. cần có một thư viện
khác.
• Sơ đồ
• Java.util.zip coi các file trong file zip là các ZipEntry.
datas.zip
Document.docx
Java.docx
Data.docx
Untulyty.png
Readme.txt
ZipEntry
12
2. Hiện thực hoá code.
a) Thuật toán :
• Đối với nén :
Input : đường dẫn đến thư mục, đường dẫn lưu thư mục
Output : file đã được nén.
o Bước 1 : Nhập đường dẫn thư mục hoặc tập tin để nén, đường dẫn lưu
file nén.
o Bước 2 : Tạo thư mục cha cho file output
outputZipFile.getParentFile().mkdirs();
o Bước 3: Lấy tất cả danh sách các thư mục con trong thư mục vừa chọn
nếu nó là thư mục List<File> allFiles = this.listChildFiles(inputDir);
o Bước 4: Tạo đường dẫn và đẩy vào ZipEntry. ZipEntry ze = new
ZipEntry(entryName);
o Bước 5 : Đọc dữ liệu file cần zip và ghi vào luồng zip.
o Bước 6: Ghi dữ liệu đọc được xuống luồng ZipOutputStream cho đến
khi số byte đọc được < 0.
o Bước 7: Đóng file.
• Đối với giải nén:
o Bước 1: Tạo bộ lọc luồng vào ZipInputStream từ FileInputStream và
đường dẫn file nén.
ZipInputStream zis = new ZipInputStream(new
FileInputStream(filepath));
o Bước 2: Tạo ZipEntry gắn với đối tượng của ZipInputStream.
ZipEntry ze = zis.getNextEntry();
o Bước 3: Tạo file mới từ đường dẫn, tên file lấy từ ZipEntry và dòng
output từ file.
String fileName = ze.getName();
File newFile = new File(filedest1 + File.separator + fileName);
new File(newFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newFile);
o Bước 4: Đọc dữ liệu từ dòng zis và ghi xuống dòng ra fos.write(buffer,
0, len);
o Bước 5: len < 0 dừng việc ghi, đẩy ze lên đối tượng tiếp theo ze =
zis.getNextEntry();
o Bước 6: ze != null dừng việc ghi và đóng file.
• Đối với cắt file:
o Bước 1: Nhập đường dẫn file đích, đường dẫn lưu file và số phần hoặc
dung lượng.
o Bước 2: Lấy kích thước của tập tin int sizeOfFile = (int) fS.length();
o Bước 3: Nếu check_Part true, tính số lượng file cắt bằng sizeOfFileCut =
(sizeOfFile / sizeSplit);
Ngược lại, nếu false thì check_data đc nhấn, tính kích cỡ dung lượng cần
cắt: int MB_File = sizeOfFile / (1024 * 1024);
sizeOfFileCut = MB * 1024 *1024;
13
o Bước 4: Gán số byte ban đầu bằng số phần hoặc số MB cần cắt để bắt
đầu việc đọc ghi: int byteRemainder = sizeSplit;
o Bước 5: Đọc toàn bộ thông tin từ file lên bộ đệm, gán bằng byteRead
byteRead = bis.read(bytes)
o Bước 6: Ghi xuống bộ đệm dích bos.write(bytes, 0, byteRead); giảm số
phần đọc xuống bằng cách trừ đi số byte thực đọc byteRemainder - =
byteRead;
o Bước 7: Lặp lại bước 6 cho tới khi byteRemainder < 0 thoát và đóng file.
• Đối với nối file:
o Bước 1: Nhập đường dẫn file nguồn, file đích.
o Bước 2: Nếu file có tồn tại, bắt đầu lặp.
o Bước 3: Nếu số byte đọc đc khác -1 thì ghi xuống bộ đệm gắn với file
đầu ra, tăng chỉ số đếm file lên 1
o Bước 4: nếu file kế tiếp k tồn tại, dừng việc đọc, đóng file, kết thúc.
b) Mã hoá
• Nén file
o Hàm chính:
14
15
o Hàm phụ: đóng file
o Hàm phụ: load tất cả các file con trong thư mục cha.
• Đối với giải nén:
o Hàm chính:
16
• Xử lý sự kiện:
17
18
• Hàm main:
• Đối với cắt file:
o Hàm chính:
19
• Đối với nối:
20
• Xử lý sự kiện:
21
22
23
3. Demo:
24
25