Delphi:如何有效地读取大的二进制文件,将其转换为十六进制以将其作为 varbinary(max) 参数传递?
我需要将二进制文件(zip 文件)转换为十六进制表示形式,然后将其作为 varbinary(max) 函数参数发送到 sql-server。
一个完整的例子(使用一个非常小的文件!)是:
1)我的文件包含以下位0000111100001111
2)我需要一个程序将其快速转换为0F0F
3)我将调用一个sql服务器函数,传递0x0F0F
作为参数
问题是我有大文件(最多100MB,即使平均文件大小是100KB文件也是可能的),所以我需要最快的方法做这个。
创建字符串
'0x'+BinaryDataInHexadecimalRepresentation
否则说明:我需要以最有效的方式 。 (注意:可能有一种方法可以立即打开文件并获取十六进制字符串,因此在这种情况下,我需要的只是使用“这种方式”(如果有的话)。
相关问题: 传递十六进制数据到sql server
更新:阅读评论后我认为有必要在这里添加更多信息。我尝试使用 T-SQL 文本命令将二进制数据发送到存储过程的原因是,通过这种方式,我消除了服务器的一些开销:存储过程接收二进制数据并将其写入文件(此是我的最终目标)。如果我使用 DAC 组件,我将能够轻松地将 biray 数据发送到服务器,但在这种情况下,我需要使用临时表来存储数据,然后将此数据发送到写入文件的存储过程。
所以想法是:
1)使用T-SQL“长”命令:客户端的开销更大,因为我需要读取文件并将其转换为十六进制以准备长命令;服务器开销更少,因为 sql server 只是接收二进制数据并在存储函数中处理它
2) 使用 DAC:我需要传递 sql server 中的临时表,因此服务器上的开销更多,
因为我将服务器用作 web文档服务器(这是一个技巧),我想尝试减少服务器的开销。无论如何,我可能错了,(2)无论如何是比(1)更好的技术
I need to convert a binary file (a zip file) into hexadecimal representation, to then send it to sql-server as a varbinary(max) function parameter.
A full example (using a very small file!) is:
1) my file contains the following bits 0000111100001111
2) I need a procedure to QUICKLY convert it to 0F0F
3) I will call a sql server function passing 0x0F0F
as parameter
The problem is that I have large files (up to 100MB, even if average file size is 100KB files are possible), so I need the fastest way to do this.
Otherwise stated: I need to create the string
'0x'+BinaryDataInHexadecimalRepresentation
in the most efficient way. (Note: may be there is a way to immediately open a file and obtain an hexadecimal string, so in this case all I need is to use "this way", if it is there).
Related question: passing hexadecimal data to sql server
UPDATE: after reading the comments I think it is needed to add more information here. The reason why I try to use a T-SQL text command to send the binary data to the stored procedure is that in this way I remove some overhead to the server: the stored prcoedure recieves the binary data and writes it to a file (this is my final goal). If I use a DAC component I will be able to easily send the biray data to the server, but in that case I need to use a temp table to store the data, and then sending this data to the storedprocedure that writes the file.
So the idea is:
1) using T-SQL "long" command: more overhead on client because I need to read the file and convert it to hexadecimal to preparing the long command; less server overhead since sql server just recieves the binary data and processes it in the stored function
2) using DAC: I need to pass through a temp table in sql server, therefore having more overhead on the server
Since I am using the server as web document server (it's a trick), I want to try to reduce the overhead on the server. Anyway may be I am wrong and (2) anyway is a better technique than (1)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,这是一个可以以我能想到的速度完成转换的选项。
代码的特点:
由于我们知道一个字节恰好转换为两个十六进制字符,因此我们知道结果字符串需要恰好是文件大小的两倍。我们分配所需大小的字符串,然后以足够大的块从文件中读取,以便操作系统可以为我们优化它(逐字节读取是邪恶的)。我们使用实际的字符串,但我们使用指针写入字符串:
PS:我使用 AnsiString 和 PAnsiChar,因此代码也适用于 Unicode Delphi。如果您碰巧使用的是 Delphi 2010,请找到一种方法以当前形式 (AnsiString) 使用它,这样您就可以跳过转换。
Well here's a option that would do the conversion as fast as I can think of.
Features of the code:
Since we know that one byte translates to exactly two hexadecimal chars, we know our result string needs to be exactly twice the size of the file. We allocate an string of the required size and then we read from the file in large-enough blocks so the OS can optimize it for us (reading byte-by-byte is evil). We use an actual string but we write into the string using an pointer:
P.S: I'm using AnsiString, and PAnsiChar so the code works also works with Unicode Delphi. If you happen to be on Delphi 2010 find a way to use this in it's current form (AnsiString) so you can skip the conversions.