-1

So I have a binary file and I am reading a word value which is 2 bytes the value is an Int16 = 43140, however whenever I read it in Delphi it returns as 43104, I wrote the code to read it in C# just to test and it reads correctly it is only in Delphi it is reading incorrectly, it looks like the 0 and 4 are shifting places for some reason.

  TMyHeader= packed record
     Value1       :String[20];
     Value2       :Word; // Is 43140 but reading as 43104
     Value3       :Word;
     Value4       :Word; // Is 43140 but reading as 43104
  end;

FileRead (fhandle, header, sizeof(MyHeader));
kyndigs
  • 3,074
  • 1
  • 18
  • 22
  • 1
    Possibly, you have UTF-16 characters in source file. Instead of ANSI. – kami Oct 27 '16 at 12:43
  • An [mcve] that demonstrates the issue would be helpful. It's impossible to guess what might be wrong. Your code also does not use Stream reader. What question are you actually asking? – Ken White Oct 27 '16 at 12:45
  • Let me knock one together, I have used both Stream reader and FileRead from SysUtils and both give the same result. – kyndigs Oct 27 '16 at 12:54
  • Strange, when I built this small example it works fine, I think there must be something else causing it then, I will need to dig more... – kyndigs Oct 27 '16 at 13:03
  • Do your digging before asking unanswerable questions. A question like this needs a [mcve]. – David Heffernan Oct 27 '16 at 13:42
  • How do you check Delphi reads wrong and C# reads right? Maybe it is the opposite ? Maybe it is C# that reads it wrong not Delphi ? – Arioch 'The Oct 27 '16 at 15:06

1 Answers1

0

Your code does not use Stream reader, and it's entirely unlikely that the issue is with reading the file. Here's an example of using TFileStream to both read and write your record successfully without altering the values in any way. (Clearly you'll have to change the TestFile constant to point to a valid, writable location on your system first.)

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes;

type
  TMyHeader = packed record
    Value1: String[20];
    Value2: Word;
    Value3: Word;
    Value4: Word;
  end;

var
  MyHeader: TMyHeader;
  Stream: TFileStream;

const
  TestFile = 'E:\TempFiles\Testheader.bin';

begin
  // Initialize the record
  MyHeader.Value1 := 'Testing One Two';
  MyHeader.Value2 := 43140;
  MyHeader.Value3 := 12345;
  MyHeader.Value4 := 43140;

  // Show what it contains. The `[]` brackets are to clearly delimit Value1
  WriteLn(Format('Before write: [%s] %d %d %d', 
                  [MyHeader.Value1, MyHeader.Value2, MyHeader.Value3, MyHeader.Value4]));

  // Write it to the stream.
  Stream := TFileStream.Create(TestFile, fmCreate, fmShareDenyNone);
  try
    Stream.Write(MyHeader, SizeOf(TMyHeader));
  finally
    Stream.Free;
  end;

  // Clear the contents of MyHeader before reading back, and show the empty values
  FillChar(MyHeader, SizeOf(TMyHeader), 0);
  WriteLn(Format('Before read: [%s] %d %d %d', 
                 [MyHeader.Value1, MyHeader.Value2, MyHeader.Value3, MyHeader.Value4]));
  Stream := TFileStream.Create(TestFile, fmOpenRead, fmShareDenyNone);
  try
    Stream.Read(MyHeader, SizeOf(TMyHeader));
  finally
    Stream.Free;
  end;
  // Output what we've read back in to verify it is correct
  WriteLn(Format('After read: [%s] %d %d %d', 
                 [MyHeader.Value1, MyHeader.Value2, MyHeader.Value3, MyHeader.Value4]));
  Readln;
end.
Ken White
  • 123,280
  • 14
  • 225
  • 444