前两天有朋友告诉我Unity的Assetbundle是LZMA压缩的,刚好今天有时间那么就研究研究LZMA。它是一个开源的类库,有C、 C++、C#、JAVA的类库,那么在我大Unity里面我们当然要使用C#的类库啦。
下载地址:http://www.7-zip.org/sdk.html 或者在文章的最后下载我的测试工程、如下图所示,因为9.22是Beta版本,所以我们还是老老实实下载9.20正式版本。
解压后把整个CS文件夹拖入Unity工程即可。当我在拖入Unity的时候发现Settings.cs报错了,查了一下是因为mono并不是完整的.net 。不过这个文件我们不需要用,所以直接把Settings.cs删除即可。
下面上代码,这是编辑时的一个类。我先把根目录下的一个文件压缩,接着在解压缩。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
using UnityEngine; using System.Collections; using UnityEditor; using SevenZip.Compression.LZMA; using System.IO; using System; public class Test : Editor { [MenuItem ("MyMenu/CompressFile")] static void CompressFile () { //压缩文件 CompressFileLZMA(Application.dataPath+"/1.jpg",Application.dataPath+"/2.zip"); AssetDatabase.Refresh(); } [MenuItem ("MyMenu/DecompressFile")] static void DecompressFile () { //解压文件 DecompressFileLZMA(Application.dataPath+"/2.zip",Application.dataPath+"/3.jpg"); AssetDatabase.Refresh(); } private static void CompressFileLZMA(string inFile, string outFile) { SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder(); FileStream input = new FileStream(inFile, FileMode.Open); FileStream output = new FileStream(outFile, FileMode.Create); // Write the encoder properties coder.WriteCoderProperties(output); // Write the decompressed file size. output.Write(BitConverter.GetBytes(input.Length), 0, 8); // Encode the file. coder.Code(input, output, input.Length, -1, null); output.Flush(); output.Close(); input.Close(); } private static void DecompressFileLZMA(string inFile, string outFile) { SevenZip.Compression.LZMA.Decoder coder = new SevenZip.Compression.LZMA.Decoder(); FileStream input = new FileStream(inFile, FileMode.Open); FileStream output = new FileStream(outFile, FileMode.Create); // Read the decoder properties byte[] properties = new byte[5]; input.Read(properties, 0, 5); // Read in the decompress file size. byte [] fileLengthBytes = new byte[8]; input.Read(fileLengthBytes, 0, 8); long fileLength = BitConverter.ToInt64(fileLengthBytes, 0); // Decompress the file. coder.SetDecoderProperties(properties); coder.Code(input, output, input.Length, fileLength, null); output.Flush(); output.Close(); input.Close(); } } |
我参考了这篇文章,不过它点问题,所以我改了改。
http://stackoverflow.com/questions/7646328/how-to-use-the-7z-sdk-to-compress-and-decompress-a-file
如下图所示,我把1.jpg先压缩成2.zip ,然后在把2.zip在解压成3.jpg。
下载地址:http://pan.baidu.com/s/1dDBxyBv
如果你想运行时运行LZMA按照上述代码简单改改就可以使用了。比如你把压缩过的文件放在服务器,然后用www下载到内存以后,可以通过lzma的解压方法将文件还原在保存在本地。 欢迎大家一起讨论与学习。嘿嘿,或者有什么更好的压缩方式,欢迎在下面给我留言,谢谢。
- 本文固定链接: https://www.xuanyusong.com/archives/3095
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
雨神大大,我使用这个方法的时候,AssetDatabase.Refresh();是编辑器的功能,编辑器打包的时候就没办法在程序运行的时候调用,用哪个方法替代呢?
编辑器下程序运行也可以调用这个方法, 只要不是真机上就可以
雨神,不管是7ZIP还是GZIP都支持移动端吗?
支持。。
assetbundle 相关的 一篇继续一篇,好过瘾,一找就是你的 ,哈哈
demo压缩一张图片是没问题的,如果压缩一个文件夹,再把文件夹解压用上边代码测试报Data Error。求解?
各位大神问个问题。问什么压缩后的大小和压缩前的大小差不多呢?几乎没什么变化。。。
雨神参照你的代码我写了Unity LZMA GZIP 压缩、解压文件 和 打包文件夹 (支持进度回调) ,http://blog.csdn.net/y1196645376/article/details/52492294打个广告,谢谢了
雨神如你所述是压缩一张图片,如果压缩一个文件夹,再把文件夹解压用上边代码测试报Data Error。不知你有没有测试过?
我也遇到这个问题了,有解决了吗
可以来个GZIP的例子工程吗?雨神。
雨神,能发下GZIP的压缩方式和解压方式吗?看你们的讨论最后说是GZIP压缩最好但是都没说怎么压缩。
雨松,我用SharpZipLib在IOS解压文件夹后,子文件夹里面的文件直接跳到解压文件中了,你遇到过这种情况吗?
哈喽,momo大大,问个问题吗,我尝试用StreamWriter写入一个用WWW来读取的二进制文件,但是发现那个生成的文件没有被压缩,再次用WWW来读取我自己生成的文件的时候会报Failed to decompress data for the AssetBundle。。。请问这个要咋个整呢?
喔。。。我刚刚找到解决方案咯。。。没用streamwriter来写,用File.WriteAllBytes(path, http://www.bytes); 直接就能保存咯~~~耶耶耶耶耶耶耶耶耶
可以来个GZIP的例子工程吗
想请教一下,压缩一个文件夹怎么实现。单个文件的压缩与解压我是尝试成功,可是压缩目录确实没有头绪,若方便,还请不惜赐教,给些启示。先谢过啦~
lzma 或者 gzip 如果editor的话 还可以用 win 或者mac 自带的app 来压缩。
具体点啊
雨松大大 我看了你这段话还是没看懂 我想将几个文件夹打成一个zip 可以给些指导么 或者您有时间做成demo的话可以发我邮箱82740198@qq.com 谢过了
你的压缩文件夹实现了吗?怎么实现的?
看了源代码,已经知道如何显示进度了。正研究如何压缩一个文件夹中的所有文件到一个压缩包中,列子好像没有写,源码也没有好像,不知道有木有人晓得哦。这个才是最终的目的。
请教下,怎么做进度显示的?我压缩的过程,整个Unity 是卡死无响应状态的。
单个文件压缩过程是同步的, 你可以用协同一个一个的解压,每解压一个资源然后更新一下UI
您好,请问 您的进度显示是怎么做的 能分享下嘛, 532610974@qq.com
这个确实有用,能不能获得压缩的进度和解压的进度,压缩比较的文件肯定要等的……如何写呢?
你解压这种写法有很大问题,FileStream input在读完第一次以后流没有释放掉,第二次读就会报错
哦。 我忘清空了。 不过我后来没用这个, LAMZ解压时间太长了 现在在用GZIP
GZIP 有 C#版吗? 能给Unity 用么?另外还发现,LZMA 这个东西PC没问题,移动平台就有问题了。
GZIP在MAC平台下默认有一个LIB存在,能够直接使用API进行压缩和解压缩的工作,而且速度非常快,压缩包大小稍微大一点点,但是在WINDOWS平台就用不了了,缺少LIB包。。。我换了另外的ICSharpCode.SharpZipLib 解压速度不能忍啊。。。。请问一下有没有更好的解决方案。
雨松你好,打扰你了。请问你用的GZIP库可以分享一下不,或者告诉来源。谢谢。