如何在Python中将网页上传文件保存为raw binary data并还原显示?
Absolutely! This approach is totally valid and works well for holding file content temporarily (or even persistently, if paired with disk storage). You can easily capture the binary data from uploaded files, store it in a bytes object or bytearray, and later convert it back to the original file format for display or download.
Here's a step-by-step breakdown of how to implement this, including handling the HTML upload form, processing the file in Python, storing the binary data, and retrieving it later:
1. Set Up Your HTML Upload Form
First, ensure your form uses enctype="multipart/form-data"—this is required to send file data as binary instead of URL-encoded text. Here's a minimal working example:
<!DOCTYPE html> <html> <head> <title>File Upload</title> </head> <body> <h2>Upload a File</h2> <form action="/upload" method="POST" enctype="multipart/form-data"> <input type="file" name="user_file" accept="*/*"> <button type="submit">Submit File</button> </form> </body> </html>
2. Python Backend to Handle Uploads & Store Binary Data
I'll use Flask for this example (it's lightweight and perfect for small file handling tasks). First, install Flask if you haven't:
pip install flask
Then, here's a complete script that receives uploaded files, stores their binary data, and lets you retrieve them later:
from flask import Flask, request, send_file import io app = Flask(__name__) # Use a dictionary to store files: key = filename, value = raw binary data stored_files = {} # Serve the upload form @app.route('/') def show_form(): return open('upload.html').read() # Handle file upload @app.route('/upload', methods=['POST']) def upload_file(): if 'user_file' not in request.files: return "No file was selected", 400 uploaded_file = request.files['user_file'] if uploaded_file.filename == '': return "No file chosen", 400 # Read the file as raw binary data (returns a bytes object) binary_content = uploaded_file.read() # Store the data (use bytearray(binary_content) if you need a mutable array) stored_files[uploaded_file.filename] = binary_content # Print data as you mentioned in your original script print(f"Stored file: {uploaded_file.filename} | Size: {len(binary_content)} bytes") return f"Success! Stored {len(binary_content)} bytes for {uploaded_file.filename}" # Retrieve and serve the stored file @app.route('/get-file/<filename>') def retrieve_file(filename): if filename not in stored_files: return "File not found", 404 # Convert binary data back to a file-like object file_stream = io.BytesIO(stored_files[filename]) file_stream.seek(0) # Send the file back in its original format return send_file( file_stream, download_name=filename, as_attachment=True ) if __name__ == '__main__': app.run(debug=True)
Key Concepts Explained
- Binary Storage: The
bytesobject (returned byuploaded_file.read()) is Python's native type for raw binary data. It's immutable, but if you need to modify the data later, convert it to abytearraywithbytearray(binary_content). - Persistence: The example uses an in-memory dictionary, which resets when the app restarts. For long-term storage, you can:
- Write the binary data to a local file (e.g.,
with open(f"{filename}.bin", "wb") as f: f.write(binary_content)), then store the file path. - Use a database with a binary column type (like
BLOBin SQLite/MySQL orBYTEAin PostgreSQL)—this might fix the database issues you had earlier (make sure you weren't storing binary data as text!).
- Write the binary data to a local file (e.g.,
- Retrieval: Using
io.BytesIOcreates an in-memory stream from the binary data, which Flask'ssend_filecan use to serve the file back to the browser in its original format (images, PDFs, text, etc.).
Alternative: Basic HTTP Server (No Framework)
If you don't want to use Flask, here's a simplified version using Python's built-in http.server:
from http.server import BaseHTTPRequestHandler, HTTPServer import cgi stored_files = {} class UploadHandler(BaseHTTPRequestHandler): def do_GET(self): if self.path == '/': self.send_response(200) self.send_header('Content-Type', 'text/html') self.end_headers() with open('upload.html', 'rb') as f: self.wfile.write(f.read()) def do_POST(self): if self.path == '/upload': form = cgi.FieldStorage( fp=self.rfile, headers=self.headers, environ={'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers['Content-Type']} ) file_item = form.get('user_file') if file_item and file_item.filename: binary_data = file_item.file.read() stored_files[file_item.filename] = binary_data print(f"Stored {file_item.filename} ({len(binary_data)} bytes)") self.send_response(200) self.end_headers() self.wfile.write(b"File uploaded successfully!") else: self.send_response(400) self.end_headers() self.wfile.write(b"Invalid file upload") def run_server(port=8000): server = HTTPServer(('', port), UploadHandler) print(f"Server running on http://localhost:{port}") server.serve_forever() if __name__ == '__main__': run_server()
Troubleshooting Notes
- Database Failures: If your earlier database attempts failed, you were probably using a text column instead of a binary one. Always use
BLOB/BYTEAfor storing raw file data. - Large Files: Storing large files in memory can cause memory issues. For big files, write the binary data to disk and store the file path instead of the entire data in memory.
- Encoding Errors: Never decode binary data as text (e.g.,
binary_content.decode('utf-8')) unless you're certain it's a text file—this will corrupt non-text files like images.
内容的提问来源于stack exchange,提问作者FishyPower

