废话不多说,直接看代码!
public class ZipUtils {
private static final String TAG = "ZipUtils";
private static ZipUtils instance;
private long zipLenght;
public static ZipUtils getInstance() {
if (instance == null) {
instance = new ZipUtils();
}
return instance;
}
public void downZIP2SD() {
InputStream dataSource = MyApp.getInstance().getContext().getResources().openRawResource(R.raw.off_line_map);
try {
UnZipFolder(dataSource, Environment.getExternalStorageDirectory().getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 把raw中的off_line_map.zip复制到SD卡中
*
* @param context
* @param id
* @param fileName
* @param storagePath
*/
public void copyFilesFromRaw(Context context, int id, String fileName, String storagePath, ZipProgress zipProgress) {
InputStream inputStream = context.getResources().openRawResource(id);
try {
LogUtils.getInstance().e("离线地图大小:" + getNetFileSizeDescription(inputStream.available()));
SpUtils.getInstance().put(Contants.MAP_OFF_LINE_SIZE, getNetFileSizeDescription(inputStream.available()));
zipLenght = inputStream.available();
if (zipLenght == 0) {
zipProgress.onError(Contants.ZIP_ERR_NULL);
}
} catch (IOException e) {
e.printStackTrace();
}
File files = new File(storagePath);
if (!files.exists()) {
files.mkdirs();
}
long count = 0;
File file = new File(storagePath + File.separator + fileName);
try {
if (!file.exists()) {
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[inputStream.available()];
int lenght = 0;
// 循环从输入流读取buffer字节
while ((lenght = inputStream.read(buffer)) != -1) {
count += lenght;
int progress = (int) ((count * 100) / zipLenght);
zipProgress.onProgress(progress);
// 将Buffer中的数据写到outputStream对象中
fos.write(buffer, 0, lenght);
}
fos.flush();// 刷新缓冲区
fos.close();
inputStream.close();
}
zipProgress.onDone();
} catch (FileNotFoundException e) {
e.printStackTrace();
zipProgress.onError(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
zipProgress.onError(e.getMessage());
}
}
/**
* 将SD卡的off_line_map.zip解压到off_line_map文件中
*
* @param filePath
* @param outPath
* @param iProgress
*/
public void unZip(String filePath, String outPath, ZipProgress iProgress) {
if (!new File(filePath).exists()) {
iProgress.onError("zip不存在 " + filePath);
return;
}
long zipLength = getZipSize(filePath);
ZipInputStream zipInputStream = null;
try {
zipInputStream = new ZipInputStream(new FileInputStream(filePath));
if (zipInputStream == null || zipInputStream.available() == 0) {
iProgress.onError("zip错误");
return;
}
ZipEntry zipEntry;
String szName = "";
long count = 0;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
szName = zipEntry.getName();
String currentParentFile = "";
if (zipEntry.isDirectory()) {
szName = szName.substring(0, szName.length() - 1);
currentParentFile = outPath + File.separator + szName;
new File(currentParentFile).mkdirs();
} else {
File file = new File(outPath + "/" + szName);
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
// 获取文件的输出流
FileOutputStream out = new FileOutputStream(file);
int len;
byte[] buffer = new byte[1024];
// 读取(字节)字节到缓冲区
while ((len = zipInputStream.read(buffer)) != -1) {
count += len;
int progress = (int) ((count * 100) / zipLength);
iProgress.onProgress(progress);
// 从缓冲区(0)位置写入(字节)字节
out.write(buffer, 0, len);
out.flush();
}
out.close();
}
}
iProgress.onDone();
} catch (Exception exc) {
iProgress.onError(exc.getMessage());
} finally {
try {
zipInputStream.close();
// LoginManager.getInstance().delete(filePath);
} catch (IOException e) {
iProgress.onError(e.getMessage());
}
}
}
/**
* 解压zip到指定的路径
*
* @param zipFileString ZIP的名称
* @param outPathString 要解压缩路径
* @throws Exception
*/
public void UnZipFolder(InputStream zipFileString, String outPathString) throws Exception {
ZipInputStream inZip = new ZipInputStream(zipFileString);
zipLenght = zipFileString.available();
ZipEntry zipEntry;
String szName = "";
long count = 0;
while ((zipEntry = inZip.getNextEntry()) != null) {
szName = zipEntry.getName();
if (zipEntry.isDirectory()) {
//获取部件的文件夹名
szName = szName.substring(0, szName.length() - 1);
File folder = new File(outPathString + File.separator + szName);
folder.mkdirs();
} else {
Log.e(TAG, outPathString + File.separator + szName);
File file = new File(outPathString + File.separator + szName);
if (!file.exists()) {
Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
file.getParentFile().mkdirs();
file.createNewFile();
}
// 获取文件的输出流
FileOutputStream out = new FileOutputStream(file);
int len;
byte[] buffer = new byte[1024];
// 读取(字节)字节到缓冲区
while ((len = inZip.read(buffer)) != -1) {
// 从缓冲区(0)位置写入(字节)字节
count += len;
int progress = (int) ((count * 100) / zipLenght);
LogUtils.getInstance().e("下载进度" + progress);
out.write(buffer, 0, len);
out.flush();
}
out.close();
}
}
inZip.close();
}
public void UnZipFolder(String zipFileString, String outPathString, String szName) throws Exception {
ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
ZipEntry zipEntry;
while ((zipEntry = inZip.getNextEntry()) != null) {
//szName = zipEntry.getName();
if (zipEntry.isDirectory()) {
//获取部件的文件夹名
szName = szName.substring(0, szName.length() - 1);
File folder = new File(outPathString + File.separator + szName);
folder.mkdirs();
} else {
Log.e(TAG, outPathString + File.separator + szName);
File file = new File(outPathString + File.separator + szName);
if (!file.exists()) {
Log.e(TAG, "Create the file:" + outPathString + File.separator + szName);
file.getParentFile().mkdirs();
file.createNewFile();
}
// 获取文件的输出流
FileOutputStream out = new FileOutputStream(file);
int len;
byte[] buffer = new byte[1024];
// 读取(字节)字节到缓冲区
while ((len = inZip.read(buffer)) != -1) {
// 从缓冲区(0)位置写入(字节)字节
out.write(buffer, 0, len);
out.flush();
}
out.close();
}
}
inZip.close();
}
/**
* 压缩文件和文件夹
*
* @param srcFileString 要压缩的文件或文件夹
* @param zipFileString 解压完成的Zip路径
* @throws Exception
*/
public void ZipFolder(String srcFileString, String zipFileString) throws Exception {
//创建ZIP
ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(zipFileString));
//创建文件
File file = new File(srcFileString);
//压缩
ZipFiles(file.getParent() + File.separator, file.getName(), outZip);
//完成和关闭
outZip.finish();
outZip.close();
}
/**
* 压缩文件
*
* @param folderString
* @param fileString
* @param zipOutputSteam
* @throws Exception
*/
private void ZipFiles(String folderString, String fileString, ZipOutputStream zipOutputSteam) throws Exception {
if (zipOutputSteam == null)
return;
File file = new File(folderString + fileString);
if (file.isFile()) {
ZipEntry zipEntry = new ZipEntry(fileString);
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);
}
}
}
/**
* 返回zip的文件输入流
*
* @param zipFileString zip的名称
* @param fileString ZIP的文件名
* @return InputStream
* @throws Exception
*/
public InputStream UpZip(String zipFileString, String fileString) throws Exception {
ZipFile zipFile = new ZipFile(zipFileString);
ZipEntry zipEntry = zipFile.getEntry(fileString);
return zipFile.getInputStream(zipEntry);
}
/**
* 返回ZIP中的文件列表(文件和文件夹)
*
* @param zipFileString ZIP的名称
* @param bContainFolder 是否包含文件夹
* @param bContainFile 是否包含文件
* @return
* @throws Exception
*/
public List<File> GetFileList(String zipFileString, boolean bContainFolder, boolean bContainFile) throws Exception {
List<File> fileList = new ArrayList<File>();
ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFileString));
ZipEntry zipEntry;
String szName = "";
while ((zipEntry = inZip.getNextEntry()) != null) {
szName = zipEntry.getName();
if (zipEntry.isDirectory()) {
// 获取部件的文件夹名
szName = szName.substring(0, szName.length() - 1);
File folder = new File(szName);
if (bContainFolder) {
fileList.add(folder);
}
} else {
File file = new File(szName);
if (bContainFile) {
fileList.add(file);
}
}
}
inZip.close();
return fileList;
}
private static long getZipSize(String filePath) {
long size = 0;
ZipFile f;
try {
f = new ZipFile(filePath);
Enumeration<? extends ZipEntry> en = f.entries();
while (en.hasMoreElements()) {
size += en.nextElement().getSize();
}
} catch (IOException e) {
size = 0;
}
return size;
}
public String getNetFileSizeDescription(long size) {
StringBuffer bytes = new StringBuffer();
DecimalFormat format = new DecimalFormat("###.0");
if (size >= 1024 * 1024 * 1024) {
double i = (size / (1024.0 * 1024.0 * 1024.0));
bytes.append(format.format(i)).append("GB");
} else if (size >= 1024 * 1024) {
double i = (size / (1024.0 * 1024.0));
bytes.append(format.format(i)).append("MB");
} else if (size >= 1024) {
double i = (size / (1024.0));
bytes.append(format.format(i)).append("KB");
} else if (size < 1024) {
if (size <= 0) {
bytes.append("0B");
} else {
bytes.append((int) size).append("B");
}
}
return bytes.toString();
}
}
配套的辅助工具类
package anrong.com.mazhanzhu_test_1.Utils.ZIP;
/**
* Created by QiYou
* on 2019/6/4
*/
public interface ZipProgress {
void onProgress(int progress);
void onError(String msg);
void onDone();
}