1

我有一个将文件从本地上传到 Minio 浏览器的 java 程序。文件大小约为 900 MB。当我执行 java 程序时,我得到 -

Java.lang.OutOfMemoryError - Java heap Size

我尝试在 eclipse.ini 和下增加堆大小Run-->Configurations-->Project to -Xms4096M -Xmx8192M.

在我执行收到的程序时增加堆大小后 -

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

如何使用 Java 将大文件上传到 Minio?

这就是我的java程序的样子——

 StringBuilder stringBuilder = new StringBuilder();
      File[] files = new File(path).listFiles();
      showFiles(files);
      System.out.println(pathList);
      ListIterator<String> itr=pathList.listIterator();  
      while(itr.hasNext()){
          String relativePath=itr.next();
          if(relativePath!=null) {
              String absolutePath=path+(relativePath).replaceFirst("minio_files", "");
              System.out.println(absolutePath);
              System.out.println(relativePath);
              File f =new File(absolutePath);
              BufferedReader reader = new BufferedReader(new FileReader(f));
              String line = null;
              String ls = System.getProperty("line.separator");
              while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
                stringBuilder.append(ls);
              }
              if(stringBuilder.length()!=0) {

                  // delete the last new line separator
                  stringBuilder.deleteCharAt(stringBuilder.length() - 1);
              }
              reader.close();
            // Create a InputStream for object upload.
                ByteArrayInputStream bais = new ByteArrayInputStream(stringBuilder.toString().getBytes("UTF-8"));
4

1 回答 1

1

您是否绝对需要从文本文件中删除尾随行分隔符?

如果这不是绝对必需的,您可以让 minio 客户端库透明地处理上传:

String absolutePath=path+(relativePath).replaceFirst("minio_files", "");
File f =new File(absolutePath);
minio.putObject("bucketName", f.getName(), absolutePath);

根据 minio 文档,这最多允许上传 5 GB。这比任何其他解决方案更容易实施且速度更快。


如果您绝对需要删除尾随行分隔符,则至少应预先设置大小StringBuilder(并使用正确的代码删除尾随行分隔符):

File f = new File(absolutePath);
stringBuilder.ensureCapacity((int) f.length()+2);
try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
    String line;
    String ls = System.getProperty("line.separator");
    while ((line = reader.readLine()) != null) {
        stringBuilder.append(line);
        stringBuilder.append(ls);
    }
    if (stringBuilder.length() != 0) {
        // delete the last new line separator
        stringBuilder.setLength(stringBuilder.length() - ls.length());
    }
}

请注意,此代码永远不能上传大于约 2GB 的文件:

  • java中的数组不能大于Integer.MAX_VALUE-5
  • 因此StringBuilder不能用于创建超过Integer.MAX_VALUE-5字符的字符串
  • 将字符串转换为UTF-8编码字节数组不能产生比Integer.MAX_VALUE-5字节长的字节数组
  • Integer.MAX_VALUE-5由于 UTF-8 是一种多字节编码,因此可能无法将带有字符的字符串转换为字节数组
于 2018-08-01T12:51:35.997 回答