XE7中使用默认的Base64编码的一个小提示

XE7中的Base64编码单元被放到了System.NetEncoding里,但它的默认实现时,会每76个字符加一个换行,先看TNetEncoding的Base64属性的读取函数实现:

class function TNetEncoding.GetBase64Encoding: TNetEncoding;
var
  LEncoding: TBase64Encoding;
begin
  if FBase64Encoding = nil then
  begin
    LEncoding := TBase64Encoding.Create;
    if AtomicCmpExchange(Pointer(FBase64Encoding), Pointer(LEncoding), nil) <> nil then
      LEncoding.Free;
{$IFDEF AUTOREFCOUNT}
    FBase64Encoding.__ObjAddRef;
{$ENDIF AUTOREFCOUNT}
  end;
  Result := FBase64Encoding;
end;

OK,我们可以看它它创建了一个TBase64Encoding的默认实例,使用的是默认构造函数。而默认构造函数我们看下:

constructor TBase64Encoding.Create;
begin
  Create(kCharsPerLine, sLineBreak);
end;

constructor TBase64Encoding.Create(CharsPerLine: Integer);
begin
  Create(CharsPerLine, sLineBreak);
end;

constructor TBase64Encoding.Create(CharsPerLine: Integer; LineSeparator: string);
begin
  FCharsPerline := CharsPerLine;
  FLineSeparator := LineSeparator;
end;

我们看到了一个kCharsPerLine和sLineBreak两个参数。再进一步到内部编码单元(580行)有下面一段代码:

if (FCharsPerLine > 0) and (State.StepCount >= FCharsPerLine/4)  then
        begin
          Move(LineSeparator[0], POut^, Length(LineSeparator));
          Inc(POut, Length(LineSeparator));
          State.StepCount := 0;
        end;

 我们看到它会自动添加了换行符。我们看下kCharsPerLine的定义:

const
    kCharsPerLine = 76;

所以,如果我们不要编码结果中存在换行符,那么我们就不应该使用默认的TNetEncoding.Base64实例来进行Base64编码,而是要自己创建一个TBase64Encoding实例来实现,参考代码如下:

procedure TForm1.Button1Click(Sender: TObject);
var
  AEncoding:TBase64Encoding;
  ...
begin
  AEncoding:=TBase64Encoding.Create(MaxInt);
  Edit2.Text := AEncoding.EncodeBytesToString(...);
  FreeAndNil(AEncoding);
end;

 

分享到: