Android 使用 7z 壓縮字串(工作總結)
阿新 • • 發佈:2019-01-01
寫在前面
通過閱讀本篇文章,那你可以學(liao)習(jie)在android中如何對資料進行壓縮(String->byte[]),
對檔案進行壓縮和解壓縮。閱讀本篇文章大約需要五到十分鐘,本人菜鳥,希望多多交流。
對資料進行壓縮
-
- 將我們需要的程式碼 cv 到我們專案中。路徑:java/ servenZip
- 講程式碼複製到我們專案中後,自己手寫壓縮 方法。
public byte[] lzmaZip(String xml) throws IOException{
BufferedInputStream inStream = new BufferedInputStream(new ByteArrayInputStream(xml.getBytes()));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
boolean eos = true;
Encoder encoder = new Encoder();
encoder.SetEndMarkerMode(eos);
encoder.WriteCoderProperties(bos);
long fileSize = xml.length();
if (eos)
fileSize = -1 ;
for (int i = 0; i < 8; i++)
bos.write((int)(fileSize >>> (8 * i)) & 0xFF);
encoder.Code(inStream, bos, -1, -1, null);
return bos.toByteArray() ;
}
*: Encoder 為 Compression / LZMA / Encoder .
對與 我們獲得到的 byte [] ,我們肯定是持懷疑態度的。接下來我們就需要 通過 大神的專案 來驗證我們的辦法是否正確了。github:
將我們獲取的 byte [] 通過檔案儲存的方式儲存到本地,並且字尾名 為7z.
try {
byte[] ss = SevenZipUtil.lzmaZip("大吉大利,今晚吃雞!隨著最近幾年健身熱," +
"雞胸肉好像已經成了網紅。中國人到底有多愛吃雞肉?中國從什麼開始流行吃雞?" +
"雞肉又是怎麼一步步登上餐桌的? ");
createFileWithByte(ss);
appUtils.logError("7z 壓縮後:"+ Arrays.toString(ss));
} catch (IOException e) {
e.printStackTrace();
}
byte [] 儲存成檔案
/**
* 根據byte陣列生成檔案
*
* @param bytes
* 生成檔案用到的byte陣列
*/
private void createFileWithByte(byte[] bytes) {
// TODO Auto-generated method stub
/**
* 建立File物件,其中包含檔案所在的目錄以及檔案的命名
*/
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "ds",
"two.7z");
// 建立FileOutputStream物件
FileOutputStream outputStream = null;
// 建立BufferedOutputStream物件
BufferedOutputStream bufferedOutputStream = null;
try {
// 如果檔案存在則刪除
if (file.exists()) {
file.delete();
}
// 在檔案系統中根據路徑建立一個新的空檔案
file.createNewFile();
// 獲取FileOutputStream物件
outputStream = new FileOutputStream(file);
// 獲取BufferedOutputStream物件
bufferedOutputStream = new BufferedOutputStream(outputStream);
// 往檔案所在的緩衝輸出流中寫byte資料
bufferedOutputStream.write(bytes);
// 刷出緩衝輸出流,該步很關鍵,要是不執行flush()方法,那麼檔案的內容是空的。
bufferedOutputStream.flush();
} catch (Exception e) {
// 列印異常資訊
e.printStackTrace();
} finally {
// 關閉建立的流物件
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
儲存到手機上 成功之後 ,我們使用 大神的apk ,尋找到該資料夾所在位置,進行解壓。然後我們進入檔案管理介面,尋找解壓後的檔案,檢視檔案內容,經過 驗證,該方法 可行。所以在這裡 做下 筆記。 也來 填充一下 自己博文 較少的情況。(實力太菜…)
最後加上 本人使用的 工具類 SevenZipUtil:
/**
* 解壓 7z檔案
* Created by pul on 2017/12/1.
*/
public class SevenZipUtil {
private final String TAG = "SevenZipUtil";
/**
* 將字串 壓縮 轉換為 byte 陣列
*
* @param xml
* @return
* @throws IOException
*/
public static byte[] lzmaZip(String xml) throws IOException {
BufferedInputStream inStream = new BufferedInputStream(new ByteArrayInputStream(xml.getBytes()));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
boolean eos = true;
Encoder encoder = new Encoder();
encoder.SetEndMarkerMode(eos);
encoder.WriteCoderProperties(bos);
long fileSize = xml.length();
if (eos)
fileSize = -1;
for (int i = 0; i < 8; i++)
bos.write((int) (fileSize >>> (8 * i)) & 0xFF);
encoder.Code(inStream, bos, -1, -1, null);
return bos.toByteArray();
}
/**
* 解壓縮 7z檔案
*/
public void extractile(String filepath) {
RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null;
try {
randomAccessFile = new RandomAccessFile(filepath, "r");
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
// Getting simple interface of the archive inArchive
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
Log.e(TAG," Hash | Size | Filename");
Log.e(TAG,"----------+------------+---------");
for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
final int[] hash = new int[]{0};
if (!item.isFolder()) {
ExtractOperationResult result;
final long[] sizeArray = new long[1];
result = item.extractSlow(new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {
//Write to file
FileOutputStream fos;
try {
File file = new File(item.getPath());
//error occours below
// file.getParentFile().mkdirs();
fos = new FileOutputStream(file);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
hash[0] ^= Arrays.hashCode(data); // Consume data
sizeArray[0] += data.length;
return data.length; // Return amount of consumed data
}
});
if (result == ExtractOperationResult.OK) {
Log.e(TAG,String.format("%9X | %10s | %s", //
hash[0], sizeArray[0], item.getPath()));
} else {
Log.e(TAG,"Error extracting item: " + result);
}
}
}
} catch (Exception e) {
Log.e(TAG,"Error occurs: " + e);
e.printStackTrace();
System.exit(1);
} finally {
if (inArchive != null) {
try {
inArchive.close();
} catch (SevenZipException e) {
System.err.println("Error closing archive: " + e);
}
}
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (IOException e) {
System.err.println("Error closing file: " + e);
}
}
}
}
}