下了个游戏,全是压缩包解压密码大全,解压了第一个,后面所有的就像图上一样,一解压,进度就直接跳到80%多

谈谈 iOS 中图片的解压缩
招聘信息:
对于大多数 iOS 应用来说,图片往往是最占用手机内存的资源之一,同时也是不可或缺的组成部分。将一张图片从磁盘中加载出来,并最终显示到屏幕上,中间其实经过了一系列复杂的处理过程,其中就包括了对图片的解压缩。图片加载的工作流概括来说,从磁盘中加载一张图片,并将它显示到屏幕上,中间的如下:1.假设我们使用 +imageWithContentsOfFile: 方法从磁盘中加载一张图片,这个时候的图片并没有解压缩;2.然后将生成的 UIImage 赋值给 UIImageView ;3.接着一个隐式的 CATransaction 捕获到了 UIImageView 图层树的变化;4.在主线程的下一个 run loop 到来时,Core Animation 提交了这个隐式的 transaction ,这个过程可能会对图片进行 copy 操作,而受图片是否字节对齐等因素的影响,这个 copy 操作可能会涉及以下部分或全部步骤:分配内存缓冲区用于管理文件 IO 和解压缩操作;将文件数据从磁盘读到内存中;将压缩的图片数据解码成未压缩的位图形式,这是一个非常耗时的 CPU 操作;最后 Core Animation 使用未压缩的位图数据渲染 UIImageView 的图层。在上面的步骤中,我们提到了图片的解压缩是一个非常耗时的 CPU 操作,并且它默认是在主线程中执行的。那么当需要加载的图片比较多时,就会对我们应用的响应性造成严重的影响,尤其是在快速滑动的列表上,这个问题会表现得更加突出。为什么需要解压缩既然图片的解压缩需要消耗大量的 CPU 时间,那么我们为什么还要对图片进行解压缩呢?是否可以不经过解压缩,而直接将图片显示到屏幕上呢?答案是否定的。要想弄明白这个问题,我们首先需要知道什么是位图:“A bitmap image (or sampled image) is an array of pixels (or samples). Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.”其实,位图就是一个像素数组,数组中的每个像素就代表着图片中的一个点。我们在应用中经常用到的 JPEG 和 PNG 图片就是位图。下面,我们来看一个具体的例子,这是一张 PNG 图片,像素为 30?×?30 ,文件大小为 843B :我们使用:UIImage&*image&=&[UIImage&imageNamed:@"check_green"];
CFDataRef&rawData&=&CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));就可以获取到这个图片的原始像素数据,大小为 3600B :00&00&00
c023c&8d06bf&08a006d9&09b307f3&09b307f3&08a006d9&078d06bf
2c023c&00&00&
76&09ab07e9&09bb07ff&09bb07ff&09bb07ff&09bb07ff&09bb07ff
09bb07ff&09bb07ff&09bb07ff&09bb07ff&09bb07ff&09ab07e9&00
00&033de2&09bb07ff&09bb07ff&09bb07ff&09bb07ff
09bb07ff&09bb07ff&09bb07ff&09bb07ff&08a607e2&033d0&00000
76&09ab07e9&09bb07ff&09bb07ff&09bb07ff&09bb07ff&09bb07ff
09bb07ff&09bb07ff&09bb07ff&09bb07ff&09bb07ff&09ab07e9&00
00&00&c023c&0567048c
078d06bf&08a006d9&09b307f3&09b307f3&08a006d9&078d06bf&2c023c&
00&00&00也就是说,这张文件大小为 843B 的 PNG 图片解压缩后的大小是 3600B ,是原始文件大小的 4.27 倍。那么这个 3600B 是怎么得来的呢?与图片的文件大小或者像素有什么必然的联系吗?事实上,解压缩后的图片大小与原始文件大小之间没有任何关系,而只与图片的像素有关:解压缩后的图片大小&=&图片的像素宽&30&*&图片的像素高&30&*&每个像素所占的字节数&4至于这个公式是怎么得来的,我们后面会有详细的说明,现在只需要知道即可。至此,我们已经知道了什么是位图,并且直观地看到了它的原始像素数据,那么它与我们经常提到的图片的二进制数据有什么联系吗?是同一个东西吗?事实上,这二者是完全独立的两个东西,它们之间没有必然的联系。为了加深理解,我把这个图片拖进 Sublime Text 2 中,得到了这个图片的二进制数据,大小与原始文件大小一致,为 843B :&0d0a&1a0a&48&1e&06&ae&a200
47&4200&aece&1ce9&44&d&c557&4d68&09&da4d
09c6&8a56&&f458&4fa2&d092&f4a6&28d8&2222&de04&3d09&a1d0&7a50&0954&8bad&2d05
4fde&3c89&482b&2ad6&&e049&ef9e&4a41&48b0&42eb&a549&6893&1ddf&9bcd&b4d9&d9d9
4dd8&a43a&b0d9&9d79&3fdf&bc79&3ff3&02ac&e97&9b3e&5b05&fb32&a2
183d&340a&b886&8ff8&1e15&fced&587a&e26b&16b2&b643&f2ff&057f&1263&fd9f&fbbb&7ed7&7edd
&268e&04f1&2a1a&&b9c3&91de&a7ab&43ab&15b5&aebf&7d81&ad65&eb0a&5a31
8f4f&9f2e&d4da&1c7e&e249&64ca&c3e5&d726&7eae&2fa2&7510&cb75&3d62&cc5e&0c0f&4a5a&69c3
36ac&b11e&86&a2b7&1e48&ad82&a26a&2880&95db&3f8b&f525&b880&e0ed&
fa02&2cd4&1af7&1d0e&546a&98e5&d4ae&342a&337e&6b96&134f&1ba0&0c0b&c83b&a0f2&c
6ca9&b541&cb4f&254e&df58&d958&8955&a0fc&60&f986&b5f1&f4dd&63f2&5aec&ce59
e3b6&b0a7&cdac&ee55&145c&c7dc&8f60&f53f&e0a6&b436&e3c0&27b0&8ecf&a&ccd0&e1d8
&323d&&c1aa&5f8b&4e37&&ed72&e&d262&&1689
a976&55fb&c993&6ed5&7d10&8ff4&b162&fe6f&cd1e&ee4a&d4bb&c18e&594e&96ea&1da6&c762&6539
bdff&7943&afc0&c91f&bdd1&a327&28fc&29f7&d47a&b337&f192&0cc9&36fa&&5827&aa39
1599&4eff&69fb&0b0d&1f7a&96cd&3eb0&49&454e&44ae&4260&82事实上,不管是 JPEG 还是 PNG 图片,都是一种压缩的位图图形格式。只不过 PNG 图片是无损压缩,并且支持 alpha 通道,而 JPEG 图片则是有损压缩,可以指定 0-100% 的压缩比。值得一提的是,在苹果的 SDK 中专门提供了两个函数用来生成 PNG 和 JPEG 图片://&return&image&as&PNG.&May&return&nil&if&image&has&no&CGImageRef&or&invalid&bitmap&format
UIKIT_EXTERN&NSData&*&__nullable&UIImagePNGRepresentation(UIImage&*&__nonnull&image);
//&return&image&as&JPEG.&May&return&nil&if&image&has&no&CGImageRef&or&invalid&bitmap&format.&compression&is&0(most)..1(least)&&&&&&&&&&&&
UIKIT_EXTERN&NSData&*&__nullable&UIImageJPEGRepresentation(UIImage&*&__nonnull&image,&CGFloat&compressionQuality);因此,在将磁盘中的图片渲染到屏幕之前,必须先要得到图片的原始像素数据,才能执行后续的绘制操作,这就是为什么需要对图片解压缩的原因。强制解压缩的原理既然图片的解压缩不可避免,而我们也不想让它在主线程执行,影响我们应用的响应性,那么是否有比较好的解决方案呢?答案是肯定的。我们前面已经提到了,当未解压缩的图片将要渲染到屏幕时,系统会在主线程对图片进行解压缩,而如果图片已经解压缩了,系统就不会再对图片进行解压缩。因此,也就有了业内的解决方案,在子线程提前对图片进行强制解压缩。而强制解压缩的原理就是对图片进行重新绘制,得到一张新的解压缩后的位图。其中,用到的最核心的函数是 CGBitmapContextCreate :/*&Create&a&bitmap&context.&The&context&draws&into&a&bitmap&which&is&`width'
&&&pixels&wide&and&`height'&pixels&high.&The&number&of&components&for&each
&&&pixel&is&specified&by&`space',&which&may&also&specify&a&destination&color
&&&profile.&The&number&of&bits&for&each&component&of&a&pixel&is&specified&by
&&&`bitsPerComponent'.&The&number&of&bytes&per&pixel&is&equal&to
&&&`(bitsPerComponent&*&number&of&components&+&7)/8'.&Each&row&of&the&bitmap
&&&consists&of&`bytesPerRow'&bytes,&which&must&be&at&least&`width&*&bytes
&&&per&pixel'&&in&addition,&`bytesPerRow'&must&be&an&integer&multiple
&&&of&the&number&of&bytes&per&pixel.&`data',&if&non-NULL,&points&to&a&block
&&&of&memory&at&least&`bytesPerRow&*&height'&bytes.&If&`data'&is&NULL,&the
&&&data&for&context&is&allocated&automatically&and&freed&when&the&context&is
&&&deallocated.&`bitmapInfo'&specifies&whether&the&bitmap&should&contain&an
&&&alpha&channel&and&how&it's&to&be&generated,&along&with&whether&the
&&&components&are&floating-point&or&integer.&*/
CG_EXTERN&CGContextRef&__nullable&CGBitmapContextCreate(void&*&__nullable&data,
&&&&size_t&width,&size_t&height,&size_t&bitsPerComponent,&size_t&bytesPerRow,
&&&&CGColorSpaceRef&cg_nullable&space,&uint32_t&bitmapInfo)
&&&&CG_AVAILABLE_STARTING(__MAC_10_0,&__IPHONE_2_0);顾名思义,这个函数用于创建一个位图上下文,用来绘制一张宽 width 像素,高 height 像素的位图。这个函数的注释比较长,参数也比较难理解,但是先别着急,我们先来了解下相关的知识,然后再回过头来理解这些参数,就会比较简单了。Pixel Format我们前面已经提到了,位图其实就是一个像素数组,而则是用来描述每个像素的组成格式,它包括以下信息:Bits per component :一个像素中每个独立的颜色分量使用的 bit 数;Bits per pixel :一个像素使用的总 bit 数;Bytes per row :位图中的每一行使用的字节数。有一点需要注意的是,对于位图来说,像素格式并不是随意组合的,目前只支持以下有限的 :从上图可知,对于 iOS 来说,只支持 8 种像素格式。其中颜色空间为 Null 的 1 种,Gray 的 2 种,RGB 的 5 种,CMYK 的 0 种。换句话说,iOS 并不支持 CMYK 的颜色空间。另外,在表格的第 2 列中,除了像素格式外,还指定了 bitmap information constant ,我们在后面会详细介绍。Color and Color Spaces在上面我们提到了,那么什么是颜色空间呢?它跟颜色有什么关系呢?在 Quartz 中,一个颜色是由一组值来表示的,比如 0, 0, 1 。而颜色空间则是用来说明如何解析这些值的,离开了颜色空间,它们将变得毫无意义。比如,下面的值都表示蓝色:如果不知道颜色空间,那么我们根本无法知道这些值所代表的颜色。比如 0, 0, 1 在 RGB 下代表蓝色,而在 BGR 下则代表的是红色。在 RGB 和 BGR 两种颜色空间下,绿色是相同的,而红色和蓝色则相互对调了。因此,对于同一张图片,使用 RGB 和 BGR 两种颜色空间可能会得到两种不一样的效果:是不是感觉非常有意思呢?Color Spaces and Bitmap Layout我们前面已经知道了,像素格式是用来描述每个像素的组成格式的,比如每个像素使用的总 bit 数。而要想确保 Quartz 能够正确地解析这些 bit 所代表的含义,我们还需要提供位图的布局信息 CGBitmapInfo :typedef&CF_OPTIONS(uint32_t,&CGBitmapInfo)&{
&&&&kCGBitmapAlphaInfoMask&=&0x1F,
&&&&kCGBitmapFloatInfoMask&=&0xF00,
&&&&kCGBitmapFloatComponents&=&(1&<<&8),
&&&&kCGBitmapByteOrderMask&&&&&=&kCGImageByteOrderMask,
&&&&kCGBitmapByteOrderDefault&&=&(0&<<&12),
&&&&kCGBitmapByteOrder16Little&=&kCGImageByteOrder16Little,
&&&&kCGBitmapByteOrder32Little&=&kCGImageByteOrder32Little,
&&&&kCGBitmapByteOrder16Big&&&&=&kCGImageByteOrder16Big,
&&&&kCGBitmapByteOrder32Big&&&&=&kCGImageByteOrder32Big
}&CG_AVAILABLE_STARTING(__MAC_10_0,&__IPHONE_2_0);它主要提供了三个方面的布局信息:alpha 的信息;颜色分量是否为浮点数;像素格式的字节顺序。其中,alpha 的信息由枚举值 CGImageAlphaInfo 来表示:typedef&CF_ENUM(uint32_t,&CGImageAlphaInfo)&{
&&&&kCGImageAlphaNone,&&&&&&&&&&&&&&&/*&For&example,&RGB.&*/
&&&&kCGImageAlphaPremultipliedLast,&&/*&For&example,&premultiplied&RGBA&*/
&&&&kCGImageAlphaPremultipliedFirst,&/*&For&example,&premultiplied&ARGB&*/
&&&&kCGImageAlphaLast,&&&&&&&&&&&&&&&/*&For&example,&non-premultiplied&RGBA&*/
&&&&kCGImageAlphaFirst,&&&&&&&&&&&&&&/*&For&example,&non-premultiplied&ARGB&*/
&&&&kCGImageAlphaNoneSkipLast,&&&&&&&/*&For&example,&RBGX.&*/
&&&&kCGImageAlphaNoneSkipFirst,&&&&&&/*&For&example,&XRGB.&*/
&&&&kCGImageAlphaOnly&&&&&&&&&&&&&&&&/*&No&color&data,&alpha&data&only&*/
};上面的注释其实已经比较清楚了,它同样也提供了三个方面的 alpha 信息:是否包含 alpha ;如果包含 alpha ,那么 alpha 信息所处的位置,在像素的,比如 RGBA ,还是,比如 ARGB ;如果包含 alpha ,那么每个颜色分量是否已经乘以 alpha 的值,这种做法可以加速图片的渲染时间,因为它避免了渲染时的额外乘法运算。比如,对于 RGB 颜色空间,用已经乘以 alpha 的数据来渲染图片,每个像素都可以避免 3 次乘法运算,红色乘以 alpha ,绿色乘以 alpha 和蓝色乘以 alpha 。那么我们在解压缩图片的时候应该使用哪个值呢?根据 Which CGImageAlphaInfo should we use 和官方文档中对 UIGraphicsBeginImageContextWithOptions 函数的讨论:“You use this function to configure the drawing environment for rendering into a bitmap. The format for the bitmap is a ARGB 32-bit integer pixel format using host-byte order. If the opaque parameter is YES, the alpha channel is ignored and the bitmap is treated as fully opaque (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host). Otherwise, each pixel uses a premultipled ARGB format (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host).”我们可以知道,当图片不包含 alpha 的时候使用 kCGImageAlphaNoneSkipFirst ,否则使用 kCGImageAlphaPremultipliedFirst 。另外,这里也提到了字节顺序应该使用 32 位的主机字节顺序 kCGBitmapByteOrder32Host ,而这个值具体是什么,我们后面再讨论。至于颜色分量是否为浮点数,这个就比较简单了,直接逻辑或 kCGBitmapFloatComponents 就可以了。更详细的内容就不展开了,因为我们一般用不上这个值。接下来,我们来简单地了解下像素格式的,它是由枚举值 CGImageByteOrderInfo 来表示的:typedef&CF_ENUM(uint32_t,&CGImageByteOrderInfo)&{
&&&&kCGImageByteOrderMask&&&&&=&0x7000,
&&&&kCGImageByteOrder16Little&=&(1&<<&12),
&&&&kCGImageByteOrder32Little&=&(2&<<&12),
&&&&kCGImageByteOrder16Big&&&&=&(3&<<&12),
&&&&kCGImageByteOrder32Big&&&&=&(4&<<&12)
}&CG_AVAILABLE_STARTING(__MAC_10_12,&__IPHONE_10_0);它主要提供了两个方面的字节顺序信息:还是;数据以 16 位还是 32 位为单位。对于 iPhone 来说,采用的是小端模式,但是为了保证应用的向后兼容性,我们可以使用系统提供的宏,来避免
:#ifdef&__BIG_ENDIAN__
&&&&#define&kCGBitmapByteOrder16Host&kCGBitmapByteOrder16Big
&&&&#define&kCGBitmapByteOrder32Host&kCGBitmapByteOrder32Big
#else&/*&Little&endian.&*/
&&&&#define&kCGBitmapByteOrder16Host&kCGBitmapByteOrder16Little
&&&&#define&kCGBitmapByteOrder32Host&kCGBitmapByteOrder32Little
#endif根据前面的讨论,我们知道字节顺序的值应该使用的是 32 位的主机字节顺序 kCGBitmapByteOrder32Host ,这样的话不管当前设备采用的是小端模式还是大端模式,字节顺序始终与其保持一致。下面,我们来看一张图,它非常形象地展示了在使用 16 或 32 位像素格式的 CMYK 和 RGB 颜色空间下,一个像素是如何被表示的:我们从图中可以看出,在 32 位像素格式下,每个颜色分量使用 8 位;而在 16 位像素格式下,每个颜色分量则使用 5 位。好了,了解完这些相关知识后,我们再回过头来看看 CGBitmapContextCreate 函数中每个参数所代表的具体含义:data :如果不为 NULL ,那么它应该指向一块大小至少为 bytesPerRow * height 字节的内存;如果 为 NULL ,那么系统就会为我们自动分配和释放所需的内存,所以一般指定 NULL 即可;width 和 height :位图的宽度和高度,分别赋值为图片的像素宽度和像素高度即可;bitsPerComponent :像素的每个颜色分量使用的 bit 数,在 RGB 颜色空间下指定 8 即可;bytesPerRow :位图的每一行使用的字节数,大小至少为 width * bytes per pixel 字节。有意思的是,当我们指定 0 时,系统不仅会为我们自动计算,而且还会进行 cache line alignment 的优化,更多信息可以查看
,亲测可用;space :就是我们前面提到的颜色空间,一般使用 RGB 即可;bitmapInfo :就是我们前面提到的位图的布局信息。到这里,你已经掌握了强制解压缩图片需要用到的最核心的函数,点个赞。开源库的实现接下来,我们来看看在三个比较流行的开源库
中,对图片的强制解压缩是如何实现的。首先,我们来看看 YYKit 中的相关代码,用于解压缩图片的函数 YYCGImageCreateDecodedCopy 存在于 YYImageCoder 类中,核心代码如下:CGImageRef&YYCGImageCreateDecodedCopy(CGImageRef&imageRef,&BOOL&decodeForDisplay)&{
&&&&if&(decodeForDisplay)&{&//&decode&with&redraw&(may&lose&some&precision)
&&&&&&&&CGImageAlphaInfo&alphaInfo&=&CGImageGetAlphaInfo(imageRef)&&&kCGBitmapAlphaInfoM
&&&&&&&&BOOL&hasAlpha&=&NO;
&&&&&&&&if&(alphaInfo&==&kCGImageAlphaPremultipliedLast&||
&&&&&&&&&&&&alphaInfo&==&kCGImageAlphaPremultipliedFirst&||
&&&&&&&&&&&&alphaInfo&==&kCGImageAlphaLast&||
&&&&&&&&&&&&alphaInfo&==&kCGImageAlphaFirst)&{
&&&&&&&&&&&&hasAlpha&=&YES;
&&&&&&&&//&BGRA8888&(premultiplied)&or&BGRX8888
&&&&&&&&//&same&as&UIGraphicsBeginImageContext()&and&-[UIView&drawRect:]
&&&&&&&&CGBitmapInfo&bitmapInfo&=&kCGBitmapByteOrder32H
&&&&&&&&bitmapInfo&|=&hasAlpha&?&kCGImageAlphaPremultipliedFirst&:&kCGImageAlphaNoneSkipF
&&&&&&&&CGContextRef&context&=&CGBitmapContextCreate(NULL,&width,&height,&8,&0,&YYCGColorSpaceGetDeviceRGB(),&bitmapInfo);
&&&&&&&&if&(!context)&return&NULL;
&&&&&&&&CGContextDrawImage(context,&CGRectMake(0,&0,&width,&height),&imageRef);&//&decode
&&&&&&&&CGImageRef&newImage&=&CGBitmapContextCreateImage(context);
&&&&&&&&CFRelease(context);
&&&&&&&&return&newI
&&&&}&else&{
&&&&&&&&...
}它接受一个原始的位图参数 imageRef ,最终返回一个新的解压缩后的位图 newImage ,中间主要经过了以下三个步骤:使用 CGBitmapContextCreate 函数创建一个位图上下文;使用 CGContextDrawImage 函数将原始位图绘制到上下文中;使用 CGBitmapContextCreateImage 函数创建一张新的解压缩后的位图。事实上,SDWebImage 和 FLAnimatedImage 中对图片的解压缩过程与上述完全一致,只是传递给 CGBitmapContextCreate 函数的部分参数存在细微的差别,如下表所示:在上表中,用浅绿色背景标记的参数即为我们在前面的分析中所推荐的参数,用这些参数解压缩后的图片渲染的速度会更快。因此,从理论上说 YYKit 中的解压缩算法是三者之中最优的。性能对比口说无凭,因此我编写了一个小的测试程序,来简单地对比一下这三个开源库的解压缩性能,源码可以在
上找到。采用的测试样例分别为 5 张 PNG 图片和 5 张 JPEG 图片,像素依次为 128x96 、256x192 、512x384 、 和
,它们其实都长一个样:首先,我们来了解下测试的原理,我们可以将从磁盘加载一张图片到最终渲染到屏幕上的过程划分为三个阶段:初始化阶段:从磁盘初始化图片,生成一个未解压缩的 UIImage 对象;解压缩阶段:分别使用 YYKit 、SDWebImage 和 FLAnimatedImage 对第 1 步中得到的 UIImage 对象进行解压缩,得到一个新的解压缩后的 UIImage 对象;绘制阶段:将第 2 步中得到的 UIImage 对象绘制到屏幕上。这里我们以绘制阶段的耗时为依据来评测解压缩的性能,解压缩的算法越优秀,那么得到的图片就越符合系统渲染时的需求,绘制的时间也就越短。为了让测试的结果更准确,我们对每张图片都解压缩 10 次,然后取平均值。说明,本次使用的测试设备是 iPhone 5s 。首先,我们来看看解压缩 PNG 图片的测试结果:相应的柱状图如下:从上图可以看出,就我们采用的测试样例来说,解压缩 PNG 图片的性能 SDWebImage 最好,FLAnimatedImage 次之,YYKit 最差。这与我们前面的理论结果有一定的差距,可能是测试样例太少,也可能这就是真实结果。另外,需要说明的是,我们这里使用的 PNG 图片都是不带 alpha 值,因为 SDWebImage 不支持解压缩带 alpha 值的 PNG 图片。接着,我们再来看看解压缩 JPEG 图片的测试结果:相应的柱状图如下:这次 YYKit 终于翻盘了,解压缩 JPEG 图片的性能最好,SDWebImage 和 FLAnimatedImage 并列第二。总结其实,要理解 iOS 中图片的解压缩并不难,重点是要理解位图的概念。而图片解压缩的过程其实就是将图片的二进制数据转换成像素数据的过程。了解这些知识,将有助于我们更好地处理图片,管理好它们所占用的内存。参考链接
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量6265点击量4590点击量4565点击量3500点击量2909点击量2409点击量2381点击量2351点击量2333
&2016 Chukong Technologies,Inc.
京公网安备89linux下的压缩解压软件7zip(不会解压rar的来看一下)-红联Linux系统门户
您的位置:
&& 查看内容 - - -
linux下的压缩解压软件7zip(不会解压rar的来看一下)
pl_014发布于
&&字号: &&&&(网友评论&58&条)&
[i=s] 本帖最后由 pl_014 于
17:23 编辑
注:只想知道如何解压RAR格式的朋友可以直接跳到后面,但注意要安装7zip的rar模块
另:linux下也可以安装unrar来解压rar文件,这里从略
7-zip是一款跨平台的开源压缩/解压软件,官方网站是,支持7z、ZIP、GZIP、BZIP2、TAR等格式,并且可以解压RAR文件(注:由于协议关系,暂时不能压缩成RAR格式),在功能和压缩率上都可以与winRAR相媲美。苦于linux下无法解压RAR文件的同志有希望了。
关于7z格式
和RAR格式相类似,7z格式是一个支持不同压缩率的压缩格式,其最高等级的压缩率比RAR格式的还要高(即压缩出来的文件的大小,比RAR格式的还要小),当然,压缩等级越高,压缩/解压所需要的时间就越多,所占用的内存就越高(甚至会超出可分配给7zip的内存的大小,请特别注意),最低的压缩等级为0,为仅打包。
debian/ubuntu下可以找开新立德软件包管理器或软件中心,搜索"7z",可以看到有p7zip之类字样的包,安装它。需要RAR格式的支持的用户,还需要安装7zip的rar模块,装好后就可以使用了。
在令命行下可以使用apt-get install p7zip-full(ubuntu用户可以在前面直接加上sudo,debian用户可能需要先用su切换至root用户)
fedora和debian/ubuntu类似,这里从略。
opensuse用户请打开官方软站,地址是,在搜索框中输入"7zip",并选好你的版本,搜索,通常是安装第一个。
其它发行版的用户既可以从自己的源里找,也可以从、上寻找相应的包或源码进行安装。
windows用户请从上寻找下载,安装过程很简单,这里从略。
7-zip在命令行下的使用方法
使用格式:7z [adeltux] [-] [SWITCH]
第一个7z是程序的名称,7zip装完后会有7z、7za、7zr三个程序,其中7z是全功能的(即启用所有模块的功能),7za是仅使用7zip本身,不启用其它模块(这种情况不支持rar等格式),7zr是精简版,只支持7z格式。
第二个参数[adeltux]是用来告诉7zip执行什么功能:a用于创建压缩文件或向压缩文件中添加文件;d用于从压缩文件里删除文件;e用于解压,但不创建目录结构;l用于显示压缩文件里所包含的内容;t用于测试压缩文件是否有效;u用于更新压缩文件内的文件;x用于解压,并且创建目录结构。
[-] [SWITCH]是选项开关,部分选项将稍后介绍,也可以使用命令man 7z查看详细说明。
是压缩文件的文件名,后面跟输入文件的文件名(可以使用通配符,可以有多个文件)。
比较常用的选项开关
-t:指定压缩格式,如-t7z
-m:设置压缩方法,详见[url=file:///usr/share/doc/p7zip-full/DOCS/MANUAL/switches/method.htm]/usr/share/doc/p7zip-full/DOCS/MANUAL/switches/method.htm[/url](在debian下,若无法打开,请参照自己的man page)
-p:为压缩档案设置密码,既可以在压缩时先在输入的命令加上-p,然后在执行中输入密码,也可以直接-pPASSWORD,如-p123456
-mhe=on|off:仅适用于7z格式,开启或关闭文件列表的加密,默认为off
-si:从标准输入中读取数据,常与管道操作相结合,用于压缩/打包文件
-so:向标准输出中写入数据,常与管道操作相结合,用于解压/释放文件
-v:用于分卷压缩,比如让输出的每个文件最大为1MB,则用-v1m
-o:将解压后的文件存放到指定目录下,如想要指定解压后的文件输出到目录a下,则用-oa
-l:存储符号链接所对应的文件/目录,并替换到此链接上(注意,在所压缩的文件里不可以有递归链接)
关于命令返回值
7-zip退出后也有自己的返回值,想要查看返回值,请在命令执行完成后马上执行echo $?命令(即中间不要执行其它命令),以查看返回值,下面列出各返回值所代表的意义。
1 警告(没有错误),比如某些文件在压缩过程中无法读取
7 无法识别命令行参数
8 没有足够的内存来执行操作
255 用户自行按下Ctrl+C来中止程序
7-zip在命令行下的使用实例
注:所有操作若无特殊说明,均在普通用户下操作
1.基本操作
我将实验用的一些文件放到了~/temp下,其结构如下:
包含三个文件,两个目录,其中一个为隐i的freemind目录下包含两个子目录,其中一个为隐i的。
好,下面来压缩这些文件,在命令行下执行CODE:7z a temp.7z *效果如下:
查看压缩文件里面所包含的文件
查看压缩文件里面都有什么,可执行命令CODE:7z l temp.7z效果如下:
向压缩文件里添加文件
可以看到,除了.freemind之外的所有文件和目录全被加到压缩文件里面了,即这种情况无法直接压缩隐i文件和目录,可以将隐i文件在压缩后添加,即执行命令CODE:7z a temp.7z .freemind
好,现在这个隐i目录就被加进去了。
解压文件(安装rar模块后,可解压RAR文件)
下面,将压缩好的文件解压,在解压时,一般用x即7z x,因为e不建立目录结构,解压后的文件直接输出到当前目录下,在本例中,将解压后的文件全放到一个指定目录t下,所以执行命令CODE:7z x -ot temp.7z
可以看到,目录t被自动创建了,并且7zip按照预期的要求解压了此文件。
注,解压可以不注明类型,7zip会自动识别。
2.加密文件
为方便演示,先将上一例中输出的文件和目录全部删掉。
为压缩后的文件加密可以使用-p参数,如CODE:7z a -p temp.7z *
这时要求你输入密码,然后再验证一次,两次完全相同,即可通过。
此时再解压文件的时候就会要求你输入密码,只有密码正确时才能将文件正常解出,否则输出的文件全为空白文件,此时7-zip的输出结果为2,如CODE:7z x -ot temp.7z
当然,也可以在-p后紧跟着密码内容,如-p123456,但密码的内容也会留在屏幕上,有泄露的危险。
3.加密文件列表
7-zip仅使用-p压缩出来的文件没有对文件列表进行加密,虽然解压必须通过密码,但文件的列表仍可以通过7z l filename.7z来查看,所以可以加上参数-mhe=on,来开启对文件列表的加密,可与-p连用(注,此方法仅适用于对7z格式的压缩),如CODE:7z a -p -mhe=on temp.7z *
这时,想要查看文件列表就必须通过密码。否则不能查看,如
4.指定压缩级别
压缩级别越高,压缩后的文件所占用的空间就越小,但压缩/解压过程所占用的内存就越高,压缩/解压所需的时间就越长,有时我们需要压缩大文件,或要压缩的所有文件的体积较大,就可能会出现因内存不够而无法压缩/解压的问题,为避免这一问题,需要调整压缩级别,调整压缩级别的参数是-mx=n,n可取0、1、3、5、7、9,其中0级为仅打包,不压缩。这里为了显示出效果,以一个稍大的文件为例。
首先我们看看默认级别的压缩,执行命令CODE:7z a z.7z openschultetable1_x86_64
大约16MB的文件被压缩成了大约3MB。
再看看最高级别CODE:7z a -mx=9 z9.7z openschultetable1_x86_64
默认级别和最高级别压缩后的大小相近(但可见默认级别并非最高级别),再看看0级CODE:7z a -mx=0 z0.7z openschultetable1_x86_64
0级压缩和原文件的大小非常接近,可以认为0级压缩就是仅打包,不压缩。
5.分卷压缩
如果想把压缩后的文件放到论坛上或邮箱上,但由于文件大小的限制却无法上传,怎么办?7-zip可以满足你,分卷压缩的参数为-v,用法为-v{Size}[b|k|m|g],比如想将压缩后的文件分为每个文件1MB大小,可以使用-v1m,如
7z a -v1m zv.7z openschultetable1_x86_64
此时,每个文件最大为1M,这个问题就解决了。
6.系统备份
特别注意:7z格式的文件本身不存储用户和组信息!如果直接用于系统备份,则还原后的系统的所有文件的用户和组都将被重置为解压的用户和所在的组!
比如,我将~/temp下目录的几个文件分别设以如下权限:
使用如下命令压缩:CODE:7z a temp.7z *再使用su命令切换到root身份:CODE:su然后解压:CODE:7z x -ot temp.7z
看!虽然权限还保留着,但用户和组却变成了解压时的用户和所在的主组。如果直接用于备份全系统,并进行复恢,是很危险的!所以,需要先打包成tar文件,再压缩成7z格式,但一般两步可合二为一,即(注,在这里,先换回普通用户,便于演示)CODE:tar c * | 7za a -si temp.tar.7z解压怎么办呢?使用如下命令(注,由于前面已换回普通用户,这里再用su切换至root用户):CODE:7za x -so
temp.tar.7z | tar xv
好,这回可以看到,用户和组的信息就全保留下来了,不过由于这种方法使用-ot参数不再凑效,故删除了原来的文件。
注:man page中给出的压缩的命令格式是CODE:tar cf - directory | 7za a -si directory.tar.7z但tar的参数f的意思是指定输出文件的名称,而这里是向tar的stdout(也就是7z的stdin)输出,所以可以不加f,而加上f后,需要在后面加上"-"才行,否则会出现问题。同理在解压时,如果给tar加上参数f,也需要在后面加上一个"-"(注意空格),即CODE:7za x -so directory.tar.7z | tar xf -7.关于链接
在默认情况下,7zip将符号链接原样保存,现在,我将~/temp目录的结构和内容置为如下图所示
现在,执行ln -s ~/temp/freemind fm命令来创建一个指向freemind目录的链接,然后压缩(注,这里为了突出效果,采用0级压缩,即仅打包),执行命令CODE:7z a -mx=0 temp.7z *
使用7z x -ot temp.7z解压,然后用ls -l t查看
可见压缩档案里对符号链接是以链接形式存放的,再看看硬链接是如何存放的,先删掉t和temp.7z,执行命令CODE:ln freemind/openschultetable1_x86_64 schulte
7z a -mx=0 temp.7z *
ls -l temp.7z
可见,7zip并不能真正地识别出硬链接,在自己的压缩文件中可能会建立两个副本,但在高压缩级别中会识别出两个文件是同一个文件,故可省去不必要的硬盘开支。
有时需要把符号链接所指向的文件/目录原样放到自己的压缩文件中,而不是存放原链接,这时就需要用到-l参数,但注意:所压缩的文件中不可以包含递归链接,否则会发生错误!下面,先删除schulte和temp.7z文件,然后执行命令CODE:7z a -mx=0 -l temp.7z *然后输入命令ls -l查看:
此时,就将符号链接所对应的文件/目录也放进压缩档案中了。
7zip在图形界面下的应用
讲了半天的命令,你可能会说:“如果能在图形界面下使用,该多好“。如果你的系统里装有file roller或ark,那么恭喜,你可以在图形界面下使用7zip了,下面,我们就来看看如何使用。
首先,保证你的系统里装有file roller(或ark)和7zip(当然是linux版的)。现在,我把待测试的文件放到~/temp下。
选中需要添加的文件,单击右键,点击“压缩”。
.7z和.tar.7z都用到了7zip,而.exe格式估计也是用7zip,好像是建立什么自解压文件吧,但仅用于在windows下,linux下需要借助模拟器。
这下会了吧,第一行就是文件名,第二行是存放的位置,点击第三行的“其它选项”,可以设置密码,可以拆分文件,不过对文件列表的加密就没的可选了,一切都好了以后,点击创建即可。
解压就更好办啦,选择要解压的文件,右键单击,在右键菜单中的“使用归档管理器打开”或“使用Ark打开”(不同的发行版的叫法可能会有所偏差)就可以啦
注:可以利用这种方法在图形界面下解压RAR文件,当然,你要安装7zip的rar模块。
7-zip在wine下
当然,你也可以用windows下的7-zip借助wine来实现,安装的话可以借助PlayOnLinux(如果你的发行版可以安装的话),这样,就可以使用windows版的7-zip了。
最后,给发布者的建议
近日本人看到许多linux的网站上以rar文件发布,也看到有不少网友在linux论坛上以rar格式发布/上传文件,虽然rar等格式可以通过如上所述的方法来解压,但别忘了,任何软件都是有自己可运行的范围的,一部分linux可以解压7z、RAR格式的文件,不代表所有的linux都可以做到,而其它系统也如此,所以建议各位发布者以zip格式打包,如果说所发布的文件只需要在linux或UN*X下使用,则尽量打包成.tar.gz、.tar.bz2、.tar或.tgz,自己打包成的文件要尽量通用一些,千万不要为了省事,只弄个怪异的格式,给别人造成不必要的麻烦,当然,也不要把rar什么的再压缩一次哦。
参考资料:
这个网页给出了更多的7-zip的参数,不过冒似作者是在windows的环境下实验的,仅供参考。
作者: 奶茶dsk&发布日期:
这么晚了还发帖呀,
话说7z确实很猛,
作者: pl_014&发布日期:
[i=s] 本帖最后由 pl_014 于
00:02 编辑 QUOTE:这么晚了还发帖呀,
话说7z确实很猛,
奶茶dsk 发表于
23:43 本想早点结束的,但是7zip的命令行确实不好琢磨,毕竟我不是第一个研究7zip的,得好好研究研究,所以才这么晚,我也该睡了(明天又得起晚了)。
作者: miftoe&发布日期:
7Z很强大,顶
作者: Growth兆&发布日期:
感谢pl_014的分享,本贴加入到顶置的Linux应用贴中
作者: pallana&发布日期:
作者: pl_014&发布日期:
呵呵,感谢大宝的支持(给我加的分真多啊)
作者: xiaoweichang&发布日期:
作者: wangyu&发布日期:
太详细了,好东西
想当年我在win下用7z,打包成.7z格式,很多人打不开,但爷从来不甩他们
作者: pl_014&发布日期:
QUOTE:太详细了,好东西
想当年我在win下用7z,打包成.7z格式,很多人打不开,但爷从来不甩他们
wangyu 发表于
17:05 唉,怎么说,也得告诉他们装个7-zip啊
作者: lihongwu1987&发布日期:
[i=s] 本帖最后由 lihongwu1987 于
18:09 编辑
推行一个通行标准来取代目前并不合理的事实标准很重要,但我不寄予希望,我怕由于各种利益,推行的又是另一个不合理的标准。
共有评论数 58/每页显示数 10
发表评论,与各位同人交流。回复请点击下方的我要评论按钮(游客可回复),要发表贴子请点击
Linux教程下载?“”(请点击),Linux教程免费下载。
求助Linux问题?论坛有39版块,覆盖所有Linux技术层面。前往“”
 |  |  |  |  |  |  |  |  |  |  |  | 
&2017 红联 Powered by SupSite}

我要回帖

更多关于 压缩包解压密码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信