将文件数组拆分为 N 个块

时间:2021-07-09 07:52:49

标签: javascript arrays reactjs typescript chunks

我有一个文件数组,我必须根据文件大小将其拆分成块,如下所示:

[10MB 图像、5MB 图像、5MB 图像] 最大大小为 20MB 不会真正需要拆分,但 [10MB、10MB、15MB] 将被拆分为 [10MB、10MB] 和 [15MB]

然后我必须执行获取文件并将它们放入表单数据以将其发送到端点的功能。

我想要做的是返回一个包含所需块的 FormData 数组。

我怎样才能做到这一点?

这是当前函数:

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

2 个答案:

答案 0 :(得分:1)

这是我很快想出的算法。这是一个有点贪心的算法,按大小 DESC 排序,然后迭代排序后的数组并将文件“打包”到具有剩余可用性的数组中。它最终将中间结果映射到只有块的数组。

注意:显然您需要调整它以实际使用您的文件数组并正确计算和比较文件大小。

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 实用程序。

答案 1 :(得分:1)

你的问题不是很清楚。我明白你的意思是拆分是通过多个 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;
};

还要注意类型,毕竟这是打字稿的重点。如果你想输出一个 FormData 数组,那么你的函数的返回类型必须是 FormData[]。这意味着您的函数将在某个时候构建并返回一个数组。如果您这样认为,从类型要求开始,并将它们应用到您构建代码的方式中,它将帮助您想出一个解决方案。

相关问题