Переход с одного языка программирования на другой может быть непростой задачей, особенно когда речь идет о конвертации приложений, работающих с двоичными файлами. В данном случае рассматривается переход с Delphi на C#, что может потребовать изменения подходов к управлению памятью и чтению данных из файлов. Ниже приведены шаги, которые помогут понять, как выполнить такой переход, на примере работы с двоичными файлами, записанными с использованием упакованных записей.
Оригинальный код на Delphi
В Delphi для работы с двоичными файлами используется класс TFileStream. Пример кода на Delphi демонстрирует чтение файла, где гарантированно присутствует запись BInfoRec в начале файла, а остальные записи могут отсутствовать или следовать в неизвестном порядке.
StartP = packed record
x:SmallInt;
y:SmallInt;
end;
InfoP = packed record
Ycoord:double;
Xcoord:double;
// другие переменные
end;
HeadP = packed record
NumP:DWORD;
SizeStruct:DWORD;
SizePoStruct:DWORD;
// другие переменные
end;
BInfoRec = packed record
StructNum: WORD;
in_size: WORD;
// другие переменные
end;
var
tStream: TFileStream;
bInfo: BInfoRec;
RestOfBFile: Pointer;
sizeofRest: Integer;
function LoadBFile(FileName: String): Boolean;
var
sizeread: Integer;
begin
Try
LoadBFile := False;
tStream := TFileStream.Create(FileName, fmOpenRead);
sizeofRest := tStream.Size - SizeOf(bInfo);
sizeread := tStream.Read(bInfo, SizeOf(bInfo));
if sizeread = SizeOf(bInfo) then
begin
RestOfBFile := AllocMem(sizeofRest);
sizeread := tStream.Read(RestOfBFile^, sizeofRest);
if sizeofRest = sizeread then
LoadBFile := True;
end;
tStream.Free;
except
LoadBFile := False;
tStream.Free;
end;
end;
Переход на C
При переходе на C# необходимо учитывать, что управление памятью в этом языке отличается от Delphi. В C# для работы с двоичными файлами обычно используются классы FileStream и BinaryReader. Ниже приведен пример структур, аналогичных Delphi, и метода LoadBFile на C#.
[Serializable()]
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct StartP
{
public short x;
public short y;
}
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct InfoP
{
public double Ycoord;
public double Xcoord;
// другие переменные
}
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct HeadP
{
public UInt32 NumP;
public UInt32 SizeStruct;
public UInt32 SizePoStruct;
// другие переменные
}
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct BInfoRec
{
public ushort StructNum;
public ushort in_size;
}
private Boolean LoadBFile(string fileName)
{
BInfoRec bInfo;
int sizeOfRest;
int sizeRead;
byte[] buffer = new byte[Marshal.SizeOf(typeof(BInfoRec))];
try
{
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
{
sizeOfRest = (int)stream.Length - Marshal.SizeOf(typeof(BInfoRec));
sizeRead = stream.Read(buffer, 0, Marshal.SizeOf(typeof(BInfoRec)));
if (sizeRead == Marshal.SizeOf(typeof(BInfoRec)))
{
// Создаем новый байтовый массив неизвестного размера
byte[] restOfFile = new byte[sizeOfRest];
// Читаем оставшуюся часть файла в массив
stream.Read(restOfFile, 0, sizeOfRest);
// Проверяем, был ли прочитан весь остаток файла
if (sizeOfRest == stream.Read(restOfFile, 0, sizeOfRest).ToInt32())
{
return true;
}
}
}
}
catch (Exception ex)
{
return false;
}
}
Подход к решению
В C# для работы с блоками памяти переменного размера удобно использовать байтовые массивы. Хотя возможен и вариант выделения неуправляемой памяти, использование байтового массива является более удобным и безопасным подходом.
Выводы
Переход с Delphi на C# требует понимания отличий в управлении памятью и работе с файлами. Использование байтовых массивов в C# для чтения и обработки двоичных файлов является предпочтительным решением, обеспечивающим удобство и безопасность.
Переход с языка программирования Delphi на C# с конвертацией старых приложений под работу с двоичными файлами требует адаптации к особенностям управления памятью и чтения данных в C#.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.