2011-04-27 66 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