如何从Java调用Python脚本时传递MultipartFile(非文件名)?
Great question! When you need to pass a MultipartFile (the actual file content) from Java to a Python script instead of just a filename, you’ve got a couple of solid approaches—let’s break them down clearly.
This is the most straightforward approach since it builds on your existing working code. You’ll first write the MultipartFile content to a temporary file on disk, then pass that temp file’s path to your Python script just like you did with fileIn before.
Here’s how to adjust your Java code:
import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Files; // ... inside your method handling the MultipartFile ... MultipartFile multipartFile = /* your incoming file */; // Create a temporary file (will auto-delete on JVM exit, but we can explicitly delete too) File tempFile = File.createTempFile("upload-", "." + getFileExtension(multipartFile.getOriginalFilename())); multipartFile.transferTo(tempFile); try { // Use your existing ProcessBuilder flow, passing the temp file path String[] command = {"python.exe", "script.py", tempFile.getAbsolutePath()}; ProcessBuilder probuilder = new ProcessBuilder(command); Process process = probuilder.start(); // Read output as before BufferedReader bfr = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = bfr.readLine()) != null) { // Handle output } // Wait for process to finish and check exit code int exitCode = process.waitFor(); if (exitCode != 0) { // Handle error (read error stream if needed) } } finally { // Explicitly delete the temp file to clean up immediately Files.deleteIfExists(tempFile.toPath()); } // Helper method to get file extension private String getFileExtension(String filename) { if (filename == null || !filename.contains(".")) return ""; return filename.substring(filename.lastIndexOf(".") + 1); }
Your Python script (script.py) can stay almost identical to before—it just reads the file path from sys.argv[1] and processes the file normally.
If you want to avoid writing to disk entirely, you can stream the MultipartFile content directly to the Python script’s standard input (stdin). This is better for large files or when disk space is a concern.
Java Code Adjustment
Instead of passing a file path, you’ll write the file content to the Process’s output stream (which connects to the Python script’s stdin):
import org.springframework.web.multipart.MultipartFile; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; // ... inside your method ... MultipartFile multipartFile = /* your incoming file */; String[] command = {"python.exe", "script.py"}; // No file path argument now ProcessBuilder probuilder = new ProcessBuilder(command); Process process = probuilder.start(); // Write the MultipartFile content to the Python script's stdin try (OutputStream out = process.getOutputStream()) { multipartFile.getInputStream().transferTo(out); } // Read output as before BufferedReader bfr = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = bfr.readLine()) != null) { // Handle output } // Wait for process and check exit code int exitCode = process.waitFor(); if (exitCode != 0) { // Handle error (read from process.getErrorStream() for details) }
Python Script Adjustment
Now your Python script needs to read the file content from sys.stdin instead of a file path. Here’s an example:
import sys def process_file_content(content): # Your existing file processing logic here print(f"Received content length: {len(content)}") # Read all content from stdin file_content = sys.stdin.read() process_file_content(file_content)
If you need the original filename or metadata in Python, you can pass those as additional command-line arguments alongside streaming the content. For example, adjust the Java command to:
String[] command = {"python.exe", "script.py", multipartFile.getOriginalFilename()};
Then in Python, access the filename with sys.argv[1] while still reading content from sys.stdin.
内容的提问来源于stack exchange,提问作者schoon

