The problem arises in this procedure
procedure TObjTest.NewSd(const path: String);
begin
Clear;
fPathSd:= path;
if fPathSd = '' then
sd:= TMemoryStream.Create
else
sd:= TFileStream.Create(fPathSd, fmCreate);
end;
in which you declare path as a const parameter.
"const" informs the compiler that you (the programmer) will not change path. However, you do change path in the first line of the routine by calling Clear, which sets fPathSd (which the path parameter points to) to become an empty string. As a consequence TFileStream.Create is then called with nonsense data, not with the string you are expecting.
Remove the "const" parameter modifier, and the problem goes away (although it is convoluted programming, not good design IMHO).
Generally when making binary choices it is better to have a FCreateMemoryStream boolean variable (or aCreateAsFileStream: Boolean parameter) which you set explicitly, than to choose what kind of stream is created based on the value of a string. AnsiStrings already have one level of indirection since they are pointers, and since they are compiler-managed you may not always realise when they have been nilled (as in this case). Whereas a private boolean, visible across the entire scope of the object is a simple type you can rely on for the lifetime of the object.