2011-04-27 59 views
0

我會將一箇舊的Delphi應用程序移植到C#中,並且需要幫助來閱讀Delphi創建的文件。閱讀在Delphi中創建的文件

我的C#程序將使用序列化來讀取和寫入文件,但該程序還必須能夠讀取舊的Delphi創建的文件,這就是我需要幫助的。

總之,我需要幫助閱讀與塊寫入

Delphi代碼創建的文件創建文件:

sys: SystemRecord; 

procedure SaveSystem; 
var 
    fileType, 
    fileVersion: Byte; 
    IORes:  Integer; 
    fileName: String; 
    f:   File; 
begin 
    fileType:=1; { system file } 
    fileVersion:=1; { Version on the file} 
    fileName:=GetSystemFileName; 
    {$I-} 
    if IOResult = 0 then; { Read IOResult } 
    Assign(f,fileName); 
    Rewrite(f,1); 
    IORes:=IOResult; 
    if IORes = 0 
    then begin 
    BlockWrite(f,fileType,1); 
    BlockWrite(f,fileVersion,1); 
    BlockWrite(f,sys,SizeOf(sys)); 
    Close(f); 
    IORes:=IOResult; 
    end; 
    {$I+} 
    if IORes <> 0 
    then begin 
    LogHnd(_SaveSystem,''); 
    MainForm.SetInfo(INFO_SaveSystem_ERR,''); 
    end 
    else begin 
    MainForm.SetInfo(INFO_SaveSystem_OK,''); 
    end; 
end; 

Delphi代碼讀取文件:

procedure LoadSystem; 
var 
    fileType, 
    fileVersion: Byte; 
    IORes:  Integer; 
    fileName: String; 
    f:   File; 
    fileOK:  Boolean; 
begin 
    fileOK:=FALSE; 
    fileName:=GetSystemFilename; 
    {$I-} 
    if IOResult = 0 then; { Read IOResult } 
    Assign(f,fileName); 
    Reset(f,1); 
    IORes:=IOResult; 
    if IORes = 0 then begin 
    BlockRead(f,fileType,1); 
    BlockRead(f,fileVersion,1); 
    IORes:=IOResult; 
    if (fileType = 1) AND (IORes = 0) then begin 
     case fileVersion of 
     1: begin 
      BlockRead(f, sys, SizeOf(sys)); 
      IORes:=IOResult; 
      if IORes = 0 then if EOF(f) then fileOK:=TRUE; 
     end; { 1 } 
     end; { case } 
    end; 
    Close(f); 
    IORes:=IOResult; 
    if IORes <> 0 then; { Skip waring } 
    end 
    else begin { system file missing => load default settings } 
    InitSystem; 
    fileOK:=TRUE; 
    end; 
    {$I+} 
    if (NOT fileOK) 
    then begin 
    InitSystem;   { Read error => Load default settings } 
    LogHnd(_LoadSystem,''); { To event log } 
    MainForm.SetInfo(INFO_LoadSystem_ERR,''); 
    end 
    else MainForm.SetInfo(INFO_LoadSystem_OK,''); 
end; 

結構/枚舉省:

SystemRecord = record 
    verk: Array[1..MAXVERK] of VerkRecord; 
    activeVerk: Integer; 
    com: ComRecord; 
    hastighet: THastighet; 
    tipStatus: Array[1..MAXTIP] of TipStatusRecord; 
    brus: Integer; { 1..50 } 
    TIPcolor: Array[1..3,1..2] of Byte; 
    dummy: Array[1..494] of Byte; { For backward compatibility } 
    end; 

VerkRecord = record 
    active: boolean; 
    name:  string[40]; 
    shortname: string[10]; 
    formula: string[100]; 
    antalKanaler: Array[1..MAXTIP] of Integer; 
    sondXref: Array[1..MAXTIP,1..MAXKANAL] of Integer; 
    TOCtime: Array[1..MAXTIP,1..MAXKANAL] of TDateTime; 
    BOCtime: Array[1..MAXTIP,1..MAXKANAL] of TDateTime; 
    blockerad: Array[1..MAXSOND] of Boolean; 
    tipIsDigit: Boolean; 
    sondLength: Integer; 
    power: Integer;  
    dummy: Array[1..200] of Byte; { For backward compatibility } 
    end; 

    ComRecord = record 
    port: Word; 
    baud: Word; 
    stop: Word; 
    data: Word; 
    par: Word; 
    end; 

TipStatusRecord = record 
    position: 1..9; 
    riktning: 0..2; 
    ATIP: 1..6;  
    ATCU: 1..4;  
    SelfTest: 0..1; 
    ATCUStatus: 0..1; 
    measurePos: Integer; 
    kanal: Integer; 
    end; 

THastighet = (normal, brus, dubbel, trippel, snabb); 
+2

使用任何您熟悉的C#原始二進制寫入功能。順便說一下,這個源文件並沒有完全定義文件格式。記錄沒有打包,包裝也沒有另行指定,因此記錄的打包由IDE中的編譯器設置定義,不包括源 – 2011-04-27 09:29:44

+0

我該如何打包記錄?我可以在項目文件中看到它嗎?我沒有IDE到德爾福。 – magol 2011-04-27 09:44:35

+0

記錄類型本身的聲明。如果沒有使用'packed'鍵,那麼它沒有打包。 – 2011-04-28 18:33:18

回答

1

假設文件寫入與預unicode的delphi版這給你一個起點:

const int MAXVERK = 10; 
const int MAXTIP = 5; 
const int MAXKANAL = 3; 

private void LoadSystem() { 
    BinaryReader reader; 

    reader = new BinaryReader(File.OpenRead("E:\\test.dat")); 

    if (reader.ReadByte() != 1) { 
    throw new Exception("Wrong file type"); 
    } 

    if (reader.ReadByte() != 1) { 
    throw new Exception("Wrong file version"); 
    } 

    ReadSystemRecord(reader);  
} 

private void ReadSystemRecord(BinaryReader Reader) { 
    for (int i = 0; i < MAXVERK; ++i) { 
    ReadVerkRecord(Reader); 
    } 
    Int32 activeVerk = Reader.ReadInt32(); 
    ReadComRecord(Reader); 
    byte hastighet = Reader.ReadByte(); // TODO: convert byte to the enum 
    //... 
} 

private void ReadVerkRecord(BinaryReader Reader) { 
    bool active = Reader.ReadByte() != 0; 
    string name = ReadDelphiString(Reader, 40); 
    string shortname = ReadDelphiString(Reader, 10); 
    string formula = ReadDelphiString(Reader, 100); 
    for (int i = 0; i < MAXTIP; ++i) { 
    Int32 antalKanaler = Reader.ReadInt32(); 
    } 
    for (int i = 0; i < MAXTIP; ++i) { 
    for (int j = 0; j < MAXKANAL; ++j) { 
     Int32 sondXref = Reader.ReadInt32(); 
    } 
    } 
    //... 
} 

private void ReadComRecord(BinaryReader Reader) { 
    Int16 port = Reader.ReadInt16(); 
    Int16 baud = Reader.ReadInt16(); 
    Int16 stop = Reader.ReadInt16(); 
    Int16 data = Reader.ReadInt16(); 
    Int16 par = Reader.ReadInt16(); 
} 

private string ReadDelphiString(BinaryReader Reader, int Length) { 
    byte strlength = Reader.ReadByte(); 
    return System.Text.ASCIIEncoding.ASCII.GetString(Reader.ReadBytes(Length), 0, strlength); 
} 

不是一個完整的閱讀器,沒有任何錯誤處理。您必須添加C#數據存儲,缺失值和TDateTime/Enum轉換。但這應該不是很難。也許你必須在delphi中測試值的大小。

+0

對於二維數組,按什麼順序存儲字節? – magol 2011-04-27 10:54:22

+0

@magol:我添加了sondXref讀數來顯示二維數組的數組結構。 – 2011-04-27 19:10:01