bonsai
2014-08-21 05:55:28
I bumped into a case where I get exceptions from TFileStream.readBuffer() depending on how I set the length of the string I'm using for the buffer.
If I use a local integer or longint for setLength() all goes well.
If I use TFileStream.getSize() in the setLength() it ends up with an access violation when you call readBuffer. There are some oddities with this case:
Other operations on the string seem to work ok in this scenario. You can assign a string to it, print it, but don't call readBuffer().
HOWEVER, if you use s[1] directly in between the setLength() and the readBuffer(), now it works!
Example:
Manually create file test.txt with test data in folder that script is saved in.
If I use a local integer or longint for setLength() all goes well.
If I use TFileStream.getSize() in the setLength() it ends up with an access violation when you call readBuffer. There are some oddities with this case:
Other operations on the string seem to work ok in this scenario. You can assign a string to it, print it, but don't call readBuffer().
HOWEVER, if you use s[1] directly in between the setLength() and the readBuffer(), now it works!
Example:
Manually create file test.txt with test data in folder that script is saved in.
program filestreamerror;
const
fmCreate = $FFFF;
fmOpenRead = 0;
fmOpenWrite = 1;
fmOpenReadWrite = 2;
procedure thisWorks();
var
testFile : TFileStream;
s: string;
i: integer;
li: longint;
begin
testFile.init(scriptPath+'test.txt', fmOpenRead);
i := testFile.getSize(); // longint -> integer
setLength(s, i); // works ok
testFile.readbuffer(s[1], testFile.getSize());
writeln(length(s), ' ', s);
testFile.free();
testFile.init(scriptPath+'test.txt', fmOpenRead);
li := testFile.getSize();
setLength(s, li); // longint -> setLength() works ok too
testFile.readbuffer(s[1], testFile.getSize());
writeln(length(s), ' ', s);
testFile.free();
end;
procedure thisDoesntWork();
var
testFile : TFileStream;
s: string;
begin
try
testFile.init(scriptPath+'test.txt', fmOpenRead);
// using result of getSize() causes problems
setLength(s, testFile.getSize());
// if you uncomment this the function starts working!!
// writeln(s[1]);
testFile.readbuffer(s[1], testFile.getSize());
writeln(length(s), ' ', s);
finally
testFile.free();
end;
end;
var
ans: integer;
begin
ans := messagebox('Would you like an exception?', 'Choose', 4 {yn box});
if (ans = 6 {yes}) then
begin
writeln('You asked for it');
thisDoesntWork();
end
else
begin
thisWorks();
end;
end.