gpt4 book ai didi

python - 稀疏文件 : How to find contents

转载 作者:行者123 更新时间:2023-12-03 17:16:16 26 4
gpt4 key购买 nike

如果我创建一个文件,使用 lseek(2)跳转到(空)文件中的较高位置,然后在那里写一些有值(value)的信息,我在 Unix 系统上创建一个稀疏文件(可能取决于我使用的文件系统,但假设我使用的是典型的 Unix 文件系统像 ext4 或类似的,就是这种情况)。

如果我那么 lseek(2)到文件中更高的位置,也在那里写一些东西,我最终得到一个稀疏文件,其中包含有值(value)的信息,被大量稀疏文件包围。我想在文件中找到这些有值(value)的信息,而不必完全阅读它。

例子:

$ python
f = open('sparse', 'w')
f.seek((1<<40) + 42)
f.write('foo')
f.seek((1<<40) * 2)
f.write('\0')
f.close()

这将创建一个仅使用 8k 磁盘空间的 2TB 文件:
$ du -h sparse 
8.0K sparse

中间的某个地方(1TB + 42 字节)是有值(value)的信息( foo )。

我可以使用 cat sparse 找到它当然,但这将读取完整的文件并打印大量的零字节。我尝试了较小的尺寸,发现这种方法需要大约 3 小时才能在我的电脑上打印三个字符。

问题是:

有没有办法在不读取所有空块的情况下找到存储在稀疏文件中的信息?我可以使用标准的 Unix 方法以某种方式找出空块在稀疏文件中的位置吗?

最佳答案

只是根据之前的评论写一个答案:

#!/usr/bin/env python3
from errno import ENXIO
from os import lseek
from sys import argv, stderr

SEEK_DATA = 3
SEEK_HOLE = 4

def get_ranges(fobj):
ranges = []
end = 0

while True:
try:
start = lseek(fobj.fileno(), end, SEEK_DATA)
end = lseek(fobj.fileno(), start, SEEK_HOLE)
ranges.append((start, end))
except OSError as e:
if e.errno == ENXIO:
return ranges

raise

def main():
if len(argv) < 2:
print('Usage: %s <sparse_file>' % argv[0], file=stderr)
raise SystemExit(1)

try:
with open(argv[1], 'rb') as f:
ranges = get_ranges(f)
for start, end in ranges:
print('[%d:%d]' % (start, end))
size = end-start
length = min(20, size)
f.seek(start)
data = f.read(length)
print(data)
except OSError as e:
print('Error:', e)
raise SystemExit(1)

if __name__ == '__main__': main()

但是,它可能不会执行您想要的操作,而是准确返回您编写的数据。返回的数据周围可能有零,必须手动修剪。

SEEK_DATA 和 SEEK_HOLE 的当前状态在 https://man7.org/linux/man-pages/man2/lseek.2.html 中描述:

SEEK_DATA and SEEK_HOLE are nonstandard extensions also present in Solaris, FreeBSD, and DragonFly BSD; they are proposed for inclusion in the next POSIX revision (Issue 8).

关于python - 稀疏文件 : How to find contents,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46100881/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com