在 SQL Server 数据库中保存文件 base64 字符串

Posted

技术标签:

【中文标题】在 SQL Server 数据库中保存文件 base64 字符串【英文标题】:Saving file base64 string in SQL Server database 【发布时间】:2020-02-13 21:29:20 【问题描述】:

我正在处理文件上传,上传时文件被转换为 base64 字符串,该字符串被发送到 API,该 API 将字符串保存在 SQL Server 数据库表中。

表中base64字符串列的类型是NVARCHAR(MAX),但我注意到保存文件时,SQL会截断字符串,这样当您使用base64在线转换为图像解码器时,它只会产生整个图片的一部分我注意到在保存到 SQL 之前的 base64 字符串的字符数约为 72,000,但在保存 SQL 后,它减少到约 4,000,这是解码不完整图像的原因。

为什么 SQL 会截断 base64 字符串,我可以做些什么来帮助解决我的情况?

这是我的base64转换代码:

public async Task<IActionResult> UploadFile()

    string base64string;
    var myFile = Request.Form.Files["claimFile"];
    var filetype = myFile.ContentType;
    var filepath = Path.GetTempFileName();
    using (var stream = System.IO.File.Create(filepath))
    
        await myFile.CopyToAsync(stream);
    
    byte[] imageByte = System.IO.File.ReadAllBytes(filepath);
    base64string = Convert.ToBase64String(imageByte);
    HttpContext.Session.SetString("Base64Str", base64string);
    return new EmptyResult();

【问题讨论】:

不是截断它,Base64 只是文本(ASCII 编码)。保存为VARCHAR(MAX),Base64没有数字。 听起来像是您的数据库映射层正在截断或数据库本身正在截断值。 4000 是 nvarchar 受限制时的最大限制(不是最大值),因此您的数据库值具有 4000 个字符这一事实并非巧合。不过,没有理由使用 nvarchar,而是使用 varchar。 如何将结果写入数据库? 不相关 - 为什么先写入文件,然后写入会话变量?还有为什么要写入会话变量? 如何从 SQL 中获取 base64?通过 SSMS? SSMS 可能只显示前 8000 个字符,即使完整值在数据库中。请参阅:***.com/questions/11897950/…(例如)。尝试将数据写入文件并从那里打开。 【参考方案1】:

我怀疑问题可能在于,通过指定 NVARCHAR(16 字节字符),您无意中“破坏”了字符串。

两个建议:

    将列重新定义为VARCHAR(MAX)

    保存一个 uuencoded 字符串,然后读回文本并查看保存/检索的字符串值是否匹配。

看这里:

https://dba.stackexchange.com/questions/212160/why-do-i-get-incorrect-characters-when-decoding-a-base64-string-to-nvarchar-in-s

请发回你找到的东西!

另外——出于好奇——你最初是如何进行 Base64 编码的?

【讨论】:

感谢您的回复我已经用编码逻辑更新了我的问题,我也尝试使用 VAR(MAx),字符串被截断为 8000 个字符数 所以您正在对 C#/.Net 字符串进行 uuencoding。问:您在哪里将该字符串写入 MSSQL?你为什么要关心会话变量?你不能把你的base64字符串传给一个可以直接写入数据库的对象吗? 我存储在会话中,因为我的更新控制器在另一个类中,我检索它并将其传递给模型类对象,然后我将其发送到 Api,我没有源代码api,但是在调试时,就在对象进入更新 api 端点之前,我从对象中检索了值并且它是正确的字符数,我什至尝试将其图像转换回在线,它给了我正确的图像 我已将数据库列的数据类型更改为 VARCHAR(MAX),我只是注意到,如果我运行查询以获取字符串并从结果中复制它,我会得到一个截断的字符串,但是如果我右键单击表格并“编辑前 200 行”并转到该特定的 base64 字符串,但如果我 Ctrl+A 和 Ctrl+C 输入框显示为空,我将获得完整的 base64 字符串,我已将其转换为正确的图片。即使在我的应用程序中,我已经向 api 发出了 base64 字符串的获取请求,并且得到的字符串也是完整的,我也对其进行了测试。【参考方案2】:

我读和写到 db 但到 nText 列类型与以下就好了:如果需要,您可以从 vb.net 转换为 c#。

#Region "write/read files to db"

Public Function SaveToDB(ByVal fullfilename As String) As String
    Dim filedata = Convert.ToBase64String(File.ReadAllBytes(fullfilename))
    Return filedata
End Function

Public Function LoadFromDB(ByVal filedata As String, ByVal fullfilename As String) As String
    Dim filepath As String = (fullfilename)
    File.WriteAllBytes(filepath, Convert.FromBase64String(filedata))
    Return filepath
End Function

#结束区域

【讨论】:

以上是关于在 SQL Server 数据库中保存文件 base64 字符串的主要内容,如果未能解决你的问题,请参考以下文章

UWP 文件缩略图保存在 SQL Server 数据库中

如何从 SQL Server 表中读取图像数据(存储 word 文档)并将其保存到本地文件夹

sql server2008中的FILESTREAM

sql server2008中的FILESTREAM

在sql server 2005中保存其他国家特殊字符

SQL Server FileStream (转载)