Bueno, mi inglés no es bueno y el título puede parecer raro.
De todos modos, ahora estoy usando el matraz para construir un sitio web que pueda almacenar archivos, y mongodb es la base de datos.
Las funciones de carga de archivos e inserción de documentos no tienen problemas, lo extraño es que el archivo enviado desde el matraz send_file() se truncó sin ningún motivo. Aquí está mi código
from flask import ..., send_file, ... import pymongo import gridfs #... @app.route("/record/download/<record_id>") def api_softwares_record_download(record_id): try: #... file = files_gridfs.find_one({"_id": record_id}) file_ext = filetype.guess_extension(file.read(2048)) filename = "{}-{}{}".format( app["name"], record["version"], ".{}".format(file_ext) if file_ext else "", ) response = send_file(file, as_attachment=True, attachment_filename=filename) return response except ...El archivo de imagen original, por ejemplo, tiene 553 KB. Pero el cuerpo de la respuesta devuelve 549,61 KB y la imagen se rompió. Pero si solo escribo directamente el archivo en mi disco
#... with open('test.png', 'wb+') as file: file.write(files_gridfs.find_one({"_id": record_id}).read())El tamaño del archivo de imagen es de 553 KB y la imagen es legible.
Cuando comparo los dos archivos con el editor de texto de VS Code, descubrí que el archivo correcto comienza con �PNG , pero el archivo dañado comienza con �ϟ8���>�L�y
busque el encabezado del archivo dañado en el archivo correcto
Y traté de usar el objeto Blob y descargarlo desde el navegador. Ninguna diferencia.
¿Hay algún problema con mi código o usé mal send_file() ? ¿O debería usar flask_pymongo ?
Y es interesante que he encontrado lo que está mal con mi código.
Así lo resolví
...file.read(2048) file.seek(0) ... file.read(2048) file.seek(0) ... response = send_file(file, ...) return responseY he aquí por qué:
Por alguna razón, utilizo el tipo de filetype para detectar el nombre de la extensión del archivo y el tipo mimo, por lo que envié filetype al tipo de archivo para su detección.
file_ext = filetype.guess_extension(file.read(2048)) file_mime = filetype.guess_mime(file.read(2048)) #this line wasn't copied in my question. My fault. Y acabo de enterarme de la API de pymongo que python (o pymongo o gridfs , completamente desconocido para esto antes) lee el archivo usando un cursor. Cuando trato de encontrar la posición del cursor usando file.seek() , devuelve 4096 . Entonces, cuando vuelvo a llamar a file.read() en send_file() , el cursor lee desde 4096B hasta el encabezado del archivo. 549+4=553, y aquí está el problema.
Finalmente coloco el cursor en la posición 0 después de cada operación de read() , y devuelve el archivo correcto.
Espero que esto pueda ayudar si cometiste el mismo error como yo.