gpt4 book ai didi

python - 发送稀疏文件

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:44:57 25 4
gpt4 key购买 nike

我一直在研究 Python 中的套接字,我希望能够将稀疏图像文件从一台机器发送到另一台机器。正如预期的那样,通过 python 套接字发送稀疏文件不会保留文件的稀疏性。我想做一个稀疏的 tar 并以这种方式发送,但我就是想不通。

tarfile 模块说它支持读取 GNU 格式的稀疏文件,这对我创建它们没有帮助……但是 python 文档说 Pax 格式“几乎没有限制”。我不确定这是否意味着我可以创建存档并保留稀疏文件或不使用 pax 格式...我一直在尝试,但我只是不知道它如何工作。

如果这个解决方案不是一个选项,是否有任何其他方法可以通过套接字发送稀疏文件?我讨厌通过我的应用程序的系统命令调用“tar -xSf”...

谢谢,

服务器

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
s.bind((socket.gethostname(), 50001))
s.listen(1)

img = open('test.img', 'rb')

client, addr = s.accept()
l = img.read(8192)

while(l):
client.send(l)
l = img.read(8192)

img.close()
s.close()

客户端

host = ''
port = 50001

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
s.connect((host, port))

img = open('./newimg.img', 'wb')

l = s.recv(8192)

while(l):
img.write(l)
l = s.recv(8192)

img.close()
s.close()

在服务器上,我创建了一个新的稀疏文件:truncate -s 1G test.img

a du -h 显示:0 test.img

我运行我的服务器和客户端。这是传输文件的 du -h:1.0G newimg.img

如您所见,它扩展了文件并且不再稀疏。

最佳答案

如果您写入文件的开头,查找到结尾并在那里写入,通常会在文件中创建空洞。如果您读取文件,即使文件中有漏洞,您也正在读取零。当您发送文件时,文字字节会被发送,当然也会被读取。当您随后写入字节时,所有字节都将被写入,并且不会发生文件系统创建漏洞的情况。

为了缓解这种情况,您可以先寻找文件中的漏洞,将漏洞发送到漏洞所在的位置,然后再发送文件的其余部分。

以下内容未经完善,但应该能为您提供一个起点。

import os

f = open(path, "b")
fd = f.fileno()

end = os.stat(fd).st_size
holes = []
offset = os.lseek(fd, 0, os.SEEK_HOLE)
while offset != end:
end_hole = os.lseek(fd, offset, os.SEEK_DATA)
holes.append((offset, end_hole))
offset = end_hole

[open socket and stuff]

# send the holes

socket.write(json.dumps(holes)) # encode appropriately

# send file

f.seek(0)
total = 0
for hole in holes:
while total < hole[0]:
l = f.read(8192)
if len(l) + total > hole[0]:
socket.write(l[:len(l) + total - hole[0]])
l.seek(hole[1])
total += len(1) + total - hole[0]
else:
socket.write(l)
total += len(l)

然后在客户端:

still_json = True
a = []
l = s.recv(8192)

while(still_json):
a.append(l)
if check_json_end(l):
still_json = False
else:
l = s.recv(8192)

holes = parse_json(a) # the last chunk can contain something that is not json
# I asume that a still contains the bytes that are not json

fout = open(outfile, "wb")
total = 0

fout.write(a[0]) # handle the case where the first rest after the json in a is already after a hole

total += len(a[0])

for hole in holes:
while total < hole[0]:
l = socket.recv(8192)
if len(l) + total > hole[0]:
fout.write(l[:len(l) + total - hole[0]])
fout.seek(hole[1])
fout.write(l[len(l) + total - hole[0]:])
else:
fout.write(l)
total += len(l)

其中可能有很多错误,你应该重新考虑每一行,但总的原则应该没问题。 JSON 当然是任意选择的,在这种情况下可能还有其他更好的协议(protocol)。您也可以创建自己的。

关于python - 发送稀疏文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38227854/

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