¿Alguien puede decirme cuál es la mejor manera de convertir un archivo de varias partes (org.springframework.web.multipart.MultipartFile) a un archivo (java.io.File)?
En mi proyecto web spring mvc, estoy subiendo un archivo como archivo Multipart. Tengo que convertirlo en un Archivo (io), por lo tanto, puedo llamar a este servicio de almacenamiento de imágenes ( Cloudinary ). Solo toman el tipo (Archivo).
He hecho tantas búsquedas pero he fallado. Si alguien conoce un método estándar bueno, hágamelo saber. Thnx
java
spring
spring-mvc
file-upload
cloudinary
Amila Iddamalgoda
fuente
fuente
MultipartFile.transferTo()
?Respuestas:
Puede obtener el contenido de a
MultipartFile
usando elgetBytes
método y puede escribir en el archivo usandoFiles.newOutputStream()
:public void write(MultipartFile file, Path dir) { Path filepath = Paths.get(dir.toString(), file.getOriginalFilename()); try (OutputStream os = Files.newOutputStream(filepath)) { os.write(file.getBytes()); } }
También puede utilizar el método transferTo :
public void multipartFileToFile( MultipartFile multipart, Path dir ) throws IOException { Path filepath = Paths.get(dir.toString(), multipart.getOriginalFilename()); multipart.transferTo(filepath); }
fuente
createNewFIle()
aquí es inútil y derrochador. Ahora está obligandonew FileOutputStream()
(a través del sistema operativo) a eliminar el archivo así creado y crear uno nuevo.Aunque la respuesta aceptada es correcta, pero si solo está intentando cargar su imagen en cloudinary, hay una mejor manera:
Donde multipartFile es su org.springframework.web.multipart.MultipartFile .
fuente
pequeña corrección en la publicación de @PetrosTsialiamanis,
new File( multipart.getOriginalFilename())
esto creará un archivo en la ubicación del servidor donde en algún momento enfrentará problemas de permisos de escritura para el usuario, no siempre es posible otorgar permisos de escritura a todos los usuarios que realizan una acción.System.getProperty("java.io.tmpdir")
creará un directorio temporal donde su archivo se creará correctamente. De esta manera, está creando una carpeta temporal, donde se crea el archivo, más adelante puede eliminar el archivo o la carpeta temporal.public static File multipartToFile(MultipartFile multipart, String fileName) throws IllegalStateException, IOException { File convFile = new File(System.getProperty("java.io.tmpdir")+"/"+fileName); multipart.transferTo(convFile); return convFile; }
ponga este método en su utilidad común y utilícelo como por ejemplo.
Utility.multipartToFile(...)
fuente
También puede utilizar la biblioteca IO de Apache Commons y la clase FileUtils . En caso de que esté utilizando maven, puede cargarlo utilizando la dependencia anterior.
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
La fuente para guardar MultipartFile en disco.
File file = new File(directory, filename); // Create the file using the touch method of the FileUtils class. // FileUtils.touch(file); // Write bytes from the multipart file to disk. FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());
fuente
FileUtils.touch()
aquí es inútil y derrochador. Ahora está obligandonew FileOutputStream()
(a través del sistema operativo) a eliminar el archivo así creado y crear uno nuevo.MultipartFile.transferTo (File) es bueno, pero no olvides limpiar el archivo temporal después de todo.
// ask JVM to ask operating system to create temp file File tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_POSTFIX); // ask JVM to delete it upon JVM exit if you forgot / can't delete due exception tempFile.deleteOnExit(); // transfer MultipartFile to File multipartFile.transferTo(tempFile); // do business logic here result = businessLogic(tempFile); // tidy up tempFile.delete();
Consulte el comentario de Razzlero sobre File.deleteOnSalir () ejecutado al salir de JVM (que puede ser extremadamente raro) detalles a continuación.
fuente
deleteOnExit()
, solo se activará cuando la JVM finalice, por lo que no se activará durante las excepciones. Debido a esto, debe tener cuidado al usar aplicacionesdeleteOnExit()
de larga ejecución, como aplicaciones de servidor. Para aplicaciones de servidor, la JVM rara vez se cerrará. Por lo tanto, debe tener cuidado de nodeleteOnExit()
causar pérdidas de memoria. La JVM necesita realizar un seguimiento de todos los archivos que necesita eliminar al salir y que no se borran porque la JVM no termina.private File convertMultiPartToFile(MultipartFile file ) throws IOException { File convFile = new File( file.getOriginalFilename() ); FileOutputStream fos = new FileOutputStream( convFile ); fos.write( file.getBytes() ); fos.close(); return convFile; }
fuente
Puede acceder al archivo temporal en Spring lanzando si la clase de interfaz
MultipartFile
esCommonsMultipartFile
.public File getTempFile(MultipartFile multipartFile) { CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile; FileItem fileItem = commonsMultipartFile.getFileItem(); DiskFileItem diskFileItem = (DiskFileItem) fileItem; String absPath = diskFileItem.getStoreLocation().getAbsolutePath(); File file = new File(absPath); //trick to implicitly save on disk small files (<10240 bytes by default) if (!file.exists()) { file.createNewFile(); multipartFile.transferTo(file); } return file; }
Para deshacerse del truco con archivos de menos de 10240 bytes, la
maxInMemorySize
propiedad se puede establecer en 0 en la@Configuration
@EnableWebMvc
clase. Después de eso, todos los archivos cargados se almacenarán en el disco.@Bean(name = "multipartResolver") public CommonsMultipartResolver createMultipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setDefaultEncoding("utf-8"); resolver.setMaxInMemorySize(0); return resolver; }
fuente
createNewFIle()
aquí es inútil y derrochador. Ahora está obligandonew FileOutputStream()
(a través del sistema operativo) a eliminar el archivo así creado y crear uno nuevo.La respuesta de Alex78191 me ha funcionado.
public File getTempFile(MultipartFile multipartFile) { CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile; FileItem fileItem = commonsMultipartFile.getFileItem(); DiskFileItem diskFileItem = (DiskFileItem) fileItem; String absPath = diskFileItem.getStoreLocation().getAbsolutePath(); File file = new File(absPath); //trick to implicitly save on disk small files (<10240 bytes by default) if (!file.exists()) { file.createNewFile(); multipartFile.transferTo(file); } return file; }
Para cargar archivos con un tamaño superior a 10240 bytes, cambie maxInMemorySize en multipartResolver a 1 MB.
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- setting maximum upload size t 20MB --> <property name="maxUploadSize" value="20971520" /> <!-- max size of file in memory (in bytes) --> <property name="maxInMemorySize" value="1048576" /> <!-- 1MB --> </bean>
fuente
maxInMemorySize
no tiene nada que ver con la limitación del tamaño de carga del archivo. El tamaño de carga del archivo lo establece lamaxUploadSize
propiedad.maxInMemorySize
, se puede configurar prop0
.si no desea utilizar MultipartFile.transferTo (). Puedes escribir un archivo como este
val dir = File(filePackagePath) if (!dir.exists()) dir.mkdirs() val file = File("$filePackagePath${multipartFile.originalFilename}").apply { createNewFile() } FileOutputStream(file).use { it.write(multipartFile.bytes) }
fuente