简体   繁体   English

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

[英]Write files to disk with python 3.x

Using BottlePy, I use the following code to upload a file and write it to disk : 使用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))

It returns the proper amount of bytes every single time. 它每次都返回适当的字节数。

The upload works fine for file like .txt , .php , .css ... 上传适用于.txt.php.css.php ...

But it results in a corrupted file for other files like .jpg , .png , .pdf , .xls ... 但它会导致其他文件的损坏文件,如.jpg.png.pdf.xls ......

I tried to change the open() function 我试图改变open()函数

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

It returns the following error: 它返回以下错误:

TypeError('must be bytes or buffer, not str',) TypeError('必须是字节或缓冲区,而不是str')

I guess its an issue related to binary files ? 我想这是一个与二进制文件有关的问题?

Is there something to install on top of Python to run upload for any file type ? 是否有东西可以在Python上安装以运行任何文件类型的上传?


Update 更新

Just to be sure, as pointed out by @thkang I tried to code this using the dev version of bottlepy and the built-in method .save() 可以肯定的是,正如@thkang指出的那样,我尝试使用开发版本的bottlepy和内置方法来编写代码.save()

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

It returns the exact same Exception error 它返回完全相同的异常错误

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

Update 2 更新2

Here the final code which "works" (and dont pop the error TypeError('must be bytes or buffer, not str',) 这里是“工作”的最终代码(并且TypeError('must be bytes or buffer, not str',)弹出错误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)

Unfortunately, the result is the same : every .txt file works fine, but other files like .jpg , .pdf ... are corrupted 不幸的是,结果是一样的:每个.txt文件工作正常,但其他文件,如.jpg.pdf ...已损坏

I've also noticed that those file (the corrupted one) have a larger size than the orginal (before upload) 我还注意到那些文件(已损坏的文件)的大小比原始文件大(在上传之前)

This binary thing must be the issue with Python 3x 这个二进制文件必须是Python 3x的问题

Note : 注意 :

In Python 3x all strings are now unicode, so you need to convert the read() function used in this file upload code. 在Python 3x中,所有字符串现在都是unicode,因此您需要转换此文件上载代码中使用的read()函数。

The read() function returns a unicode string aswell, which you can convert into proper bytes via encode() function read()函数返回一个unicode字符串,您可以通过encode()函数将其转换为正确的字节

Use the code contained in my first question, and replace the line 使用我的第一个问题中包含的代码,并替换该行

raw = upload.file.read()

with

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

That's all ;) 就这样 ;)

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

Try this: 尝试这个:

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))

Update 更新

Try value : 尝试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))

Update 2 更新2

See this thread , it seems to do same as what you are trying... 看到这个帖子 ,它似乎和你正在尝试的一样......

# 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'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM