使用python 3.x将文件写入磁盘

时间:2013-03-17 11:32:28

标签: python file upload python-3.x bottle

使用BottlePy,我使用以下代码上传文件并将其写入磁盘:

upload = request.files.get('upload')
raw = upload.file.read()
filename = upload.filename
with open(filename, 'w') as f:
    f.write(raw)
return "You uploaded %s (%d bytes)." % (filename, len(raw))

每次都返回适当的字节数。

上传适用于.txt.php.css等文件...

但它会导致其他文件(例如.jpg.png.pdf.xls ...

的文件损坏

我尝试更改open()功能

with open(filename, 'wb') as f:

它返回以下错误:

  

TypeError('必须是字节或缓冲区,而不是str',)

我猜这是一个与二进制文件有关的问题?

是否可以在Python上安装某些内容以运行任何文件类型的上传?


更新

正如@thkang指出的那样,我试图使用开发版本的bottlepy和内置方法来编写代码.save()

upload = request.files.get('upload')
upload.save(upload.filename)

它返回完全相同的异常错误

TypeError('must be bytes or buffer, not str',)

更新2

这里是“有效”的最终代码(并且不会弹出错误TypeError('must be bytes or buffer, not str',)

upload = request.files.get('upload')
raw = upload.file.read().encode()
filename = upload.filename
with open(filename, 'wb') as f:
    f.write(raw)

不幸的是,结果是一样的:每个.txt文件都可以正常工作,但.jpg.pdf等其他文件已损坏

我也注意到那些文件(已损坏的文件)的大小比原始文件大(上传前)

这个二进制文件必须是Python 3x的问题

注意:

  • 我使用的是python 3.1.3

  • 我使用BottlePy 0.11.6(raw bottle.py file,没有2to3或其他任何东西)

2 个答案:

答案 0 :(得分:1)

试试这个:

upload = request.files.get('upload')

with open(upload.file, "rb") as f1:
    raw = f1.read()
    filename = upload.filename
    with open(filename, 'wb') as f:
        f.write(raw)

    return "You uploaded %s (%d bytes)." % (filename, len(raw))

<强>更新

尝试value

# Get a cgi.FieldStorage object
upload = request.files.get('upload')

# Get the data
raw = upload.value;

# Write to file
filename = upload.filename
with open(filename, 'wb') as f:
    f.write(raw)

return "You uploaded %s (%d bytes)." % (filename, len(raw))

更新2

请参阅this thread,它似乎与您正在尝试的内容相同...

# Test if the file was uploaded
if fileitem.filename:

   # strip leading path from file name to avoid directory traversal attacks
   fn = os.path.basename(fileitem.filename)
   open('files/' + fn, 'wb').write(fileitem.file.read())
   message = 'The file "' + fn + '" was uploaded successfully'

else:
   message = 'No file was uploaded'

答案 1 :(得分:1)

在Python 3x中,所有字符串现在都是unicode,因此您需要转换此文件上传代码中使用的read()函数。

read()函数返回一个unicode字符串,您可以通过encode()函数将其转换为正确的字节

使用我的第一个问题中包含的代码,并替换

raw = upload.file.read()

raw = upload.file.read().encode('ISO-8859-1')

这就是全部;)

进一步阅读:http://python3porting.com/problems.html