es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Es posible almacenar archivos grandes en Spring Boot en Postgres Db como InputStream?

Estoy utilizando una aplicación de Spring Boot. Quiero almacenar un mayor número de archivos de imagen/PDF. Cada archivo tiene un tamaño aproximado de 20 MB.

Clase Actual:

Class StoreFile {
   @Lob
   @Type(type = "org.hibernate.type.BinaryType")
   @Column(name = "file", nullable = false, length=20000000)
   private byte[] file;
}

He establecido el tipo como Inputstream en lugar de byte[] de esta manera y obtuve la siguiente excepción al almacenar el archivo.

org.springframework.dao.InvalidDataAccessApiUsageException: El valor no era un array

Class StoreFile {
   @Lob
   @Type(type = "org.hibernate.type.BinaryType")
   @Column(name = "file", nullable = false, length=20000000)
   private InputStream file;
}

¿Cómo puedo almacenar archivos de gran tamaño en una base de datos Postgres de manera eficiente? ¿Podemos almacenarlo como Inputstream en la base de datos?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Almacenar archivos grandes directamente como un InputStream en la base de datos puede no ser un enfoque eficiente, ya que puede causar problemas de rendimiento y aumentar el tamaño de la base de datos. Se recomienda almacenar los archivos en un sistema de archivos o almacenamiento en la nube como Amazon S3 o Google Cloud Storage, y almacenar las rutas de archivo o URL en la base de datos. De esta manera, solo se almacena una referencia al archivo en la base de datos, reduciendo el tamaño de la misma y mejorando el rendimiento.

    Para almacenar archivos en el sistema de archivos utilizando Spring Boot, puede configurar la aplicación para usar una ubicación de almacenamiento basada en el sistema de archivos y guardar el archivo en esa ubicación utilizando el paquete Java NIO. Aquí hay un ejemplo de cómo hacerlo:

    1. Cree una clase de configuración para establecer la ubicación de almacenamiento de archivos:
    @Configuration
    public class FileStorageConfig {
    
        @Value("${file.upload-dir}")
        private String uploadDir;
    
        @Bean
        public void configureFileStorage() {
            Path path = Paths.get(uploadDir);
            if (!Files.exists(path)) {
                try {
                    Files.createDirectories(path);
                } catch (IOException e) {
                    throw new RuntimeException("No se pudo inicializar la ubicación de almacenamiento", e);
                }
            }
        }
    
        public String getUploadDir() {
            return uploadDir;
        }
    
    }
    

    En este ejemplo, la ubicación de almacenamiento de archivos se lee desde el archivo de propiedades de la aplicación utilizando la anotación @Value.

    1. Actualice la clase StoreFile para almacenar la ruta de archivo en lugar del archivo en sí:
    @Entity
    @Table(name = "store_file")
    public class StoreFile {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String fileName;
    
        private String fileType;
    
        private String fileUrl;
    
        private Long fileSize;
    
        // getters and setters
    }
    

    En este ejemplo, el campo fileUrl almacena la URL/ruta del archivo almacenado.

    1. Actualice el punto de acceso de carga de archivos para almacenar el archivo en el sistema de archivos y guardar la ruta de archivo en la base de datos:
    @RestController
    @RequestMapping("/api/files")
    public class FileUploadController {
    
        @Autowired
        private StoreFileRepository storeFileRepository;
    
        @Autowired
        private FileStorageConfig fileStorageConfig;
    
        @PostMapping("/upload")
        public ResponseEntity<storefile> uploadFile(@RequestParam("file") MultipartFile file) {
            String fileName = StringUtils.cleanPath(file.getOriginalFilename());
    
            try {
                Path fileStorageLocation = Paths.get(fileStorageConfig.getUploadDir()).toAbsolutePath().normalize();
                Path targetLocation = fileStorageLocation.resolve(fileName);
                Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
    
                StoreFile storeFile = new StoreFile();
                storeFile.setFileName(fileName);
                storeFile.setFileType(file.getContentType());
                storeFile.setFileSize(file.getSize());
                storeFile.setFileUrl(targetLocation.toString());
    
                storeFileRepository.save(storeFile);
    
                return ResponseEntity.status(HttpStatus.OK).body(storeFile);
            } catch (IOException ex) {
                throw new RuntimeException("No se pudo almacenar el archivo " + fileName + ". Por favor, inténtelo de nuevo.", ex);
            }
    
        }
    }
    

    En este ejemplo, el archivo cargado se copia a la ubicación de almacenamiento en el sistema de archivos y la ruta de archivo se almacena en el objeto StoreFile, que luego se guarda en la base de datos. La ruta de archivo se devuelve en la respuesta.

    Siguiendo este enfoque, puede almacenar archivos grandes de manera eficiente en un sistema de archivos o almacenamiento en la nube, al tiempo que reduce el tamaño de la base de datos y mejora el rendimiento.

Comments are closed.