bottle.py 使用 file.save() 提高 ValueError('I/O operation on closed file',)
bottle.py raising ValueError('I/O operation on closed file',) with file.save()
对于我当前的项目,我正在使用 python 瓶。目前,我正在尝试保存用户在表单中上传的文件,但它引发了上面显示的错误。我尽我所能地遵循了文档,但无论我尝试了什么,它都给出了这个错误。
函数如下:
def uploadFile(file, isPublic, userId, cu, dirId=-1):
"""Takes a bottle FileUpload instance as an argument and adds it to storage/media as well as adds its
info to the database. cu should be the db cursor. isPublic should be a bool. userId should be the
uploaders id. dirId is the directory ID and defaults to -1."""
fakeName = file.filename
extension = os.path.splitext(file.filename)[1]
cu.execute("SELECT * FROM files WHERE fileId=(SELECT MAX(fileId) FROM files)")
newId = cu.fetchone()
if newId==None:
newId = 0
else:
newId = newId[1]
if debugMode:
print(f"newId {newId}")
fileName = f"userfile-{newId}-{userId}.{extension}"
file.save(vdata["m_folder"] + "/" + fileName)
cu.execute("INSERT INTO files VALUES (?, ?, ?, ?, ?, ?)",
(userId, newId, dirId, fakeName, fileName, isPublic))
cu.connection.commit()
有人知道问题出在哪里吗?
您似乎还没有打开文件进行写入。你可以这样做:
with open('path/to/file', 'w') as file:
file.write('whatever')
使用Bottle框架上传文件的例子
我不确定您是否还需要这个答案,但我想把它包含在未来的读者中。这是 如何使用 bottle 框架上传文件的完整示例
目录结构:
.
├── app.py
├── uploaded_files
└── views
└── file_upload.tpl
app.py
:
import os
from bottle import Bottle, run, request, template
app = Bottle()
def handle_file_upload(upload):
name, ext = os.path.splitext(upload.filename)
if ext not in ('.png','.jpg','.jpeg'):
return 'File extension not allowed.'
save_path = "uploaded_files"
upload.save(save_path) # appends upload.filename automatically
return 'OK'
@app.route('/')
def file_upload():
return template('file_upload')
@app.route('/upload', method='POST')
def do_upload():
category = request.forms.get('category')
upload = request.files.get('upload')
return handle_file_upload(upload)
run(app, host='localhost', port=8080, debug=True)
views/file_upload.tpl
:
<form action="/upload" method="post" enctype="multipart/form-data">
Category: <input type="text" name="category" />
Select a file: <input type="file" name="upload" />
<input type="submit" value="Start upload" />
</form>
输出:
上传有效文件后的截图:
上述案例中可能存在的问题:
以下代码块有可能引发异常:
fileName = f"userfile-{newId}-{userId}.{extension}"
file.save(vdata["m_folder"] + "/" + fileName)
请检查每个变量的值:newId
、userId
、extension
、vdata["m_folder"]
您也可以将 "/"
替换为 os.sep
或 os.path.sep
。
正如@AlexanderCécile 在评论中提到的,将文件对象传递给外部方法也可能导致问题。您可以将变量名称 file
重命名为其他名称,但我认为它根本无法解决问题。
更新
我更新了代码。现在我将文件对象发送到另一个方法而不是路由函数,但代码仍然可以正常工作。
参考:
对于我当前的项目,我正在使用 python 瓶。目前,我正在尝试保存用户在表单中上传的文件,但它引发了上面显示的错误。我尽我所能地遵循了文档,但无论我尝试了什么,它都给出了这个错误。
函数如下:
def uploadFile(file, isPublic, userId, cu, dirId=-1):
"""Takes a bottle FileUpload instance as an argument and adds it to storage/media as well as adds its
info to the database. cu should be the db cursor. isPublic should be a bool. userId should be the
uploaders id. dirId is the directory ID and defaults to -1."""
fakeName = file.filename
extension = os.path.splitext(file.filename)[1]
cu.execute("SELECT * FROM files WHERE fileId=(SELECT MAX(fileId) FROM files)")
newId = cu.fetchone()
if newId==None:
newId = 0
else:
newId = newId[1]
if debugMode:
print(f"newId {newId}")
fileName = f"userfile-{newId}-{userId}.{extension}"
file.save(vdata["m_folder"] + "/" + fileName)
cu.execute("INSERT INTO files VALUES (?, ?, ?, ?, ?, ?)",
(userId, newId, dirId, fakeName, fileName, isPublic))
cu.connection.commit()
有人知道问题出在哪里吗?
您似乎还没有打开文件进行写入。你可以这样做:
with open('path/to/file', 'w') as file:
file.write('whatever')
使用Bottle框架上传文件的例子
我不确定您是否还需要这个答案,但我想把它包含在未来的读者中。这是 如何使用 bottle 框架上传文件的完整示例
目录结构:
.
├── app.py
├── uploaded_files
└── views
└── file_upload.tpl
app.py
:
import os
from bottle import Bottle, run, request, template
app = Bottle()
def handle_file_upload(upload):
name, ext = os.path.splitext(upload.filename)
if ext not in ('.png','.jpg','.jpeg'):
return 'File extension not allowed.'
save_path = "uploaded_files"
upload.save(save_path) # appends upload.filename automatically
return 'OK'
@app.route('/')
def file_upload():
return template('file_upload')
@app.route('/upload', method='POST')
def do_upload():
category = request.forms.get('category')
upload = request.files.get('upload')
return handle_file_upload(upload)
run(app, host='localhost', port=8080, debug=True)
views/file_upload.tpl
:
<form action="/upload" method="post" enctype="multipart/form-data">
Category: <input type="text" name="category" />
Select a file: <input type="file" name="upload" />
<input type="submit" value="Start upload" />
</form>
输出:
上传有效文件后的截图:
上述案例中可能存在的问题:
以下代码块有可能引发异常:
fileName = f"userfile-{newId}-{userId}.{extension}"
file.save(vdata["m_folder"] + "/" + fileName)
请检查每个变量的值:newId
、userId
、extension
、vdata["m_folder"]
您也可以将 "/"
替换为 os.sep
或 os.path.sep
。
正如@AlexanderCécile 在评论中提到的,将文件对象传递给外部方法也可能导致问题。您可以将变量名称 file
重命名为其他名称,但我认为它根本无法解决问题。
更新
我更新了代码。现在我将文件对象发送到另一个方法而不是路由函数,但代码仍然可以正常工作。
参考: