Mac下ASP.NET MVC应用用Aspose.Pdf读取上传PDF提示文件不存在
问题分析与解决建议
问题根源
你直接使用formFile.FileName拼接全路径的方式是错误的:IFormFile是客户端上传的流式文件,服务器端并没有自动将文件保存到Path.GetFullPath(formFile.FileName)这个路径——这个路径只是客户端上传时的文件名,服务器本地不存在该文件(或存在的是无关文件),因此Aspose.Pdf调用Document构造函数时会抛出文件未找到异常。
解决方案
提供两种可行的处理方式,按需选择:
方案1:先保存上传文件到服务器目录再处理
将上传的文件先保存到服务器的临时目录(或自定义目录),再用保存后的路径初始化Aspose.Pdf的Document:
[HttpPost] public IActionResult Index(List<IFormFile> files) { PassData localMessage = new PassData(); localMessage.SendMessage = "Your file failed to convert"; if (files == null || files.Count == 0) { return View(localMessage); } // 创建服务器临时上传目录 var tempDir = Path.Combine(Directory.GetCurrentDirectory(), "TempUploads"); if (!Directory.Exists(tempDir)) { Directory.CreateDirectory(tempDir); } foreach (var formFile in files) { if (formFile.Length == 0) continue; // 生成唯一文件名,避免重名覆盖 var uniqueFileName = Guid.NewGuid().ToString() + Path.GetExtension(formFile.FileName); var savePath = Path.Combine(tempDir, uniqueFileName); // 保存上传文件到服务器 using (var stream = new FileStream(savePath, FileMode.Create)) { formFile.CopyTo(stream); } try { // 用保存后的路径打开PDF文档 Document pdfDocument = new Document(savePath); TextAbsorber textAbsorber = new TextAbsorber( new TextExtractionOptions(TextExtractionOptions.TextFormattingMode.Pure), new TextSearchOptions(new Rectangle(5, 5, 50, 50)) ); pdfDocument.Pages.Accept(textAbsorber); string extractedText = textAbsorber.Text; if (!string.IsNullOrEmpty(extractedText)) { localMessage.SendMessage = $"File {formFile.FileName} converted successfully"; // 将提取的文本保存为TXT文件 var txtSavePath = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(uniqueFileName) + ".txt"); File.WriteAllText(txtSavePath, extractedText); } } catch (Exception ex) { localMessage.SendMessage = $"File {formFile.FileName} failed: {ex.Message}"; } finally { // 可选:处理完成后删除临时PDF文件 if (System.IO.File.Exists(savePath)) { System.IO.File.Delete(savePath); } } } // 将处理结果传递给视图 return View(localMessage); }
方案2:直接通过文件流处理(无需本地保存,更高效)
Aspose.Pdf支持直接从流初始化Document,跳过本地保存步骤,直接处理上传的文件流:
[HttpPost] public IActionResult Index(List<IFormFile> files) { PassData localMessage = new PassData(); localMessage.SendMessage = "Your file failed to convert"; if (files == null || files.Count == 0) { return View(localMessage); } // 创建转换后TXT文件的保存目录 var txtSaveDir = Path.Combine(Directory.GetCurrentDirectory(), "ConvertedTexts"); if (!Directory.Exists(txtSaveDir)) { Directory.CreateDirectory(txtSaveDir); } foreach (var formFile in files) { if (formFile.Length == 0) continue; try { // 直接通过上传文件的流初始化Document using (var stream = formFile.OpenReadStream()) { Document pdfDocument = new Document(stream); TextAbsorber textAbsorber = new TextAbsorber( new TextExtractionOptions(TextExtractionOptions.TextFormattingMode.Pure), new TextSearchOptions(new Rectangle(5, 5, 50, 50)) ); pdfDocument.Pages.Accept(textAbsorber); string extractedText = textAbsorber.Text; if (!string.IsNullOrEmpty(extractedText)) { localMessage.SendMessage = $"File {formFile.FileName} converted successfully"; // 保存提取的文本为TXT文件 var txtSavePath = Path.Combine(txtSaveDir, Path.GetFileNameWithoutExtension(formFile.FileName) + ".txt"); File.WriteAllText(txtSavePath, extractedText); } } } catch (Exception ex) { localMessage.SendMessage = $"File {formFile.FileName} failed: {ex.Message}"; } } return View(localMessage); }
额外注意事项
- 原代码中
return View();未传递localMessage,导致前端@Model.SendMessage无法显示处理结果,修改后需传递模型给视图。 - 若处理多文件,当前代码会覆盖消息,建议改为拼接每个文件的处理状态(比如用列表存储),再传递给视图展示。
- Mac系统下路径分隔符为
/,使用Path.Combine会自动适配系统,避免硬编码路径。 - 确保使用最新版本的Aspose.Pdf包,避免版本兼容问题。
内容的提问来源于stack exchange,提问作者Jonathan Small
相关产品推荐
相关产品推荐

