這裡可以下載。
code中有註解說明了,要注意兩點:
- 其中有用到權限:
會用到sd卡。<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- 我們實做時是把資料從Assets資料夾中抓出來的,如果需要實做從各個不同的地方獲取資料,建議把資料複製一份至同一個資料夾中再進行壓縮等動作。
- 基本上顯示的文字沒有什麼作用,大概就是告訴我們資料夾位置在哪裡。
- File的處理很討厭,要特別注意資料夾有沒有建立以及stream有沒有關閉。
我們這個類別進行的動作是這樣的:
- 將準備好的壓縮檔案從Assests資料夾複製到SD卡的ZipTest資料夾,並且以目前時間作為命名。
- 將
ZipTest資料夾的壓縮檔解壓縮,存在ZipTestUnZip的kulipaFile資料夾中。
假裝目前我們已經將檔案都複製到了同一個資料夾。 - 分別做兩個動作,將 kulipaFile資料夾壓縮至 ZipTestZip資料夾。
- 再從 ZipTestZip資料夾中把壓縮檔解壓縮至 ZipTestUnZipGoal資料夾。
package zipTest.susan.idea;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
//參考:http://crackren.iteye.com/blog/752732
public class ZipTestActivity extends Activity {
final String FILENAME = "kulipa.zip";
final String FOLDER_NAME = "kulipaFile";// 設計一個資料夾,壓縮與解壓縮都放置其中。
final String SRC_PATH = android.os.Environment
.getExternalStorageDirectory().getAbsolutePath() + "/ZipTest";
final String PATH_UNZIP = android.os.Environment
.getExternalStorageDirectory().getAbsolutePath() + "/ZipTestUnZip";
final String PATH_ZIP = android.os.Environment
.getExternalStorageDirectory().getAbsolutePath() + "/ZipTestZip";
final String PATH_UNZIP_GOAL = android.os.Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/ZipTestUnZipGoal";
Calendar calendar;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
calendar = Calendar.getInstance();
SimpleDateFormat dF = new java.text.SimpleDateFormat(
"yyyy-MM-dd-kk-mm-ss");
// Timestamp mTimestamp=
String fileName = dF.format(calendar.getTime()).toString() + ".zip";// 實做依照日期產生名稱
TextView mTextView;
mTextView = (TextView) this.findViewById(R.id.textView1);
String FileName = SRC_PATH + File.separator + fileName;
mTextView.setText("開始..壓縮的檔案路徑" + FileName);
copyFile(SRC_PATH, fileName, FILENAME); // 將原始壓縮檔放到sd卡
String unZipFilePath = PATH_UNZIP + File.separator + FOLDER_NAME;
// String unZipFilePath = PATH_UNZIP;
mTextView.append("\n準備檔案完成");
try {// 解壓縮
UnZipFolder(FileName, unZipFilePath);
} catch (Exception e) {
e.printStackTrace();
}
mTextView.append("\n解壓縮完成,位置在:" + unZipFilePath + "\n行為開始!");
FileName = PATH_ZIP + File.separator + fileName;
mTextView.append("\n我們接下來的動作是這樣的:\n1.壓縮一個檔案路徑為:" + FileName
+ "模擬上傳壓縮檔案");
File fileout = new File(PATH_ZIP);// 檢查並創立一個文件夾
if (!fileout.exists()) {
fileout.mkdirs();
}
try {
ZipFolder(unZipFilePath, FileName);
} catch (Exception e) {
e.printStackTrace();
}
mTextView.append("\n壓縮檔案完畢");
mTextView.append("\n2.解壓縮,放置到一個新的資料夾,模擬還原資料。");
fileout = new File(PATH_UNZIP_GOAL);// 檢查並創立一個文件夾
if (!fileout.exists()) {
fileout.mkdirs();
}
mTextView.append("\n準備檔案完成");
try {// 解壓縮
UnZipFolder(FileName, PATH_UNZIP_GOAL);
} catch (Exception e) {
e.printStackTrace();
}
mTextView.append("\n解壓縮完成,位置在:" + PATH_UNZIP_GOAL);
}
/**
* 壓縮文件
*
* @param srcFileString
* 壓縮文件的絕對路徑
* @param zipFileString
* 指定文件壓縮檔的絕對路徑+名字.副檔名
* @throws Exception
*/
public void ZipFolder(String srcFileString, String zipFileString)
throws Exception {
android.util.Log.v("XZip", "ZipFolder(String, String)");
// 打開來源文件
File intputFile = new File(srcFileString);
if (intputFile.exists()) {//如果來源文件存在才會動作
// 創建壓縮檔的輸出流
ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(
zipFileString));
// 進行壓縮動作。注意這邊有進行遞迴的動作。
ZipFiles(intputFile.getParent() + File.separator,
intputFile.getName(), outZip);
outZip.finish();//結束
outZip.close();//關閉
}
}// end of func
/**
* 壓縮文件
*
* @param folderString
* 壓縮文件來源的路徑
* @param fileString
* 壓縮文件來源的名稱
* @param zipOutputSteam
* 壓縮檔串流
* @throws Exception
*/
private void ZipFiles(String folderString, String fileString,
java.util.zip.ZipOutputStream zipOutputSteam) throws Exception {
if (zipOutputSteam != null) {
File file = new File(folderString + fileString);
// 判断是不是文件夾
if (file.isFile()) {// 此為一個檔案
ZipEntry zipEntry = new ZipEntry(fileString);// 獲取entry
FileInputStream inputStream = new FileInputStream(file);
zipOutputSteam.putNextEntry(zipEntry);
int len;
byte[] buffer = new byte[4096];
while ((len = inputStream.read(buffer)) != -1) {
zipOutputSteam.write(buffer, 0, len);
}// 寫入
zipOutputSteam.closeEntry();// 關閉串流
} else {// 為文件夾的情況下..
// 獲取文件夾的子目錄
String fileList[] = file.list();
// 若子目錄不存在
if (fileList.length <= 0) {
ZipEntry zipEntry = new ZipEntry(fileString
+ File.separator);
zipOutputSteam.putNextEntry(zipEntry);// 則添加該文件(空)資料夾
zipOutputSteam.closeEntry();// 關閉串流
}
// 若子目錄存在,則採遞迴方式一併添加
for (int i = 0; i < fileList.length; i++) {
ZipFiles(folderString, fileString + File.separator
+ fileList[i], zipOutputSteam);
}// end of for
}// end of if
}
}// end of func
/**
* 解壓縮一個壓縮檔至指定的路徑
*
* @param zipFileString
* 壓縮檔的完整路徑+名稱.副檔名
* @param outPathString
* 指定的路徑文件夾。
* @throws Exception
*/
public void UnZipFolder(String zipFileString, String outPathString)
throws Exception {
int BUFFER = 4096;
String strEntry; // entry的名稱ref
try {
BufferedOutputStream dest = null; // 缓冲输出流
FileInputStream fis = new FileInputStream(zipFileString);
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(fis));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {// 獲取下一個entry,並遍訪其內容。注意一開始位置為-1
try {
int count;
byte data[] = new byte[BUFFER];
strEntry = entry.getName();
File entryFile = new File(outPathString + "/" + strEntry);// 建立目的資料夾的File類別
File entryDir = new File(entryFile.getParent());
if (!entryDir.exists()) {// 若我們指定的文件夾不存在,則創立一個
entryDir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(entryFile);
dest = new BufferedOutputStream(fos, BUFFER);// 這裡包了兩層...
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();// 寫入File類別
dest.close();// 這個關掉FileOutputStream也會關掉。
} catch (Exception ex) {
ex.printStackTrace();
}
}
zis.close();
} catch (Exception cwj) {
cwj.printStackTrace();
}
}
/**
* 產生一個檔案 在sd card中的ZipTest資料夾中。
*
* @param path
* 路徑
* @param name
* 檔案名稱
* @param srcFileName
* 來源檔案名稱
*/
private boolean copyFile(String path, String name, String srcFileName) {
String FileName = path + "/" + name;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}// 如果資料夾不存在則創立一個資料夾..
if (!(new File(FileName)).exists()) {
try {
// TODO 實做檔案取出與複製至指定資料夾至此
InputStream is = this.getAssets().open(srcFileName);// 從assets中取出
FileOutputStream fos = new FileOutputStream(FileName);
byte[] buffer = new byte[1024]; // 設定Buffer
int count = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer, 0, count);
}
fos.close();
is.close();
return true;
} catch (IOException e) {
return false;
}
} else {
return true;
}
}
}
沒有留言:
張貼留言
你好,我是小書,如果文章內容有錯誤,或是看到有建議以及任何感想時,歡迎提出分享,我們一起學習一起努力。