将文件数组拆分为n个块

cclgggtu  于 2021-09-23  发布在  Java
关注(0)|答案(2)|浏览(307)

我有一个文件数组,我必须根据文件大小将其拆分为块,方法如下:
最大大小为20mb的[10mb图像、5mb图像、5mb图像]实际上不需要拆分,但[10mb、10mb、15mb]将拆分为[10mb、10mb]和[15mb]
然后我需要一个函数,它将文件放入formdata中,然后将其发送到端点。
我要做的是返回一个 FormData 包含所需的块。
我怎样才能做到这一点?
这是当前的功能:

const newImagesToEndpoint = (newFiles: NewImagesInterface[]) => {
    const newImages = new FormData();
    newFiles.forEach(img => {
      newImages.append('images[]', (img.file as unknown) as File);
    });
    return newImages;
  };
rkttyhzu

rkttyhzu1#

你的问题不是很清楚。我理解您所说的拆分是指通过多个http调用从客户端发送到服务器,而不是拆分单个文件?
假设 NewImagesInterface 有一个 size: number 菲尔德,像这样的吗?

function sendChunks(images: NewImagesInterface[], limit = 20e6): FormData[] {
  const out: FormData[] = [], chunkSize = 0;
  for(const img of images) {
    if(img.size > limit)
      throw new Error('each individual image must be < ' + limit);
    if(!out.length || chunkSize + img.size > limit) {
      chunkSize = 0;
      out.push(new FormData[]);
    }
    out[out.length-1].append('images[]', (img.file as unknown) as File);
    chunkSize += img.size;
    return out;
};

另外,请注意类型,这毕竟是typescript的要点。如果要输出 FormData 那么函数的返回类型必须是 FormData[] . 这意味着您的函数将在某个时候构建并返回一个数组。如果您这样想,从类型需求开始,并将其应用于如何构建代码,它将帮助您找到解决方案。

imzjd6km

imzjd6km2#

这是我很快想出的一个算法。这是一种贪婪算法,按大小desc排序,然后迭代排序后的数组,并将文件“打包”到具有剩余可用性的数组中。最后,它将中间结果Map到只包含块的数组。
注意:显然,您需要对此进行调整,以实际使用文件数组并正确计算和比较文件大小。

const MAX_CHUNK_SIZE = 20;

const chunkFiles = (filesArray) =>
  filesArray
    .slice()
    .sort((a, b) => b.size - a.size)
    .reduce((chunks, file) => {
      const chunk = chunks.find((chunk) => chunk.available >= file.size);

      if (chunk) {
        chunk.array.push(file);
        chunk.available -= file.size;
      } else {
        chunks.push({
          array: [file],
          available: MAX_CHUNK_SIZE - file.size
        });
      }
      return chunks;
    }, [])
    .map(({ array }) => array);

const filesToProcess = [
  [{ size: 10 }, { size: 5 }, { size: 5 }],
  [{ size: 10 }, { size: 10 }, { size: 15 }],
  [{ size: 10 }, { size: 3 }, { size: 7 }, { size: 10 }, { size: 15 }]
];

filesToProcess.forEach((files, i) => {
  const chunks = chunkFiles(files);
  console.log(JSON.stringify(chunks));
});

这些文件块数组可以传递给您的 newImagesToEndpoint 效用。

相关问题