救命,用MyDAC的存储文件到Blob字段问题!(200分)

H

hehuan

Unregistered / Unconfirmed
GUEST, unregistred user!
救命,用MyDAC的存储文件到Blob字段问题!<br><br>小弟使用WinXP+Delphi7+Mysql开发一套管理软件,用的是MyDAC v5.10读取Mysql。是从这里下载的Full Source版本:<br>http://www.2ccc.com/article.asp?articleid=4280 <br><br>本来觉得非常好用,但是由于业务需要,把mysql的latin1字符集改成了utf8。<br>原来在latin1下读取blob字段都没有问题,但是自从改成了utf8以后,别的都非常好用,但是我现在发现MyDAC在utf8字符集下读取blob字段有问题,两个症状如下:<br>1. 在硬盘上一个30.5K的文件存到数据库里居然有61K,正好翻倍!<br>&nbsp; &nbsp;很明显,MyDAC把blob的每一个字节像处理普通文本一样,把它从ANSI转成Unicode再存入到数据库中!但这是错误的!<br>2. 从硬盘上读取一个Jpg文件,用MyDAC存到数据库的Blob字段中,Delphi就报错!错误停在MyDAC源代码的MemData.pas里的这个函数的raise Exception.Create(SInvalidBlobPosition);语句,整个函数如下:<br><br>function TBlob.TranslatePosition(Position: integer): integer; // Ansi to Unicode<br>var<br>&nbsp; Piece: PPieceHeader;<br>&nbsp; CurPosAnsi, CurPosUni, i: integer;<br>&nbsp; p: IntPtr;<br>&nbsp; w: WideString;<br>&nbsp; s: string;<br>begin<br>&nbsp; Assert(FIsUnicode);<br><br>&nbsp; if {$IFNDEF CLR}not SysLocale.FarEast{$ELSE}(LeadBytes = []){$ENDIF} or (Position = 0) then begin<br>&nbsp; &nbsp; Result := Position * 2;<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br><br>&nbsp; CurPosAnsi := 0;<br>&nbsp; CurPosUni := 0;<br>&nbsp; Piece := FFirstPiece;<br>&nbsp; while IntPtr(Piece) &lt;&gt; nil do begin<br>&nbsp; &nbsp; p := IntPtr(Integer(Piece) + Sizeof(TPieceHeader));<br>&nbsp; &nbsp; for i := 0 to Cardinal((Piece.Used div 2) - 1) do begin<br>&nbsp; &nbsp; &nbsp; w := Marshal.PtrToStringUni(IntPtr(Integer(p) + i * 2), 1);<br>&nbsp; &nbsp; &nbsp; s := w;<br>&nbsp; &nbsp; &nbsp; Inc(CurPosUni, 2);<br>&nbsp; &nbsp; &nbsp; Inc(CurPosAnsi, Length(s));<br>&nbsp; &nbsp; &nbsp; if CurPosAnsi = Position then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Result := CurPosUni;<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; if CurPosAnsi &gt; Position then<br>&nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create(SInvalidBlobPosition);<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Piece := Piece.Next;<br>&nbsp; end;<br>&nbsp; raise Exception.Create(SInvalidBlobPosition);<br>end;<br><br><br>这个问题,我认为是MyDAC的一个bug,没想到收费的专业控件也这么水啊。但是小弟对Delphi理解不深刻,只会用它编一些简单的数据库软件,所以没法改这个MyDAC的源代码。哪位大哥可以帮我想想这个问题怎么解决?有能力的不妨改改MyDAC源代码试试。非常感谢!<br><br>如果需要我的测试程序,请留下EMAIL,我发给你们。再次感谢!!<br><br>注意,如果MyDAC想要读取utf8字符集的话,需要把TMyConnection的Options属性的Charset设为utf8,同时把Options属性的UseUnicode设为True。这步必不可少,否则它不会按照utf8的编码去读取数据库,这样读出来的数据当然不能正确显示!设定完毕以后,处理一般各种语言的文本没有任何问题,唯独不能正确存储Blob字段!
 
将TBlobField.Transliterate:=false
 
with ADOPhoto do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Close;<br>&nbsp; &nbsp; &nbsp; &nbsp; SQL.Clear;<br>&nbsp; &nbsp; &nbsp; &nbsp; SQL.Add('SELECT * FROM pub_photo');<br>&nbsp; &nbsp; &nbsp; &nbsp; Open;<br>&nbsp; &nbsp; &nbsp; &nbsp; Append;<br>&nbsp; &nbsp; &nbsp; &nbsp; if FileExists(PubContenuPage.Text) then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TBlobField(FieldByName(strPhotoBlob)).Transliterate:=false;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TBlobField(FieldByName(strPhotoBlob)).LoadFromFile(PubContenuPage.Text);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; Post;<br>&nbsp; &nbsp; &nbsp; &nbsp; ShowMessage('&amp;acute;&amp;aelig;&amp;acute;&amp;cent;&amp;Icirc;&amp;Auml;&amp;frac14;&amp;thorn;&amp;micro;&amp;frac12; °&amp;aelig;&amp;Atilde;&amp;aelig;'+strPhotoBlob +'&amp;sup3;&amp;Eacute;&amp;sup1;&amp;brvbar;&amp;pound;&amp;iexcl;');<br>&nbsp; &nbsp; end;<br><br>我试了一下,把那个30.5K的word文件存进去之后,再读取出来变成30.8K,而且Word根本不认这个文件的内容。<br><br>并且症状2仍然存在:(<br>. 从硬盘上读取一个Jpg文件,用MyDAC存到数据库的Blob字段中,Delphi就报错!错误停在MyDAC源代码的MemData.pas里的这个函数的raise Exception.Create(SInvalidBlobPosition);语句<br><br>请再次指教,非常感谢!!
 
路过..学习..
 

Similar threads

顶部