Android 压缩字符串
Android 端能够对字符串进行压缩。在进行大量简略文本传输时,能够先压缩字符串再发送。接收端接管后再解压。也能够将字符串压缩后存入数据库中。
应用到的类库
- GZIPInputStream
- GZIPOutputStream
代码示例
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class StrZipUtil {
/**
* @param input 须要压缩的字符串
* @return 压缩后的字符串
* @throws IOException IO
*/
public static String compress(String input) throws IOException {if (input == null || input.length() == 0) {return input;}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzipOs = new GZIPOutputStream(out);
gzipOs.write(input.getBytes());
gzipOs.close();
return out.toString("ISO-8859-1");
}
/**
* @param zippedStr 压缩后的字符串
* @return 解压缩后的
* @throws IOException IO
*/
public static String uncompress(String zippedStr) throws IOException {if (zippedStr == null || zippedStr.length() == 0) {return zippedStr;}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(zippedStr
.getBytes("ISO-8859-1"));
GZIPInputStream gzipIs = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = gzipIs.read(buffer)) >= 0) {out.write(buffer, 0, n);
}
// toString() 应用平台默认编码,也能够显式的指定如 toString("GBK")
return out.toString();}
}
红米手机测试输入
08-09 13:16:53.388 32248-32267/com.rustfisher.ndkproj D/rustApp: 开始存入数据库 ori1 len=304304
08-09 13:16:53.418 32248-32267/com.rustfisher.ndkproj D/rustApp: 已存入数据库 ori1 len=304304 , 耗时约 37 ms
08-09 13:16:53.418 32248-32267/com.rustfisher.ndkproj D/rustApp: 开始压缩 ori1 len=304304
08-09 13:16:53.438 32248-32267/com.rustfisher.ndkproj D/rustApp: 压缩结束 zip1 len=1112 , 耗时约 19 ms
08-09 13:16:53.438 32248-32267/com.rustfisher.ndkproj D/rustApp: 存压缩后的数据进数据库 zip1.length=1112
08-09 13:16:53.448 32248-32267/com.rustfisher.ndkproj D/rustApp: 压缩后的数据已进数据库 zip1.length=1112 , 耗时约 8 ms
08-09 13:16:53.448 32248-32267/com.rustfisher.ndkproj D/rustApp: 解压开始
08-09 13:16:53.488 32248-32267/com.rustfisher.ndkproj D/rustApp: 解压结束 耗时约 36 ms
存储工夫受存储字符串的长度影响。字符串长度与存储耗时正相干。
光荣手机测试
08-09 10:38:42.759 23075-23109/com.rustfisher D/rustApp: 开始压缩 ori1 len=304304
08-09 10:38:42.764 23075-23109/com.rustfisher D/rustApp: 压缩结束 zip1 len=1112
08-09 10:38:42.764 23075-23109/com.rustfisher D/rustApp: 解压开始
08-09 10:38:42.789 23075-23109/com.rustfisher D/rustApp: 解压结束
此例中,光荣压缩耗时约 5ms,解压耗时约 25ms。
能够看出,压缩后与原长度之比 1112/304304,约 0.365% 压缩和解压缩耗时视手机状况而定。
应用 ZipFile 进行解压
应用 Kotlin 实现
Android 中应用 ZipFile 与相干类来进行文件解压操作。
java.util.zip.ZipEntry
形容 zip 中的文件java.util.zip.ZipFile
形容 zip 文件java.util.zip.ZipInputStream
蕴含 ZipEntry 信息
1,解压 assets 里的 zip
本例解决 assets 中的 zip 文件。例子中解压失去一份网页文件。
ZipFile 须要一个 File 对象。而 assets 中的文件不能间接当成 File 来用。第一步咱们先把指标 zip 复制一份进去。以下是执行复制操作的代码。
val tempFile = File(targetLocation, "tmp-$assetsZipName.zip")
try {val inputStream = assets.open(assetsZipName)
if (tempFile.exists()) {tempFile.delete()
}
tempFile.createNewFile()
val copyOs: OutputStream = FileOutputStream(tempFile)
val tmp = ByteArray(1024)
var len: Int
while (((inputStream.read(tmp)).also {len = it}) != -1) {copyOs.write(tmp, 0, len)
}
copyOs.flush()
copyOs.close()
inputStream.close()
Log.d(TAG, "临时文件复制结束")
} catch (e: Exception) {Log.e(TAG, "unzipAssetsFile:", e)
return
}
如果文件寄存在 app 外部存储或者 SD 卡,就不必这么麻烦。
失去长期 zip 后,应用长期 zip 来进行解压操作。
通过文件失去 ZipInputStream,它带有压缩文件外部的各个文件的信息。用 ZipEntry 来形容。
拿到 ZipFile 对象,用 getInputStream(entry)
办法,失去每一个文件(目录)的输出流。而后用流来复制各个压缩的文件。
val zipInputStream = ZipInputStream(FileInputStream(tempFile))
val zipFile = ZipFile(tempFile)
var entry: ZipEntry?
while (zipInputStream.nextEntry.also { entry = it} != null) {val outFile = File(targetLocation, entry!!.name)
Log.d(TAG, "以后文件: $entry -> $outFile")
if (outFile.parentFile != null && !outFile.parentFile!!.exists()) {outFile.parentFile!!.mkdir()
}
if (!outFile.exists()) {if (entry!!.isDirectory) {outFile.mkdirs()
continue
} else {outFile.createNewFile()
}
}
val bis = BufferedInputStream(zipFile.getInputStream(entry))
val bos = BufferedOutputStream(FileOutputStream(outFile))
val entryTmpArr = ByteArray(1024)
while (true) {val readLen = bis.read(entryTmpArr)
if (readLen == -1) {break}
bos.write(entryTmpArr, 0, readLen)
}
bos.close()
bis.close()
Log.d(TAG, "解压失去文件 $outFile")
}
整个办法代码如下
/**
* 解压 assets 里指定的某个 zip
*/
private fun unzipAssetsFile(assetsZipName: String, targetLocation: String) {Log.d(TAG, "[unzipAssetsFile] targetLocation: $targetLocation")
val targetDir = File(targetLocation)
if (!targetDir.exists()) {targetDir.mkdirs()
}
val tempFile = File(targetLocation, "tmp-$assetsZipName.zip")
try {val inputStream = assets.open(assetsZipName)
if (tempFile.exists()) {tempFile.delete()
}
tempFile.createNewFile()
val copyOs: OutputStream = FileOutputStream(tempFile)
val tmp = ByteArray(1024)
var len: Int
while (((inputStream.read(tmp)).also {len = it}) != -1) {copyOs.write(tmp, 0, len)
}
copyOs.flush()
copyOs.close()
inputStream.close()
Log.d(TAG, "临时文件复制结束")
} catch (e: Exception) {Log.e(TAG, "unzipAssetsFile:", e)
return
}
val zipInputStream = ZipInputStream(FileInputStream(tempFile))
val zipFile = ZipFile(tempFile)
var entry: ZipEntry?
while (zipInputStream.nextEntry.also { entry = it} != null) {val outFile = File(targetLocation, entry!!.name)
Log.d(TAG, "以后文件: $entry -> $outFile")
if (outFile.parentFile != null && !outFile.parentFile!!.exists()) {outFile.parentFile!!.mkdir()
}
if (!outFile.exists()) {if (entry!!.isDirectory) {outFile.mkdirs()
continue
} else {outFile.createNewFile()
}
}
val bis = BufferedInputStream(zipFile.getInputStream(entry))
val bos = BufferedOutputStream(FileOutputStream(outFile))
val entryTmpArr = ByteArray(1024)
while (true) {val readLen = bis.read(entryTmpArr)
if (readLen == -1) {break}
bos.write(entryTmpArr, 0, readLen)
}
bos.close()
bis.close()
Log.d(TAG, "解压失去文件 $outFile")
}
val delTmp = tempFile.delete()
Log.d(TAG, "解压结束 删除临时文件 $delTmp")
}
2,电脑压缩 zip
mac 上如果在 Finder 里进行压缩,可能在操作的时候,零碎创立了一个 __MACOS
的目录。为了防止这个目录呈现。咱们能够用 zip 命令来压缩。
zip -r target.zip sourceDir
【Android 零根底入门教程视频参考】