c/c++读取txt文件中指定行的内容_刁钻的文件压缩需求:压缩每一指定份数文件到许多的一份份压缩包中的解决办法...

文章为我在自己提问的问题下的回答。

编程解决第三步的方法待更

才学疏浅,如有错误,敬请指正


现在假设老板交给你1000000份文件,要求你快速地将这1000000份文件按照把每100份文件压缩至一个压缩包中的方法压缩出10000份压缩包,该如何解决?

显然,这样奇怪的需求很少,你经过搜索后发现没有一个现成的方案来解决这个问题,本文就这样的问题进行讨论。

大体思路是:7z支持读取含有文件名的txt文件对特定文件进行压缩,那就想方法将所有的文件名写入到一个txt文件中(Windows下DIR命令),再想办法将txt文件按指定文件数分割,最后将分割好的几个txt文件按特定顺序命名,以便用for循环使7z遍历所有txt文件进行压缩。


1. 7z支持读取含有特定规则的txt文件进行压缩

根据7z官方文档说明,7z命令行模式具有"List File"功能。

List file You can supply one or more filenames or wildcards for special list files (files containing lists of files). The filenames in such list file must be separated by new line symbol(s). For list files, 7-Zip uses UTF-8 encoding by default. You can change encoding using -scs switch. Multiple list files are supported. For example, if the file "listfile.txt" contains the following: My programs*.cpp Src*.cpp then the command 7z a -tzip archive.zip @listfile.txt adds to the archive "archive.zip" all "*.cpp" files from directories "My programs" and "Src".

其大意是,7z支持通过有文件列表的文件(如txt)对指定文件进行压缩。具体用法是在压缩命令后方加入@{ListFile} ( ListFile为文件列表文件的路径)。

例如:

7z a -tzip archive.zip @listfile.txt

表示按照listfile.txt文件中的特定要求打包压缩成archive.zip文件。


2. (按顺序)读取大量文件的文件名并写入txt文件中

仅讨论在Windows下的操作,其他OS同理。

Windows中的DIR命令可以输出指定目录下所有文件及文件夹的信息,利用DIR命令获取所有文件的文件名。

但一般情况下,DIR命令的输出格式是这样的:

0bfb96550004828d0f18689a185ce707.png

这是Explorer显示的当前目录:

5e4bbbdf48728c344da665b0c8d5b973.png

而List File要求内容为纯文件名且每个文件名之间换行分隔。

我们详细看一下DIR的参数:

3896122dff554f8df9bba89d052a2ca7.png

发现 /B 参数可以提供没有多余信息的输出,看一下效果:

44edc259700fc57e41cc9a30aaabbe08.png

非常符合List file的要求

接下来处理的问题是如何将这些在屏幕在输出的内容写入txt文件中?

Windows下也有类似C++流操作符的东西 >> ,它可以将DIR命令的输出内容写入文件中,于是:

DIR /B >> listfile.txt

3. txt文件分割

输出的listfile.txt为如下格式

e817dd261c28f5add93d001b09fe2a74.png

要做到压缩指定份数文件,只需要对List file按特定行数分割成多份List file文件即可。

按行分割txt文件的方法比较少,可以通过编程实现,后经过搜索发现有现成的小工具进行分割,但是不确定是否含有病毒,不做推荐,这个工具是TXTKiller

TXTKiller的使用方法十分简单,只需选择要分割的txt文件,指定输出目录即可完成分割。

ff9fa7be33703add02d305787bc4b98f.png

( 其功能也十分强大,不仅能够支持list file的按行分割,还有按字数、大小、章节分割等功能。)

将list file按每10行分割,效果如图:

ad69cbc0507008ea114ffff90b68ae48.png

d51fb54001234fe1d764c8ee303b749f.png

此方法不太推荐,不确定该软件是否含有病毒。

编程方法稍后再更。


4. for循环控制压缩多份压缩包

假设现在有数量特别巨大的文件,要将每特定数量份文件打包压缩成一份文件,且非分卷压缩(分卷压缩不能做到每份文件互相独立)。这就是我提出这个问题的实际应用。

如果一次次用分割后的List file文件指引压缩,数量小的文件还好处理,如果有1000000份文件要执行这样的操作,显然,工作量十分庞大

先了解一下7z的命令行模式的用法,引自7z官方文档。

Examples 7z a archive1.zip subdir adds all files and subfolders from folder subdir to archive archive1.zip. The filenames in archive will contain subdir prefix. 7z a archive2.zip .subdir* adds all files and subfolders from folder subdir to archive archive2.zip. The filenames in archive will not contain subdir prefix. cd /D c:dir1 7z a c:archive3.zip dir2dir3 The filenames in archive c:archive3.zip will contain dir2dir3 prefix, but they will not contain c:dir1 prefix. 7z a Files.7z *.txt -r adds all *.txt files from current folder and its subfolders to archive Files.7z.

从中得知,7z的压缩命令为

7z a

对压缩命令的有用参数(Switches)有:

-t //压缩格式,如zip格式: -tzip
-mx //压缩等级(0-9)(0为最低,9为最高
-mmt= //多线程模式,用法: -mmt=8
-m[0,1,2,...]=[alg]:d=2[1,2,...] //压缩算法优先级,m0为第一算法,[alg]为算法,:d=2[n]为字典大小,大小为2的n次幂MB,如:d=25为字典大小32MB(2的5次幂),用法: e.g.: -m0=LZMA:d=25
-p[passwd] //添加密码,[passwd]为密码
@[listfile] //添加List file文件,用法:e.g.: @listfile.txt

于是,7z命令行压缩的较为完备的用法:

7z a -tzip archive.zip @listfile.txt -mx9 -mmt=8 -m0=LZMA:d=25 -ppassword

意为:将listfile.txt中指定的文件添加进archive.zip中(自动创建zip文件),设定最高压缩模式,CPU线程数为8,第一算法为LZMA算法,字典大小为32MB,设定密码为password。

批处理大量文件:

在Windows下,最简单的循环方式就是cmd下的for命令了。利用顺序递进循环命令

for /L %[variable] in ([start],[step],[stop]) do [command]

[variable]为循环变量名,[start]为起始值,[step]为步进值,[stop]为终止值,[command]为执行的命令

针对当前的需求,非常容易写出循环压缩命令:

以压缩5000份文件,最高压缩模式为例,这5000份文件的文件名写入listfile.txt并按每100行分割成50份listfile_%i.txt(%i为序号)文件。

for /L %i in (1,1,50) do 7z a -tzip archive.zip @listfile_%i.txt -mx9 -mmt=8 -m0=LZMA:d=27 -psecret

这样,我们就成功地将大量文件按每一特定数量文件打包成一份份压缩包。


最后

这个问题来自于我的实际需求,一开始寻求百度谷歌无果,故在知乎上提出该问题,后来经过详细的思考与实践,得出了这个不算简洁的方法。可能有这样的需求的人很少,但是如果这种功能能够添加到压缩软件中,就更加完美了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值