我想从一个ftp站点向另一个ftp站点发送带有python ftplib的文件,以避免文件读/写过程.
我创建了一个BytesIO流:
myfile=BytesIO()
Run Code Online (Sandbox Code Playgroud)
我使用retrbinary成功从ftp站点检索图像文件:
ftp_one.retrbinary('RETR P1090080.JPG', myfile.write)
Run Code Online (Sandbox Code Playgroud)
我可以将此内存对象保存为常规文件:
fot=open('casab.jpg', 'wb')
fot=myfile.readvalue()
Run Code Online (Sandbox Code Playgroud)
但我无法通过ftp与storbinary发送此流.我认为这会奏效:
ftp_two.storbinary('STOR magnafoto.jpg', myfile.getvalue())
Run Code Online (Sandbox Code Playgroud)
但不是.我得到一个很长的错误消息msg结尾'buf = fp.read(blocksize)AttributeError:'str'对象没有属性'read'
我也试过很多荒谬的组合,但没有成功.顺便说一句,我对myfoto.write真正做的事情也很困惑.不应该是myfoto.write()吗?
我对这个缓冲器的功能或要求也很无能为力.我想要的实现太复杂了吗?我应该在系统中使用中间写/读来ping文件吗?所有
编辑:感谢abanert,我把事情做好了.对于记录,storbinary参数是错误的,并且在发送之前需要myfile.seek(0)来"回放"流.这是一个工作片段,可以在两个ftp地址之间移动文件而无需中间物理文件写入:
import ftplib as ftp
from io import BytesIO
ftp_one=ftp.FTP(address1, user1, pass1)
ftp_two=ftp.FTP(address2, user2, pass2)
myfile=BytesIO()
ftp_one.retrbinary ('RETR imageoldname.jpg', myfile.write)
myfile.seek(0)
ftp_two.storbinary('STOR imagenewname.jpg', myfile)
ftp_one.close()
ftp_two.close()
myfile.close()
Run Code Online (Sandbox Code Playgroud) 在Python中用生成器创建一个zip文件?描述了从一堆文件中将.zip写入磁盘的解决方案.
我在相反的方向上有类似的问题.我被给了一个发电机:
stream = attachment.iter_bytes()
print type(stream)
Run Code Online (Sandbox Code Playgroud)
而且我想将它管道传输到tar gunzip文件对象:
b = io.BytesIO(stream)
f = tarfile.open(mode='r:gz', fileobj = b)
f.list()
Run Code Online (Sandbox Code Playgroud)
但我不能:
<type 'generator'>
Error: 'generator' does not have the buffer interface
Run Code Online (Sandbox Code Playgroud)
我可以在shell中解决这个问题:
$ curl --options http://URL | tar zxf - ./path/to/interesting_file
Run Code Online (Sandbox Code Playgroud)
如何在给定条件下在Python中执行相同的操作?
我无法理解这两个 BytesIO 对象的区别。如果我这样做:
f = open('decoder/logs/testfile.txt', 'rb')
file = io.BytesIO(f.read())
decode(file,0)
Run Code Online (Sandbox Code Playgroud)
然后在解码方法中这有效:
for line in islice(file, lines, None):
Run Code Online (Sandbox Code Playgroud)
但是如果我像这样创建 BytesIO :
file = io.BytesIO()
file.write(b"Some codded message")
decode(file, 0)
Run Code Online (Sandbox Code Playgroud)
然后解码方法中的循环不返回任何内容。我的理解是 BytesIO 应该充当类似文件的对象,但存储在内存中。那么为什么当我尝试仅传递一行文件时,此循环不会返回任何内容,就像文件中没有行一样?
我正在使用此函数解压缩正文或HTTP响应(如果使用gzip对其进行了压缩,压缩或放气)。
def uncompress_body(self, compression_type, body):
if compression_type == 'gzip' or compression_type == 'compress':
return zlib.decompress(body)
elif compression_type == 'deflate':
compressor = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
compressed = compressor.compress(body)
compressed += compressor.flush()
return base64.b64encode(compressed)
return body
Run Code Online (Sandbox Code Playgroud)
但是python抛出此错误消息。
TypeError: a bytes-like object is required, not '_io.BytesIO'
Run Code Online (Sandbox Code Playgroud)
在这条线上:
return zlib.decompress(body)
Run Code Online (Sandbox Code Playgroud)
本质上,我如何从“ _io.BytesIO”转换为类似字节的对象?
谢谢
我正在尝试决定在我的代码中使用的最佳内部接口,特别是关于如何处理文件内容。实际上,文件内容只是二进制数据,因此字节足以表示它们。
我将文件存储在不同的远程位置,因此有几个不同的读写类。我正在尝试找出用于我的功能的最佳界面。最初我使用的是文件路径,但这并不理想,因为这意味着始终使用磁盘(这意味着有很多笨拙的临时文件)。
代码中有几个区域具有相同的要求,并且会直接使用从该接口返回的任何内容。因此,我选择的任何抽象都会涉及相当多的代码。
使用 BytesIO 与字节的各种权衡是什么?
def put_file(location, contents_as_bytes):
def put_file(location, contents_as_fp):
def get_file_contents(location):
def get_file_contents(location, fp):
Run Code Online (Sandbox Code Playgroud)
我发现使用类文件接口(BytesIO 等)在等方面需要一些管理开销seek(0)。这引发了如下问题:
seek在开始之前还是在完成之后更好?seek是从头开始还是从文件所在的位置开始操作?tell()应该保持这个位置吗?shutil.copyfileobj它不会做任何寻求的东西我发现使用类文件接口的一个优点是它允许在您检索数据时传入要写入的 fp。这似乎提供了很大的灵活性。
def get_file_contents(location, write_into=None):
if not write_into:
write_into = io.BytesIO()
# get the contents and put it into write_into
return write_into
get_file_contents('blah', file_on_disk)
get_file_contents('blah', gzip_file)
get_file_contents('blah', temp_file)
get_file_contents('blah', bytes_io)
new_bytes_io = get_file_contents('blah')
# etc
Run Code Online (Sandbox Code Playgroud)
在 python 中设计接口时,是否有充分的理由更喜欢 BytesIO 而不是仅使用固定字节?
我正在使用 Django,需要读取上传的 xlsx 文件的工作表和单元格。使用 xlrd 应该是可能的,但是因为文件必须保留在内存中并且可能无法保存到某个位置,所以我不确定如何继续。
在这种情况下,起点是一个带有上传输入和提交按钮的网页。提交后,文件被捕获request.FILES['xlsx_file'].file并发送到处理类,该处理类必须提取所有重要数据以进行进一步处理。
的类型request.FILES['xlsx_file'].file是 BytesIO 并且 xlrd 由于没有 getitem 方法而无法读取该类型。
将 BytesIO 转换为 StringIO 后,错误消息似乎保持不变 '_io.StringIO' object has no attribute '__getitem__'
file_enc = chardet.detect(xlsx_file.read(8))['encoding']
xlsx_file.seek(0)
sio = io.StringIO(xlsx_file.read().decode(encoding=file_enc, errors='replace'))
workbook = xlrd.open_workbook(file_contents=sio)
Run Code Online (Sandbox Code Playgroud) 我正在使用pandas库将 excel 存储到bytesIO内存中。后来,我将此bytesIO对象存储到 SQL Server 中,如下所示-
df = pandas.DataFrame(data1, columns=['col1', 'col2', 'col3'])
output = BytesIO()
writer = pandas.ExcelWriter(output,engine='xlsxwriter')
df.to_excel(writer)
writer.save()
output.seek(0)
workbook = output.read()
#store into table
Query = '''
INSERT INTO [TABLE]([file]) VALUES(?)
'''
values = (workbook)
cursor = conn.cursor()
cursor.execute(Query, values)
cursor.close()
conn.commit()
#Create excel file.
Query1 = "select [file] from [TABLE] where [id] = 1"
result = conn.cursor().execute(Query1).fetchall()
print(result[0])
Run Code Online (Sandbox Code Playgroud)
现在,我想从表中拉回 BytesIO 对象并创建一个 excel 文件并将其存储在本地。我该怎么做?
我想要做的基本上是:
Model.objects.create(form=pdf_file, name="Some name")我的问题是,当create()方法运行,这样可以节省所有字段除了为form。
helpers.py
import io
import tempfile
from contextlib import contextmanager
import requests
import pdfrw
@contextmanager
def as_file(url):
with tempfile.NamedTemporaryFile(suffix='.pdf') as tfile:
tfile.write(requests.get(url).content)
tfile.flush()
yield tfile.name
def write_fillable_pdf(input_pdf_path, output_pdf_path, data_dict):
template_pdf = pdfrw.PdfReader(input_pdf_path)
## PDF is modified here
buf = io.BytesIO()
print(buf.getbuffer().nbytes). # Prints "0"!
pdfrw.PdfWriter().write(buf, template_pdf)
buf.seek(0)
return buf
Run Code Online (Sandbox Code Playgroud)
视图.py
from django.core.files import File
class FormView(View):
def get(self, …Run Code Online (Sandbox Code Playgroud) 我想根据要求提供 xlsx。通过使用BytesIO,xlsxwriter我创建了一个文件。
使用下面的代码,我可以下载一个空(!).txt文件:
@router.get("/payments/xlsx", response_description='xlsx')
async def payments():
"""sss"""
output = BytesIO()
workbook = xlsxwriter.Workbook(output)
worksheet = workbook.add_worksheet()
worksheet.write(0, 0, 'ISBN')
worksheet.write(0, 1, 'Name')
worksheet.write(0, 2, 'Takedown date')
worksheet.write(0, 3, 'Last updated')
workbook.close()
output.seek(0)
return StreamingResponse(output)
Run Code Online (Sandbox Code Playgroud)
如果我添加,headers={'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}我会在浏览器中收到此错误:
Unable to open file
You may be having a problem connecting with the server, or the file that you wanted to open was corrupted.
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
请参阅底部的更新 - 问题略有改变
我正在尝试使用 boto3 的方法将文件从 s3 下载到类似文件的对象.download_fileobj,但是当我尝试检查下载的字节流时,它是空的。但我不确定我做错了什么:
client = boto3.client('s3')
data = io.BytesIO()
client.download_fileobj(Bucket='mybucket', Key='myfile.wav', Fileobj=data)
print(data.read())
Run Code Online (Sandbox Code Playgroud)
这会产生一个空字节串:
b''
Run Code Online (Sandbox Code Playgroud)
更新 :
有点解决了。所以事实证明,data.seek(0)在该download_fileobj行后面添加可以解决问题。有鉴于此,我现在正在寻找一个答案来解释此代码片段的作用以及它为何解决问题。