将SQL二进制内容转换为文件

时间:2018-05-23 22:38:56

标签: sql coldfusion hex varbinarymax

我有一个SQL Server数据库,它将文件内容存储在表中。具体来说,有两个领域:

  • 内容:varbinary(max)字段始终以' 0x1F开头.....'

  • FileType:varchar(5)具有文件类型的字段,例如PDF,docx等。

如何将内容转换回文件?我试图使用Coldfusion,如果可能的话,转换它。如果没有,将二进制文件转换为文件的步骤是什么?

我尝试了以下(假设docx文件类型),但它没有生成有效的word文件:

<cfset DecodedValue = BinaryDecode(contents,"hex")>
<cffile action="WRITE" output="#DecodedValue#" file="C:\decodedfile.docx">

2 个答案:

答案 0 :(得分:3)

感谢用户Ageax,前面的4个大小字节31,-117,8,0显示内容以GZIP格式存储。

我首先将内容保存为gzip,然后解压缩文件。我的代码如下:

<cfquery name="getfile" datasource="tempdb">
select content from table
</cfquery>

<cfset FileWrite("C:\mygzipfile.gzip", getfile.content)>

要使用coldfusion将gzip提取到文件,我使用了以下解决方案:http://coldfusion-tip.blogspot.com/2012/04/unzip-gz-file-in-coldfusion.html

答案 1 :(得分:2)

<强> tldr;

数据已经是二进制的,因此抛弃binaryX()函数并将内容直接保存到文件中。读取二进制文件的前几个字节以验证文件类型。在这种情况下,结果文件实际上是以GZIP格式存储的,而不是原始的DOCX。

不要被SSMS如何选择显示它所误导。 SSMS以用户友好的十六进制格式显示二进制文件,但它仍然以二进制形式存储。只需将二进制文件直接写入文件,无需任何BinaryX函数。

<cfset FileWrite("C:\decodedfile.docx", contents)>

此外,检查您的DSN设置并确保启用“ BLOB - 启用二进制大对象检索(BLOB)”设置,因此二进制值不会在64K(默认缓冲区大小)处截断。

更新1:

如果“contents”列包含有效.docx文件的二进制文件,则上面的FileWrite()代码可以正常工作。也许数据的存储方式与我们的想法不同?运行查询以检索单个文档的二进制文件并输出前四个字节。结果是什么?通常,the first four bytes of .docx files应为80, 75, 3, 4

<!--- print size and first 4 bytes --->
<cfoutput>
    size in bytes = #arrayLen(qYourQuery.contents)#<br>
    <cfloop from="1" to="4" index="x">
        byte #x# = #qYourQuery.contents[1][x]#<br>
    </cfloop>
</cfoutput>

更新2:

我可以找到1F 8B 08最近的是GZIP。尝试在保存的文件上使用probeContentType()。它报道了什么?

<cfscript>
    paths = createObject("java", "java.nio.file.Paths");
    files = createObject("java", "java.nio.file.Files");
    input = paths.get("c:/yourFileName.docx", []);
    writeDump(files.probeContentType(input));
</cfscript>