我使用了你回答的二进制转Base64函数:Binary to Base64 (Delphi)。
我成功地将文件编码为Base64字符串并写入MsSQL2008数据库,但我想问一个问题: 如何使用EncdDecd.pas再次将此文件写入磁盘?
我成功地将文件编码为Base64字符串并写入MsSQL2008数据库,但我想问一个问题: 如何使用EncdDecd.pas再次将此文件写入磁盘?
像往常一样,David的回答足够了。虽然我忍不住想提供一个稍微不同的解决方案,使用一些最近Delphi版本中的好东西。
procedure DecodeFile(const base64: AnsiString; const FileName: string);
var
stream: TBytesStream;
begin
stream := TBytesStream.Create(DecodeBase64(base64));
try
stream.SaveToFile(Filename);
finally
stream.Free;
end;
end;
这个函数将会接收一个base64编码的字符串,解码它,并将结果字节数组写入文件。
procedure DecodeToFile(const base64: AnsiString; const FileName: string);
var
stream: TFileStream;
bytes: TBytes;
begin
bytes := DecodeBase64(base64);
stream := TFileStream.Create(FileName, fmCreate);
try
if bytes<>nil then
stream.Write(bytes[0], Length(Bytes));
finally
stream.Free;
end;
end;
bytes := DecodeBase64(base64);
执行解码操作并将文件的解码二进制内容返回到TBytes
变量中。TBytes
只是一个字节数组。
下一步是创建文件。在Delphi中编写文件的惯用方式是使用流。在这种情况下,我们需要一个TFileStream
。
stream := TFileStream.Create(FileName, fmCreate);
fmCreate
选项表示如果文件已经存在,它将被我们写的内容替换并覆盖。if bytes<>nil then
stream.Write(bytes[0], Length(Bytes));
if bytes<>nil
检查是为了处理base64字符串解码为空数组的情况。如果我们删除此检查,则在启用范围检查的情况下(应该这样做),以下行将导致运行时错误。调用stream.Write
应该是不言自明的。
在研究 Soap.EncdDecd 后,我们可以找到更多平台无关的方法,因为它的 DecodeBase64 使用了来自 System.NetEncoding 的通用方法(没有 AnsiString)。
基于 Uwe 的示例:
uses
...
System.Classes,
System.NetEncoding;
...
procedure DecodeFile(const base64: String; const FileName: string);
var
stream: TBytesStream;
begin
stream := TBytesStream.Create(TNetEncoding.Base64.DecodeStringToBytes(base64));
try
stream.SaveToFile(Filename);
finally
stream.Free;
end;
end;
uses
Soap.EncdDecd;
function TForm1.EncodeFile(const FileName: string): AnsiString;
var
MemStream: TMemoryStream;
begin
MemStream := TMemoryStream.Create;
try
MemStream.LoadFromFile(Filename);
Result := EncodeBase64(MemStream.Memory, MemStream.Size);
finally
MemStream.Free;
end;
end;
function TForm1.DecodeFile(const base64: AnsiString): TBytesStream;
begin
Result := TBytesStream.Create(DecodeBase64(base64));
end;
Uses
IdCoderMIME; // Indy9
var
decoder: TIdDecoderMIME;
str: WideString;
- - -
decoder := TIdDecoderMIME.Create(nil);
str := base64DecodeUTF8(decoder, b64sourcestr);
decoder.Free;
- - -
function base64DecodeUTF8(decoder:TIdDecoderMIME; str:String): WideString;
var
stream:TMemoryStream;
utf8: UTF8String;
//idx:Integer;
begin
stream := TMemoryStream.Create;
try
decoder.DecodeToStream(str, stream);
setString(utf8, PChar(stream.Memory), stream.Size);
Result := UTF8Decode(utf8);
//for idx := 0 to stream.Size-1 do begin
// Writeln(PChar(stream.Memory)[idx] + ' ' + IntToStr(ORD(PChar(stream.Memory) [idx])) );
//end;
finally
stream.Free;
end;
end;
TIdDecoderMIME
有一个静态的DecodeStream()
方法,因此您不需要实例化一个TIdDecoderMIME
对象。您可以删除decoder
变量,并将decoder.DecodeToStream(str, stream);
替换为TIdDecoderMIME.DecodeStream(str, stream);
。或者,您可以使用静态的TIdDecoderMIME.DecodeString()
方法,该方法具有用于指定二进制数据的字符集的参数,以及在将Unicode字符串转换为Ansi(仅限D2007及更早版本)时输出字符串的字符集的参数。 - Remy Lebeau
DecodeBase64
函数。你看过它吗?如果是这样,你做到了什么程度,遇到了什么问题? - Jon Skeet