我将旧的Delphi应用程序移植到C#,需要帮助来读取Delphi创建的文件。
我的C#程序将使用序列化来读取和写入文件,但程序还必须能够读取旧的Delphi创建的文件,这就是我需要帮助的地方。
简而言之,我需要帮助来阅读使用BlockWrite创建的文件
用于创建文件的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);
答案 0 :(得分:1)
假设文件是使用pre 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#data sotrage,缺失值和TDateTime / Enum转换。但这应该不是很难。也许您必须在delphi中测试值大小。