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

Azure Function v4音频上传临时目录报错及文件长度为0问题

解决Azure Function v4(JS/TS)线上临时目录文件操作报错及文件长度为0问题

核心问题分析

线上环境出现illegal operation on a directory, open 'C:\local\Temp\test.webm'错误且文件长度为0,本质是硬编码临时路径、流处理不完整、请求解析异常三类问题导致,本地与线上环境的文件系统权限、异步处理逻辑差异是主要诱因。


针对性解决方案

1. 避免硬编码临时目录路径

线上Azure Function的临时目录路径并非固定为C:\local\Temp,需通过环境变量动态获取:

  • 使用process.env.TEMP或process.env.TMP(跨平台兼容,Linux环境会返回/tmp)
  • 用path.join拼接安全的文件路径,避免路径解析错误

示例代码:

import * as path from 'path';

// 动态获取临时目录, fallback到/tmp确保跨平台兼容
const tempDir = process.env.TEMP || process.env.TMP || '/tmp';
const targetFilePath = path.join(tempDir, 'test.webm');

2. 确保文件流完整写入

本地同步逻辑可能掩盖异步流处理的问题,线上必须等待流写入完成再执行后续操作:

  • 使用stream/promises的pipeline方法(自动处理流的错误、关闭)
  • 或用fs.promises.writeFile配合文件流,确保写入完成

示例代码:

import * as fs from 'fs';
import { pipeline } from 'stream/promises';
import * as path from 'path';

async function saveAudioStream(fileStream: NodeJS.ReadableStream) {
  const tempDir = process.env.TEMP || '/tmp';
  const targetPath = path.join(tempDir, 'test.webm');
  // 用pipeline确保流完整写入,自动处理异常
  await pipeline(fileStream, fs.createWriteStream(targetPath));
  return targetPath;
}

3. 正确解析上传请求

线上环境可能因请求体解析配置错误,导致文件流为空:

  • 使用formidable等库解析multipart/form-data请求(Azure Function v4原生不自动解析文件上传)
  • 验证上传文件的存在性,避免空流写入

示例代码:

import { HttpRequest, InvocationContext } from "@azure/functions";
import * as formidable from 'formidable';
import * as fs from 'fs';
import * as path from 'path';

export async function audioUploadHandler(request: HttpRequest, context: InvocationContext) {
  // 解析multipart请求
  const form = formidable({ multiples: false });
  const [_, files] = await form.parse(request.rawBody);
  
  const audioFile = files.audio?.[0];
  if (!audioFile) {
    return { status: 400, body: '未上传音频文件' };
  }

  // 将上传的临时文件复制到目标临时路径
  const tempDir = process.env.TEMP || '/tmp';
  const targetPath = path.join(tempDir, audioFile.originalFilename || 'audio.webm');
  await fs.promises.copyFile(audioFile.filepath, targetPath);

  // 验证文件大小
  const fileStats = await fs.promises.stat(targetPath);
  context.log(`写入文件大小:${fileStats.size} bytes`);

  // 后续对接OpenAI逻辑...
  return { status: 200, body: '文件上传成功' };
}

4. 权限与路径校验

  • 不要尝试修改或创建临时目录本身,仅在目录内创建文件(Azure Function对临时目录有读写权限,但禁止目录级操作)
  • 确保文件名不含特殊字符(如/、\),避免路径被解析为目录

5. 日志调试辅助

在关键节点添加日志,排查线上问题:

context.log(`当前临时目录:${tempDir}`);
context.log(`目标文件路径:${targetPath}`);
context.log(`上传文件原始大小:${audioFile?.size || 0} bytes`);

通过Azure Portal的Function日志面板,查看路径、大小等信息,定位异常点。


内容的提问来源于stack exchange,提问作者Tkay Bay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:05:10