oak-general-business/es/utils/files/slice.js

93 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import assert from "assert";
import { OakUploadException } from '../../types/Exception';
// 辅助方法:将文件切片
export async function sliceFile(file, chunkSize, partCount) {
if (process.env.OAK_PLATFORM === 'wechatMp') {
// 微信小程序环境下file 可能是临时文件路径字符串
if (typeof file === 'string') {
return sliceFileForMp(file, chunkSize, partCount);
}
else {
assert(false, '小程序环境下得到不为string的文件');
}
}
assert(file instanceof File, '分片上传仅支持 File 类型的文件');
const chunks = [];
for (let i = 0; i < partCount; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
chunks.push(file.slice(start, end));
}
return chunks;
}
// 小程序环境下的文件分片
export async function sliceFileForMp(filePath, chunkSize, partCount) {
const fs = wx.getFileSystemManager();
const tempDir = `${wx.env.USER_DATA_PATH}/oak_upload_temp`;
assert(chunkSize <= 10 * 1024 * 1024, '小程序下,单个分片大小不能超过 10MB'); // 微信小程序限制单个文件不能超过10MB
// 确保临时目录存在
try {
fs.accessSync(tempDir);
}
catch (e) {
fs.mkdirSync(tempDir, false);
}
const chunks = [];
// 读取文件信息
const fileStat = fs.statSync(filePath);
assert(!Array.isArray(fileStat), '无法获取文件信息');
const fileSize = fileStat.size;
// 读取每个分片并写入临时文件
for (let i = 0; i < partCount; i++) {
const start = i * chunkSize;
const length = Math.min(chunkSize, fileSize - start);
try {
// 读取分片数据
const data = await new Promise((resolve, reject) => {
fs.readFile({
filePath: filePath,
encoding: 'binary',
position: start,
length: length,
success: (res) => resolve(res.data),
fail: reject
});
});
// 写入临时文件
const tempFilePath = `${tempDir}/chunk_${Date.now()}_${i}.temp`;
await new Promise((resolve, reject) => {
fs.writeFile({
filePath: tempFilePath,
encoding: 'binary',
data: data,
success: () => resolve(),
fail: reject
});
});
chunks.push(tempFilePath);
}
catch (err) {
console.error('分片读取失败:', err);
// 清理已创建的临时文件
await cleanTempFiles(chunks);
throw new OakUploadException(`分片 ${i + 1} 读取失败: ${err}`);
}
}
return chunks;
}
// 清理临时文件
export async function cleanTempFiles(tempFiles) {
if (process.env.OAK_PLATFORM !== 'wechatMp') {
return;
}
const fs = wx.getFileSystemManager();
for (const filePath of tempFiles) {
try {
fs.unlinkSync(filePath);
}
catch (err) {
console.warn(`清理临时文件失败: ${filePath}`, err);
}
}
}