我正在尝试手动保存上传的文件以供学习,无需 的帮助request.files。
request.files
我正在使用 Flask,它给我一种str原始主体数据,通过print(type(reqeust.data))
str
print(type(reqeust.data))
<type bytes>
但是后来我又想,就算我拿到了二进制数据,我该如何过滤掉前几行,然后从正确的位置开始读取二进制数据呢?
例如:
-----------------------------1699415032232102060211780227 Content-Disposition: form-data; name="myfile"; filename="Screenshot from 2018-10-05 15-49-07.png" Content-Type: image/png �PNG �ߧd�tEXtSoftwaregnome-screenshot��>�IDATx���OPY����l�*c���=��El"f[��)3��S�+z-v�0�c������zp����6��qS�\W��6S�qM�S=tG�Ǩb��A�ؒvc���@rh��.N]���?JK����b+�J��(�����OR�T -----------------------------1699415032232102060211780227--
最后我自己终于弄清楚了。
request.data
python2.7
virtualenv
b'raw binary data'
request.form['firstname']
所以现在的问题归结为,如何根据二进制数据重建文件。
首先,我准备了2个小文件进行测试。
文件1:1.txt
1.txt
内容:1234567
1234567
file2:test.png 这张小图像 ------>
test.png
内容(用途open('test.png', 'rb').read()):
open('test.png', 'rb').read()
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x08\x08\x02\x00\x00\x00\xa4\xafB\xe2\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\x10tEXtSoftware\x00Shutterc\x82\xd0\t\x00\x00\x00\x15IDAT\x08\xd7c\xd4\xe5Tb\xc0\x01\x98\x18p\x83\xa1"\x07\x00T;\x00h\xb9\x9335\x00\x00\x00\x00IEND\xaeB`\x82'
所以request.data我在服务器上看到的是:
b'-----------------------------16866548741414816351605255076\r\nContent-Disposition: form-data; name="myfile"; filename="1.txt"\r\nContent-Type: text/plain\r\n\r\n1234567\r\n-----------------------------16866548741414816351605255076\r\nContent-Disposition: form-data; name="myfile2"; filename="test.png"\r\nContent-Type: image/png\r\n\r\n\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x08\x08\x02\x00\x00\x00\xa4\xafB\xe2\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\x10tEXtSoftware\x00Shutterc\x82\xd0\t\x00\x00\x00\x15IDAT\x08\xd7c\xd4\xe5Tb\xc0\x01\x98\x18p\x83\xa1"\x07\x00T;\x00h\xb9\x9335\x00\x00\x00\x00IEND\xaeB`\x82\r\n-----------------------------16866548741414816351605255076--\r\n'
稍微格式化一下:
(由于我添加了额外的新行用于显示,因此数据不能直接使用。)
b'-----------------------------16866548741414816351605255076\r\n Content-Disposition: form-data; name="myfile"; filename="1.txt"\r\n Content-Type: text/plain\r\n\r\n 1234567\r\n -----------------------------16866548741414816351605255076\r\n Content-Disposition: form-data; name="myfile2"; filename="test.png"\r\n Content-Type: image/png\r\n\r\n \x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x08\x08\x02\x00\x00\x00\xa4\xafB\xe2\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\x10tEXtSoftware\x00Shutterc\x82\xd0\t\x00\x00\x00\x15IDAT\x08\xd7c\xd4\xe5Tb\xc0\x01\x98\x18p\x83\xa1"\x07\x00T;\x00h\xb9\x9335\x00\x00\x00\x00IEND\xaeB`\x82\r\n -----------------------------16866548741414816351605255076--\r\n'
让raw_data = binary data above
raw_data = binary data above
files_data_array = raw_data.split(b'-----------------------------16866548741414816351605255076\r\n)
然后我得到一个数组,其中每个文件位于不同的索引中。
这里files_data_array[1]包含第一个文件的元信息和数据。files_data_array[2]包含第二个文件的元信息和数据。如果您有更多文件,则依此类推。
files_data_array[1]
files_data_array[2]
[b'', b'Content-Disposition: form-data; name="myfile"; filename="1.txt"\r\nContent-Type: text/plain\r\n\r\n1234567\r\n', b'Content-Disposition: form-data; name="myfile2"; filename="test.png"\r\nContent-Type: image/png\r\n\r\n\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x08\x08\x02\x00\x00\x00\xa4\xafB\xe2\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\x10tEXtSoftware\x00Shutterc\x82\xd0\t\x00\x00\x00\x15IDAT\x08\xd7c\xd4\xe5Tb\xc0\x01\x98\x18p\x83\xa1"\x07\x00T;\x00h\xb9\x9335\x00\x00\x00\x00IEND\xaeB`\x82\r\n-----------------------------16866548741414816351605255076--\r\n']
file2_data = files_data_array[2]
b'Content-Disposition: form-data; name="myfile2"; filename="test.png"\r\nContent-Type: image/png\r\n\r\n\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x08\x08\x02\x00\x00\x00\xa4\xafB\xe2\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\x10tEXtSoftware\x00Shutterc\x82\xd0\t\x00\x00\x00\x15IDAT\x08\xd7c\xd4\xe5Tb\xc0\x01\x98\x18p\x83\xa1"\x07\x00T;\x00h\xb9\x9335\x00\x00\x00\x00IEND\xaeB`\x82\r\n-----------------------------16866548741414816351605255076--\r\n'
然后用 分割元数据file2_meta_info = file2_data.split(b'\r\n\r\n', maxsplit=1)[0]。注意这里我分割的是二进制数据,如果b'\r\n\r\n'文件数据中有 ,maxsplit则需要进行设置。
file2_meta_info = file2_data.split(b'\r\n\r\n', maxsplit=1)[0]
b'\r\n\r\n'
maxsplit
现在我得到了file2_meta_info,b'Content-Disposition: form-data; name="myfile"; filename="1.txt"'我可以解码它并获取我想要的任何元信息。
file2_meta_info
b'Content-Disposition: form-data; name="myfile"; filename="1.txt"'
现在转向文件主体数据本身,file2_body_data = file2_data.split(b'\r\n\r\n', maxsplit=1)[1]
file2_body_data = file2_data.split(b'\r\n\r\n', maxsplit=1)[1]
我明白了
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x08\x08\x02\x00\x00\x00\xa4\xafB\xe2\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\x00\x10tEXtSoftware\x00Shutterc\x82\xd0\t\x00\x00\x00\x15IDAT\x08\xd7c\xd4\xe5Tb\xc0\x01\x98\x18p\x83\xa1"\x07\x00T;\x00h\xb9\x9335\x00\x00\x00\x00IEND\xaeB`\x82\r\n-----------------------------16866548741414816351605255076--\r\n'
test.png与开头显示的内容相比,我还需要削减一些字节
real_file2_body_data = file2_body_data.rsplit(b'\r\n', maxsplit=2)[0]'
最后我可以使用以下命令重建文件:
f = open('test2.png', 'wb') f.write(real_file2_body_data) f.close()