成功将文件上传到MySQL中的字节数组,但是下载时内容不可读

Posted

技术标签:

【中文标题】成功将文件上传到MySQL中的字节数组,但是下载时内容不可读【英文标题】:Upload a file to byte array in MySQL successfully, however the content is not readable when download 【发布时间】:2020-12-11 14:56:14 【问题描述】:

在我使用 javascript XMLHttpRequest 中的 FormData 上传文件并连接到 Web API 并将其作为 LONGBLOB 数据类型保存到 mysql DB 后,我在下载内容时遇到问题。当我尝试将之前作为 BLOB 上传的文件下载到 MySQL DB 时,正在下载该文件,但是该文件不再可读。有什么解决办法吗?

这是我用于将文件作为字节数组上传到数据库的代码:

HTML 和 Javascript
<input id="Upload" type="file" accept="application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/pdf" />
let SubmittedData = new FormData();
let XHR = new XMLHttpRequest();

SubmittedData.append("FileContent", $("#Upload").files[0]);

XHR.open("POST", "/UploadFile");
XHR.send(SubmittedData);
XHR.onreadystatechange = function () 
    if (XHR.readyState == 4 && XHR.status == 200)
        alert("Success");

Web API:
[HttpPost]
public ActionResult UploadFile()

    if (Request.Files.Count <= 0)
        return Ok();

    byte[] FileContent = new byte[0];

    using (var reader = new BinaryReader(Request.Files[0].InputStream))
        FileContent = reader.ReadBytes(Request.Files[0].ContentLength);

    InsertToMySQLDB(FileContent);

    return Ok()

这是我用于从 DB 中检索字节数组并将其下载为 PDF 的代码(我在 NuGet 中使用 htmlToPDF 库以下载为 PDF)和 Word:

public ActionResult DownloadPDF()

    byte[] FileContent = RetrieveFileContentFromMySQLDB();

    return File(FileContent, "application/pdf", "File.pdf");


public ActionResult DownloadWord()

    byte[] FileContent = RetrieveFileContentFromMySQLDB();

    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("Content-Disposition", $"attachment;filename=File.doc");
    Response.Charset = string.Empty;
    Response.ContentType = "application/vnd.ms-word";
    Response.Output.Write(Encoding.Default.GetString(FileContent, 0, FileContent.Length));
    Response.Flush();
    Response.End();
    break;
)

编辑:

现在还有一个问题,场景是:

当我上传PDF文件并将其下载为PDF时,可以下载,内容与我之前上传的相同,但是当我尝试将其下载为Word时,它正在下载,但内容只是所有的十六进制字符。

当我上传 Word 文件并下载为 PDF 时,无法下载(文件已损坏),当我下载为 Word 时,正在下载,但内容全是十六进制字符。

任何转换的解决方案?

非常感谢

【问题讨论】:

您能否显示 MySQL 在选择 blob 时将返回的 left(hex(id),16),以验证 PDF 是否正确存储? (参见:this)长度为 16 以显示 8 个字节,因为可能存在 BOM。 嗨@Luuk,这是我尝试SELECT LEFT(HEX(FileContent), 16) 时的数据,其中FileContentLONGBLOB 数据类型:504B030414000600 我希望504446 在那个字符串中,所以我认为您的 PDF 存储不正确,这会使阅读变得困难...... ???? (或者您不小心选择了不是 PDF 的文档) 嗨@Luuk,对不起,我上传了不是PDF的,在我上传PDF并在MySQL中选择语句后,这里是数据:255044462D312E34 好的,结论是PDF似乎正确存储在MySQL中,因为第一个字节显示'%PDF',或十六进制26504446 【参考方案1】:

我认为您可以将DownloadPDF() 更改为:

public ActionResult DownloadPDF()

    byte[] FileContent = RetrieveFileContentFromMySQLDB();

    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("Content-Disposition", $"attachment;filename=File.pdf");
    Response.Charset = string.Empty;
    Response.ContentType = "application/pdf";
    Response.Output.Write(Encoding.Default.GetString(FileContent, 0, FileContent.Length));
    Response.Flush();
    Response.End();
    break;

上面(几乎)与DownloadWord() 相同。区别在于标题“Content-Disposition”和“Content-Type”。

【讨论】:

嗨@Luuk,我已经尝试了DownloadPDF() 的上述解决方案,但是它没有按预期工作(正在下载文件,但是即使我上传文件它也只显示白页(PDF)有内容而不是白页)。现在还有另一个问题: - 当我用 .doc 或 .docx 上传文件并将文件下载为 PDF 时,它正在下载,但无法打开(文件已损坏),当我下载文件时也是如此作为Word,它正在下载,但内容就像所有十六进制字符一样。有关更多信息,请参阅我编辑过的上述问题 仅存储一个 PDF 文件,然后以“Word”形式下载它不会转换文档。还存储一个 Word 文件,然后以“PDF 格式”下载它不会转换它! 嗨@Luuk,非常感谢你,你知道有什么转换方法吗? 有许多不同的工具可以将 Word 文档转换为 PDF。从 PDF 到 Word 更难,因为一些 PDF 文档只包含图像,这更难转换为 Word 嗨@Luuk,好的,我会做解决方法,将文件扩展名存储到数据库中,一旦用户想要将其下载到另一个(假设:存储单词扩展名,和用户点击下载为PDF),然后我将做从Word到HTML的转换,然后将其转换回PDF,反之亦然。这能解决问题吗?

以上是关于成功将文件上传到MySQL中的字节数组,但是下载时内容不可读的主要内容,如果未能解决你的问题,请参考以下文章

上传图像/文件并将其转换为 mysql 数据库

ios将图像上传到Firebase但是当我尝试下载时却不是这样吗?

C# 中的 FileNotFoundException

通过 Flutter App 的 PreSigned URL 将文件上传到 S3。但是当我下载它时文件已损坏

将文件加载为字节数组,而不在内存中分配它 C#

上传文件并将文件名保存在 MySQL 数据库中