gpt4 book ai didi

Java OutOfMemoryError 同时从分块文件中合并大文件部分

转载 作者:行者123 更新时间:2023-11-30 06:11:00 25 4
gpt4 key购买 nike

当用户上传大文件(> 1 GB)(我正在使用 flow.js 库)时我遇到了问题,它在临时目录中创建了数十万个小分块文件(例如每个 100KB)但无法合并到单个文件,由于 MemoryOutOfException。当文件小于 1 GB 时,不会发生这种情况。我知道这听起来很乏味,您可能建议我增加容器中的 XmX - 但除此之外我还想有另一个角度。

这是我的代码

private void mergeFile(String identifier, int totalFile, String outputFile) throws AppException{
File[] fileDatas = new File[totalFile]; //we know the size of file here and create specific amount of the array
byte fileContents[] = null;
int totalFileSize = 0;
int filePartUploadSize = 0;
int tempFileSize = 0;
//I'm creating array of file and append the length
for (int i = 0; i < totalFile; i++) {
fileDatas[i] = new File(identifier + "." + (i + 1)); //indentifier is the name of the file
totalFileSize += fileDatas[i].length();
}

try {
fileContents = new byte[totalFileSize];
InputStream inStream;
for (int j = 0; j < totalFile; j++) {
inStream = new BufferedInputStream(new FileInputStream(fileDatas[j]));
filePartUploadSize = (int) fileDatas[j].length();
inStream.read(fileContents, tempFileSize, filePartUploadSize);
tempFileSize += filePartUploadSize;
inStream.close();
}
} catch (FileNotFoundException ex) {
throw new AppException(AppExceptionCode.FILE_NOT_FOUND);
} catch (IOException ex) {
throw new AppException(AppExceptionCode.ERROR_ON_MERGE_FILE);
} finally {
write(fileContents, outputFile);
for (int l = 0; l < totalFile; l++) {
fileDatas[l].delete();
}
}
}

请再次说明这种方法的“低效”……只有不能使用这种方法合并的大文件,较小的文件 (< 1 GB) 完全没问题……如果您不建议我增加堆内存,而是告诉我此方法的基本错误,我将不胜感激……谢谢……

谢谢

最佳答案

没有必要通过声明整个大小的字节数组来在内存中分配整个文件大小。一般来说,在内存中构建连接文件是完全没有必要的。

只需为您的目标文件打开一个输出流,然后对于您要合并的每个文件,只需将每个文件作为输入流读取并将字节写入输出流,完成后关闭每个文件。然后,当您完成所有操作后,关闭输出文件。缓冲区的总内存使用量为几千字节。

此外,不要在 finally block 中执行 I/O 操作(关闭和填充除外)。

这是一个您可以尝试的粗略示例。

        ArrayList<File> files = new ArrayList<>();// put your files here
File output = new File("yourfilename");
BufferedOutputStream boss = null;
try
{
boss = new BufferedOutputStream(new FileOutputStream(output));
for (File file : files)
{
BufferedInputStream bis = null;
try
{
bis = new BufferedInputStream(new FileInputStream(file));
boolean done = false;
while (!done)
{
int data = bis.read();
boss.write(data);
done = data < 0;
}
}
catch (Exception e)
{
//do error handling stuff, log it maybe?
}
finally
{
try
{
bis.close();//do this in a try catch just in case
}
catch (Exception e)
{
//handle this
}
}
}
} catch (Exception e)
{
//handle this
}
finally
{
try
{
boss.close();
}
catch (Exception e) {
//handle this
}
}

关于Java OutOfMemoryError 同时从分块文件中合并大文件部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34823874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com