6

D2007からXE2に変換して、この関数を変換しました

function Add_Line( FileStream : TFileStream; ALine : string) : boolean;

function Add_Line( FileStream : TFileStream; ALine : string; Enc: TEncoding = nil) : boolean;
var
  AStr: ANSISTring;
begin
  Result := True;
  if Enc = nil then Enc := TEncoding.ANSI;
  try
//Old    FileStream.WriteBuffer( Pointer(ALine)^, Length(ALine) );
    if Enc = TEncoding.UTF8 then
      AStr := UTF8Encode(ALine)
    else
      AStr := ANSIString(ALine);
    FileStream.WriteBuffer( AStr[1], Length(ALine) );
    end;
  except
    Result := False;
  end;
end;

理論的根拠:

  • Add_Lineを使用してコードをできるだけ変更しない

  • Unicodeへの自動変更を受け入れます。最後の瞬間にのみ、8ビットのテキストファイルを書き込みます(これはXMLおよびCSVで使用されます)。将来的には、必要に応じてUTF-16ファイルに移動することもできます。

私は次のようなものを定義したかったでしょう:

function Add_Line( FileStream : TFileStream; ALine : string; Enc: TEncoding = TEncoding.ANSI) : boolean;

しかし、コンパイラは文句を言います;-)

そのようなことは可能ですか?

4

2 に答える 2

12

デフォルトの引数はコンパイル時定数でなければなりませんが、より高度なものが必要な場合は、オーバーロードを作成できます。

function Add_Line( FileStream : TFileStream; ALine : string) : boolean; overload;
function Add_Line( FileStream : TFileStream; ALine : string; Enc: TEncoding) : boolean; overload;


function Add_Line( FileStream : TFileStream; ALine : string) : boolean;
begin
  Result := Add_Line(FileStream, ALine, TEncoding.ANSI);
end;

キーワードを追加しinlineて、デフォルトの引数が有効であった場合とまったく同じ生成コードを取得することもできます。

TEncoding.ANSI注:と以外はサポートされていないようですTEncoding.UTF8。その場合、TEncodingパラメータはやり過ぎのようです。UTF8: Boolean代わりにパラメータを使用できます(または、任意のエンコーディングで動作するようにコードを作り直しますCodePage)。

注2:同じである必要はないため、FileStream.WriteBuffer( AStr[1], Length(ALine) );間違っています。代わりに使用する必要があります。また、が空の文字列の場合に例外が発生する可能性があります。空でない場合にのみ呼び出す特別なケースを追加できます。Length(ALine)Length(AStr)Length(AStr)AStr[1]AStrWriteBufferAStr

于 2012-09-10T12:59:38.860 に答える
6

他の人は、パラメータのデフォルト値を指定する方法についてコメントしていTEncodingます。TEncoding一般的に、あなたの使用は完全に間違っていることを指摘したいと思います。

TEncoding.UTF8UTF-8エンコーディングオブジェクトを取得できるのTEncoding.GetEncoding(65001)は(別の方法です)唯一の方法ではないため、具体的にチェックするTEncoding.UTF8のは間違っています。さらに悪いことに、UTF8以外のエンコーディングを完全に無視し、他のすべてをプレーンにエンコーディングするだけAnsiStringで、使用する目的全体が完全に無効にTEncodingなります。たとえば、ユーザーはISO-8859-Xエンコーディングオブジェクトを渡すことができ、出力はユーザーが要求したようにISOエンコードされません。UseUTF8: Boolean = False代わりに、パラメーターをパラメーターに変更することもできます。これは、パラメーターを効果的に使用する方法だからです。

function Add_Line( FileStream : TFileStream; ALine : string; UseUTF8: Boolean = False) : boolean;  
var  
  AStr: AnsiString;  
begin  
  Result := True;  
  try  
    if UseUTF8 then  
      AStr := UTF8Encode(ALine)  
    else  
      AStr := AnsiString(ALine);  
    if AStr <> '' then
      FileStream.WriteBuffer( AStr[1], Length(AStr) );  
  except  
    Result := False;  
  end;  
end;  

正しい使用方法TEncodingは、実際のエンコードを実行させることです。自分でエンコードを実行しないでください。

function Add_Line( FileStream : TFileStream; ALine : string; Enc: TEncoding = nil) : boolean; 
var 
  AStr: TBytes; 
begin 
  if ALine = '' then
  begin
    Result := True;
    Exit;
  end; 
  Result := False;
  try 
    if Enc = nil then Enc := TEncoding.Ansi; 
    AStr := Enc.GetBytes(ALine); 
    // GetBytes() returns 0 bytes if it fails to encode, it does not raise an exception!
    if Length(AStr) = 0 then Exit;
    FileStream.WriteBuffer( AStr[0], Length(AStr) )
  except 
    Exit;
  end; 
  Result := True;
end; 
于 2012-09-10T21:23:38.367 に答える