spring 增加Java中字节数组的大小

f1tvaqid  于 2023-06-21  发布在  Spring
关注(0)|答案(3)|浏览(132)

我有一个Spring多部件控制器,我试图上传2GB - 5GB的文件。Spring multipart resolves get the whole file in memory when i try to do file.getBytes()I get an error Required array length 2147483639 + 9 is too large.
它可以很好地与2,147,483,647字节的文件大小,这是整数的最大大小。
任何增加字节数组容量的方法或任何其他使用spring Boot 处理大文件的方法。
使用Java 17和Sping Boot 3,因此不支持Commons fileupload,因为它使用javax

ni65a41a

ni65a41a1#

我认为这不是Spring或ByteArray本身的问题,而是Java语言本身的限制。从历史上看,数组的大小是由32位的int值跟踪的,因此数组中的最大理论元素可能是2^32 - 1 ~= 2B个元素。因此,不幸的是,大文件不能很容易地保存在内存中,以访问它们作为一个字节数组。一种解决方案是在上传后将它们保存为磁盘上的文件,并通过Scanner或NIO API(或使用Apache Commons I/O等外部库)访问它们的内容

vatpfxk5

vatpfxk52#

你可能想看看这篇文章:Spring和Apache FileUpload
Spring and Apache FileUpload

tez616oj

tez616oj3#

在Sping Boot 中处理大型文件上传时,仅仅依靠内存存储可能不是最有效的方法。上传2GB到5GB的文件会很快耗尽可用内存,并导致类似您遇到的问题。
要在Sping Boot 中处理大型文件上传,建议使用流式传输技术,而不是将整个文件存储在内存中。实现这一点的一种方法是利用Spring的MultipartFile API与Apache Commons IO或Java NIO等流库相结合。
以下是如何使用Sping Boot 流处理大文件上传的示例:
将必要的依赖项添加到项目中。对于Apache Commons IO,您可以在pom.xml文件中包含以下依赖项:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

1.修改您的Spring控制器,以使用流技术处理文件上传。不使用file.getBytes(),您可以使用BufferedInputStream分块处理文件,并将其写入临时文件或直接写入所需的位置。
import org.apache.commons.io.IOutils; importorg.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile;
import java.io.BufferedInputStream;导入java.io.文件; import java.io.FileOutputStream; import java.io.IOException;
public class MyNode {

@PostMapping("/upload")
 public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
     try (BufferedInputStream inputStream = new BufferedInputStream(file.getInputStream())) {
         // Specify the desired location or create a temporary file
         File outputFile = new File("/path/to/save/file.ext");

         try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
             // Buffer size for reading from input stream
             byte[] buffer = new byte[8192];
             int bytesRead;
             while ((bytesRead = inputStream.read(buffer)) != -1) {
                 outputStream.write(buffer, 0, bytesRead);
             }
         }

         return ResponseEntity.ok("File uploaded successfully.");
     } catch (IOException e) {
         e.printStackTrace();
         return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error uploading file.");
     }
 }

}
通过使用流技术,您可以避免将整个文件加载到内存中,并以较小的块处理它,从而可以在Sping Boot 中处理大型文件上传。

相关问题