You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask后端无法上传BAM文件:Argument must be string, bytes or unicode错误排查求助

Flask后端无法上传BAM文件:Argument must be string, bytes or unicode错误排查求助

我刚仔细看了你的代码,确实能发现几个可能导致最后一块上传失败、以及出现类型错误的问题,尤其是分块合并和文件对象/路径混用的部分,咱们一步步来理清楚:

1. 最可能触发"Argument must be string..."错误的核心问题:文件对象 vs 文件路径混淆

在你的Flask代码里,合并完完整文件后的函数调用存在明显的类型错误:

with open(complete_file_path, 'wb') as output_file:
    # ...分块合并代码...
if rcg.is_valid_bam(output_file):  # 这里传的是已打开的文件对象而非路径!
    sorted_bam = rcg.sort_and_index_bam(output_file)
else:
    coverage = rcg.calculate_full_coverage(output_file, mode)

output_file是一个已打开的文件句柄,但rcg.is_valid_bam这类工具函数大概率需要的是文件路径字符串(比如complete_file_path),而非打开的文件对象。把文件句柄传入时,函数内部会因类型不匹配抛出"Argument must be string, bytes or unicode"错误,这应该是你看到500错误的直接原因。

修复方案:
将所有需要文件路径的调用,替换为complete_file_path,并确保文件在调用前已关闭(with语句块结束后会自动关闭文件):

# 分块合并完成后,output_file已自动关闭
complete_file_path = os.path.join(UPLOAD_DIR, file_name)
with open(complete_file_path, 'wb') as output_file:
    for i in range(total_chunks):
        part_path = os.path.join(UPLOAD_DIR, f"{file_name}.part{i}")
        with open(part_path, 'rb') as part_file:
            output_file.write(part_file.read())
        os.remove(part_path)

# 传入文件路径而非文件对象调用工具函数
if rcg.is_valid_bam(complete_file_path):
    sorted_bam = rcg.sort_and_index_bam(complete_file_path)
    coverage = rcg.calculate_full_coverage(sorted_bam, mode)
else:
    coverage = rcg.calculate_full_coverage(complete_file_path, mode)

2. 分块上传的并发与判断逻辑漏洞

你前端同步发起所有分块的fetch请求,可能导致:

  • 服务器同时处理多个文件写入,最后一个chunk的文件还未完全保存到磁盘,后端就开始执行合并逻辑,读取到不完整的chunk文件
  • 分块数量判断不准确:len(uploaded_chunks) == total_chunks用startswith(file_name)匹配,若存在同名文件(如test.bam和test.bam.old)会误判分块数量,提前触发合并

修复方案:

后端:精确匹配分块文件

修改分块判断逻辑,避免误匹配:

# 原来的模糊匹配
# uploaded_chunks = [f for f in os.listdir(UPLOAD_DIR) if f.startswith(file_name)]
# 改成精确匹配分块文件名
expected_chunk_names = {f"{file_name}.part{i}" for i in range(total_chunks)}
uploaded_chunks = [f for f in os.listdir(UPLOAD_DIR) if f in expected_chunk_names]
if len(uploaded_chunks) == total_chunks:
    # 执行合并逻辑

前端:控制分块上传并发数,避免同时发起所有请求

将同步循环改为串行上传(或限制并发数),降低服务器压力:

// 先修复函数参数不匹配的问题:原来调用传3个参数,但定义只接1个
async function file_to_readdata(uploadedFile, mode, fileType) {
    const chunkSize = 10 * 1024 * 1024; // 10MB块
    const totalChunks = Math.ceil(uploadedFile.size / chunkSize);
    let uploadedChunks = 0;

    // 串行上传:完成一块再传下一块
    for (let i = 0; i < totalChunks; i++) {
        const start = i * chunkSize;
        const end = Math.min(start + chunkSize, uploadedFile.size);
        const chunk = uploadedFile.slice(start, end);

        console.log(`Uploading chunk ${i + 1}/${totalChunks}`);
        console.log("Chunk size:", chunk.size);

        const formData = new FormData();
        formData.append("chunk", chunk);
        formData.append("chunkIndex", i);
        formData.append("totalChunks", totalChunks);
        formData.append("fileName", uploadedFile.name);
        formData.append("mode", mode); // 新增:把mode传给后端

        try {
            const response = await fetch(`${$SCRIPT_ROOT}/_upload_file`, {
                method: "POST",
                body: formData,
            });
            const data = await response.json();
            console.log(data);
            if (data.status === "success") {
                uploadedChunks++;
                if (uploadedChunks === totalChunks) {
                    console.log("File upload complete");
                    // 可添加前端成功提示
                }
            } else {
                console.error(`Error uploading chunk ${i + 1}:`, data.message);
                break;
            }
        } catch (error) {
            console.error(`Error uploading chunk ${i + 1}:`, error);
            break;
        }
    }
}

3. 其他潜在问题

  • 参数传递缺失:前端原代码未将mode传入后端,导致request.form.get('mode')为None,可能触发后续计算逻辑错误(已在前端修复中补充)
  • 分块文件残留:若合并失败,分块文件会残留,可在except块中添加清理逻辑,删除已上传的分块文件
  • 文件权限:确保UPLOAD_DIR目录有足够的读写权限,避免分块保存或合并时出现权限错误

总结

最紧急的是修复文件对象误传为路径的问题,这直接触发了你看到的类型错误;其次控制前端上传并发数,避免服务器压力过载;最后修复参数传递和分块判断逻辑,应该就能解决最后一块上传失败的问题了。你可以先尝试这些修复,有新的错误信息或问题再反馈!

备注:内容来源于stack exchange,提问作者Ivar2001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:23:02