0

私のwin32プログラムは、文字列[32]とその直後の整数のみを含むバイナリファイルを作成しました。次に、同じファイルを読み取るための.NETプログラムを作成しました。

これが私の.NETコードです:

method ReadUnitFile;
var
  FHeader:TFileHeader;
  Biread:BinaryReader;
  FUnitLoc:String;
begin
  FUnitLoc := baseDir+'\system\Units.dat';
  if Environment.OSVersion.Platform = System.PlatformID.Unix then
    FUnitLoc := baseDir+'/system/Units.dat';

  if File.Exists(FUnitLoc) then
  begin
    Biread:= new BinaryReader(File.OpenRead(FUnitLoc));

    FHeader.id:=Biread.ReadString;
    FHeader.version:=Biread.ReadInt32;
    Biread.Close;
  end;
end;

おそらくファイルの読み取りに失敗しました。実際、「ファイルの終わりを超えて読み取る」例外が発生しました。その理由は、文字列が正確に32文字の長さであるためです。BinaryReaderには情報がないと思います。したがって、文字列に対して32文字を超えて読み取ります。したがって、バイナリファイルを正しく読み取ることができません。

では、この場合、.NETFrameworkでbinary-win32-fileをどのように読み取るのでしょうか。

アップデート

これが私の.NET更新コードです:

method ReadUnitFile;
var
  FHeader:TFileHeader;
  Biread:BinaryReader;
  FUnitLoc:String;
  tmparray:array[0..32] of char;
begin
  FUnitLoc := baseDir+'\system\Units.dat';
  if Environment.OSVersion.Platform = System.PlatformID.Unix then
    FUnitLoc := baseDir+'/system/Units.dat';

  if File.Exists(FUnitLoc) then
  begin
    Biread:= new BinaryReader(File.OpenRead(FUnitLoc));

    Biread.Read(tmparray,0,32);
    FHeader.id := tmparray.ToString;
    FHeader.version:=Biread.ReadInt32;
    Biread.Close;
  end;
end;

これは機能しますが、tmparrayから文字列を取得できないようです。FHeader.idは文字列型です。ToStringが正しく機能していないようです。そのコード行の後、FHeader.idは「System.Char[]」と等しくなります。実際には文字列自体は含まれていません。

何か案が?

前もって感謝します、

4

3 に答える 3

2

ReadStringのドキュメントで説明されているように、文字列には「長さのプレフィックスが付けられ、一度に7ビットの整数としてエンコードされる」ことが想定されています。(それは少し不明確ですが、ほとんどの人は自分が書いた文字列を読んでいると思いますBinaryWriter.Write(String))。

既知の長さの文字列(この場合は32など)がある場合、またはファイル全体を読み取りたい場合は、おそらくBinaryReader.Readオーバーロードの1つを使用する必要があります

更新された質問への回答

char[].ToString()文字を文字列に連結しません。代わりに、charの配列()の記述表現を提供し"System.Char[]"ます。

できることは、コンストラクターを使用して、を同等の文字列stringに変換することです。この回答char[]を参照してください。

更新char[]:他の回答とコメントに記載されているように、をに変換するときは正しいエンコーディングに注意する必要がありますstringString(Char[])コンストラクターはユニコード文字を想定していますが、これは必要な文字である場合とそうでない場合があります(ただし、プレーンASCIIでも機能します)。

于 2012-04-27T13:31:31.977 に答える
1

BinaryReader.ReadString() は、BinaryReader.WriteString() によって書き込まれた文字列のみを読み取ることができます。ファイル内の文字列データには、文字列の長さを格納する可変長フィールドが事前に固定されています。

回避策は簡単です。代わりに ReadBytes(32) を呼び出すだけです。次に、Encoding.GetString() を使用してバイトを文字列に変換します。

それほど単純ではないのは、適切な Encoding クラスを選択することです。ファイルを書き込んだプログラムで使用されたエンコーディングと一致する必要があります。これは、世界の別の場所で作成されたファイルで問題が発生する可能性のある醜い実装の詳細です。Encoding.Default は、ファイルがあまり移動していない場合に機能します。

于 2012-04-27T14:19:06.777 に答える
1

DelphiShortStringをファイルに保存しました。には、 にある要素の数を指定するために先頭にaShortStringが含まれています。.NET コードでは、 を読み取り、次に指定された数の 8 ビット文字を読み取り、次に 4 バイト整数を読み取る必要があります。ByteAnsiCharShortStringByte

method ReadUnitFile;
var
  FHeader: TFileHeader;
  Biread: BinaryReader;
  FUnitLoc: String;
begin
  FUnitLoc := baseDir+'\system\Units.dat';
  if Environment.OSVersion.Platform = System.PlatformID.Unix then
    FUnitLoc := baseDir+'/system/Units.dat';
  if File.Exists(FUnitLoc) then
  begin
    Biread := new BinaryReader(File.OpenRead(FUnitLoc));
    FHeader.id := System.Encoding.Default.GetString(Biread.ReadBytes(Biread.ReadByte));
    FHeader.version := Biread.ReadInt32;
    Biread.Close;
  end;
end;
于 2012-04-27T20:17:10.620 に答える