分割与合并文件
可移植地分割文件
示例:split.py
"""
将文件分割成很多部分,join.py将它们合并回去;
这是标准的Unix split命令行工具的一个可移植版本,因为它用Python写成,所以在Windows下也能工作和方便的修改;
因为它包装成一个函数,所以它的逻辑业务也可以由其他命令程序导入并重复使用。
"""
import sys
import os
def split(fromfile, todir, chunksize=1024 * 1024):
if not os.path.exists(todir):
os.mkdir(todir)
else:
input('即将删除{}下的所有内容,按回车键继续……'.format(todir))
for eachfile in os.listdir(todir):
os.remove(os.path.join(todir, eachfile))
partsnum = 0
infile = open(fromfile, 'rb')
while True:
chunk = infile.read(chunksize)
if not chunk:
break
partsnum += 1
filename = os.path.join(todir, 'part{:0>4}'.format(partsnum))
part = open(filename, 'wb')
part.write(chunk)
part.close()
infile.close()
assert partsnum <= 9999, "文件过大"
return partsnum
def command():
if len(sys.argv) == 2 and (sys.argv[1] == '--help' or sys.argv[1] == '-h'):
print('Use: ./split.py [file-to-split target-dir [chunksize]]')
else:
chunksize = 1024 * 1024
if len(sys.argv) < 3:
interact = True
fromfile = input('请输出要分割的文件:')
todir = 'splited_' + os.path.basename(fromfile)
todir = input(
'请输入存储分割后的文件的目录(回车后默认{}):'.format(todir)
) or todir
chunksize = input('请输入分割后文件kb大小(回车后默认1024):') or 1024
chunksize = int(chunksize) * 1024
else:
interact = False
fromfile, todir = sys.argv[1: 3]
if len(sys.argv) == 4:
chunksize = int(sys.argv[3]) * 1024
absfrom, absto = map(os.path.abspath, [fromfile, todir])
print('将{}分割到{}中,每个文件{}kb'.format(absfrom, absto, chunksize / 1024))
try:
partsnum = split(fromfile, todir, chunksize=chunksize)
except Exception:
print('分割失败')
print(sys.exc_info()[0], sys.exc_info()[1])
else:
print('分隔成功:{}个分割文件在{}中'.format(partsnum, absto))
if interact:
input('按回车键退出……')
if __name__ == '__main__':
command()
输出:split.py
$ ./split.py
请输出要分割的文件:bigext_tree.py
请输入存储分割后的文件的目录(回车后默认splited_bigext_tree.py):
请输入分割后文件kb大小(回车后默认1024):1
将/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/bigext_tree.py分割到/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/splited_bigext_tree.py中,每个文件1.0kb
分隔成功:3个分割文件在/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/splited_bigext_tree.py中
按回车键退出……
$ ./split.py bigpy_path.py path1
将/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/bigpy_path.py分割到/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/path1中,每个文件1024.0kb
分隔成功:1个分割文件在/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/path1中
$ ./split.py bigpy_path.py path2 1
将/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/bigpy_path.py分割到/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/path2中,每个文件1.0kb
分隔成功:3个分割文件在/media/beacherhou/Coding/code_obsidian_知识库/python-programming---markdown-notes/my_PP4E/system/filetools/path2中
$ ls splited_bigext_tree.py/
part0001 part0002 part0003
$ ls path1/
part0001
$ ls path2/
part0001 part0002 part0003
可移植地合并文件
示例:join.py
"""
合并split.py创建的目录下的所有分割文件以重建文件。
大概相当于Unix下的cat fromdir/* > tofile命令,
不过可移植性和可配置性更好,
并且将合并操作作为可以重复使用的函数。
依赖文件名的排序顺序:长度必须一致。
可以进一步拓展为分割/合并,弹出Tkinter文件选择器。
"""
import os
import sys
def join(fromdir, tofile, readsize=1024):
output = open(tofile, 'wb')
parts = os.listdir(fromdir)
parts.sort()
for part in parts:
path = os.path.join(fromdir, part)
infile = open(path, 'rb')
while True:
read = infile.read(readsize)
if not read:
break
output.write(read)
infile.close()
output.close()
def command():
if len(sys.argv) == 2 and sys.argv[1] == '--help':
print('Use: ./join.py [from-dir-name to-file-name [read-size]]')
else:
if len(sys.argv) < 3:
interactive = True
fromdir = input('请输入分割文件所在的目录:')
if 'splited_' in os.path.basename(fromdir):
tofile = os.path.basename(fromdir).replace('splited_', '')
tofile = input('请输入合并后的文件名(回车后默认{}):'.format(tofile)) or tofile
else:
tofile = input(
'请输入合并后的文件名(回车后默认{}):'.format(os.path.basename(fromdir))
) or os.path.basename(fromdir)
readsize = input('请输入每次读取的字节大小(回车后默认1024):') or 1024
readsize = int(readsize)
else:
interactive = False
fromdir, tofile = sys.argv[1], sys.argv[2]
readsize = 1024
if len(sys.argv) > 3:
readsize = int(sys.argv[3])
absfrom, absto = map(os.path.abspath, [fromdir, tofile])
print('将{}下的分割文件合并为{},每次读取{}字节'.format(absfrom, absto, readsize))
try:
join(fromdir, tofile, readsize=readsize)
except Exception:
print('合并失败')
print(sys.exc_info()[0], sys.exc_info()[1])
else:
print('合并成功:{}'.format(absto))
if interactive:
input('按回车键退出……')
if __name__ == '__main__':
command()
输出:join.py
$ ./my_PP4E/system/filetools/split.py ./my_PP4E/system/filetools/split.py splited_split.py 1
将/media/beacherhou/Git仓库/python-programming---markdown-notes/my_PP4E/system/filetools/split.py分割到/media/beacherhou/Git仓库/python-programming---markdown-notes/splited_split.py中,每个文件1.0kb
分隔成功:3个分割文件在/media/beacherhou/Git仓库/python-programming---markdown-notes/splited_split.py中
$ ./my_PP4E/system/filetools/join.py splited_split.py split.py 1
将/media/beacherhou/Git仓库/python-programming---markdown-notes/splited_split.py下的分割文件合并为/media/beacherhou/Git仓库/python-programming---markdown-notes/split.py,每次读取1字节
合并成功:/media/beacherhou/Git仓库/python-programming---markdown-notes/split.py
$ ls
第二部分_系统编程 jupyter LICENSE my_PP4E PP4E README.md splited_split.py split.py
$ ./my_PP4E/system/filetools/join.py
请输入分割文件所在的目录:splited_split.py
请输入合并后的文件名(回车后默认split.py):
请输入每次读取的字节大小(回车后默认1024):
将/media/beacherhou/Git仓库/python-programming---markdown-notes/splited_split.py下的分割文件合并为/media/beacherhou/Git仓库/python-programming---markdown-notes/split.py,每次读取1024字节
合并成功:/media/beacherhou/Git仓库/python-programming---markdown-notes/split.py
按回车键退出……
$ cat split.py
"""
将文件分割成很多部分,join.py将它们合并回去;
这是标准的Unix split命令行工具的一个可移植版本,因为它用Python写成,所以在Windows下也能工作和方便的修改;
因为它包装成一个函数,所以它的逻辑业务也可以由其他命令程序导入并重复使用。
"""
import sys
import os
def split(fromfile, todir, chunksize=1024 * 1024):
if not os.path.exists(todir):
os.mkdir(todir)
else:
input('即将删除{}下的所有内容,按回车键继续……'.format(todir))
for eachfile in os.listdir(todir):
os.remove(os.path.join(todir, eachfile))
partsnum = 0
infile = open(fromfile, 'rb')
while True:
chunk = infile.read(chunksize)
if not chunk:
break
partsnum += 1
filename = os.path.join(todir, 'part{:0>10}'.format(partsnum))
part = open(filename, 'wb')
part.write(chunk)
part.close()
infile.close()
assert partsnum <= 9999999999, "文件过大"
return partsnum
def command():
if len(sys.argv) == 2 and (sys.argv[1] == '--help' or sys.argv[1] == '-h'):
print('Use: ./split.py [file-to-split target-dir [chunksize]]')
else:
chunksize = 1024 * 1024
if len(sys.argv) < 3:
interact = True
fromfile = input('请输出要分割的文件:')
todir = 'splited_' + os.path.basename(fromfile)
todir = input(
'请输入存储分割后的文件的目录(回车后默认{}):'.format(todir)
) or todir
chunksize = input('请输入分割后文件kb大小(回车后默认1024):') or 1024
chunksize = int(chunksize) * 1024
else:
interact = False
fromfile, todir = sys.argv[1: 3]
if len(sys.argv) == 4:
chunksize = int(sys.argv[3]) * 1024
absfrom, absto = map(os.path.abspath, [fromfile, todir])
print('将{}分割到{}中,每个文件{}kb'.format(absfrom, absto, chunksize / 1024))
try:
partsnum = split(fromfile, todir, chunksize=chunksize)
except Exception:
print('分割失败')
print(sys.exc_info()[0], sys.exc_info()[1])
else:
print('分隔成功:{}个分割文件在{}中'.format(partsnum, absto))
if interact:
input('按回车键退出……')
if __name__ == '__main__':
command()
———————————————————————————————————————————
😃 学完博客后,是不是有所启发呢?如果对此还有疑问,欢迎在评论区留言哦。 如果还想了解更多的信息,欢迎大佬们关注我哦,也可以查看我的个人博客网站BeacherHou。
|