Base64到二进制(Delphi)

Base64到二进制(Delphi),delphi,Delphi,我使用了Binary to Base64函数,您回答: 我成功地将文件编码为base64字符串并将其写入MSSQLS2008数据库,但我想问一个问题: 如何使用EncdDecd.pas将此文件再次写入磁盘?此函数将获取base64编码字符串,对其进行解码,并将生成的字节数组写入文件 procedure DecodeToFile(const base64: AnsiString; const FileName: string); var stream: TFileStream; byte

我使用了Binary to Base64函数,您回答:

我成功地将文件编码为base64字符串并将其写入MSSQLS2008数据库,但我想问一个问题:
如何使用EncdDecd.pas将此文件再次写入磁盘?

此函数将获取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;
执行解码并以
TBytes
变量返回文件的解码二进制内容
TBytes
只是一个字节数组

下一步是创建文件。在Delphi中编写文件的惯用方法是使用流。在这种情况下,我们需要一个
TFileStream

stream := TFileStream.Create(FileName, fmCreate);
fmCreate
选项意味着,如果文件已经存在,它将被替换并被我们编写的内容覆盖

最后一步是将字节数组的内容写入文件

if bytes<>nil then
  stream.Write(bytes[0], Length(Bytes));
如果为bytesnil,则
stream.Write(字节[0],长度(字节));

if bytesnil
检查用于处理base64字符串解码为空数组的情况。如果我们要删除该检查,那么如果您在启用范围检查的情况下运行(您应该这样做),那么下面的一行将导致运行时错误。调用
stream.Write
应该是不言自明的。

像往常一样,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;

我有一个非常旧的Delphi2006(v10.0.2558.35231更新2),必须解码base64 UTF8编码的输入字符串。我终于弄明白了,这里有一个例子供感兴趣的人参考

  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;

在查看Soap.EncdDecd之后,您可以找到更多与平台无关的方法,因为DecodeBase64使用System.NetEncoding中的通用(无解析)方法

根据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;

在公认的答案中,它谈到了一个
DecodeBase64
函数。你看了吗?如果是这样,你走了多远,遇到了什么问题?是的,我正在寻找它,但我不知道如何使用它。您是否可以编写一个类似于accepted answer中的函数,用于从编码的base64还原此文件并将其写入磁盘?同样,您尝试了什么,取得了多大进展?仅仅使用匙形代码并不能学到很多东西。我还没有尝试过,DecodeBase64函数中只有一个参数(输入:AnsiString)。我不知道如何将它再次转换为原始文件。我正在努力学习。+1这是一种更干净的方法。请继续不要抗拒诱惑,给出其他更好的答案
TidDecoderMie
有一个静态的
DecodeStream()
方法,因此不需要实例化
TidDecoderMie
对象。您可以删除
decoder
变量,并替换
decoder.DecodeToStream(str,stream)
tidecoderMime.DecodeStream(str,stream)取而代之。或者,您可以使用静态的
tidecoderMie.DecodeString()
方法,该方法具有参数,用于在将二进制数据解码为Unicode字符串时指定二进制数据的字符集,以及在将Unicode字符串转换为Ansi(仅限D2007和更早版本)时指定输出字符串的字符集。
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
  ...
  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;