I've been looking around for quite some time now on how to stream the file contents (in this case, excel files) towards console output. When compiling for Windows, it's a walk in the park using a THandleStream
in combination with the handle to STDOUT (console output). It uses the Win32 API, so it obviously won't work when compiling for Linux (Debian by the way).
I'm looking for an equivalent to this :
...
aFileStream := TFileStream.Create(FullFileName,fmOpenRead); // This creates the input stream
aOutputStream := THandleStream.Create(GetStdHandle(STD_OUTPUT_HANDLE)); // Here goes the output stream
aOutputStream.CopyFrom(aFileStream, aFileStream.Size); // And the copy operation
...
Update: The following seems to work on Windows, however as soon as I switch to Linux it doesn't compile since PAnsiChar
is unknown.
...
f : File;
Buff : PAnsiChar;
BytesRead : integer;
ByteSize : integer;
iBuffRunner : integer;
...
AssignFile(F, 'details.xlsx');
Reset(F,1);
ByteSize := (fileSize(F));
GetMem(Buff,ByteSize);
BlockRead(F,Buff[0],ByteSize,BytesRead);
CloseFile(F);
for iBuffRunner := 0 to (Bytesize-1) do
System.Write(Buff[iBuffRunner]);
FreeMem(Buff);
Can you figure out something that might help?
Update:
Hi Remy,
Thanks again for your help! I'm almost there, still struggeling with the last bit. You mention that I should be able to do a BlockWrite towards system.output . However, BlockWrite expects var F: File as first parameter, while System.Output is of type TEXT ?
Furthermore, I'm working with 'File of Byte' instead of 'File' for the file I'm reading and I'm not sure how to convert appropriately for output towards console?
This is the current state of this linux POC :
This part works fine : read details.xlsx and write the contents towards test.xlsx (basically a copy). The destination file is identical to the source file.
This part doesn't work yet, but is ultimately what I need : write the contents of details.xlsx towards stdout :
const
MaxBufSize = 4096;
var
f : File of Byte;
tf : File of Byte;
Buff : array of Byte;
BytesRead : integer;
ByteSize : integer;
WillRead : integer;
begin
AssignFile(F, 'details.xlsx');
Reset(F);
ByteSize := (fileSize(F));
if ByteSize > MaxBufSize then
BytesRead := MaxBufSize
else
BytesRead := ByteSize;
SetLength(Buff, BytesRead);
AssignFile(tf, 'test.xlsx');
Rewrite(tf);
try
while ByteSize <> 0 do
begin
if ByteSize > BytesRead then
WillRead := BytesRead
else
WillRead := ByteSize;
BlockRead(F,Buff[0], WillRead);
BlockWrite(tf,Buff[0], WillRead);
//BlockWrite(System.Output, buff[0], WillRead);
Dec(ByteSize, WillRead);
end;
finally
SetLength(Buff,0);
CloseFile(f);
CloseFile(tf);
end;
System.Readln;
end;
FINAL Update:
const
MaxBufSize = 4096;
var
f : File of Byte;
tf : File of Byte;
Buff : array of Byte;
BytesRead : integer;
ByteSize : integer;
WillRead : integer;
iBufRunner : integer;
begin
AssignFile(F, 'details.xlsx');
Reset(F);
ByteSize := (fileSize(F));
if ByteSize > MaxBufSize then
BytesRead := MaxBufSize
else
BytesRead := ByteSize;
SetLength(Buff, BytesRead);
AssignFile(tf, 'test.xlsx');
Rewrite(tf);
try
while ByteSize <> 0 do
begin
if ByteSize > BytesRead then
WillRead := BytesRead
else
WillRead := ByteSize;
BlockRead(F,Buff[0], WillRead);
BlockWrite(tf,Buff[0], WillRead);
for iBufRunner := 0 to (WillRead - 1) do
System.Write(System.Output, UTF8Char(Buff[iBufRunner]));
Dec(ByteSize, WillRead);
end;
finally
SetLength(Buff,0);
CloseFile(f);
CloseFile(tf);
end;
System.Readln;
end;
We found the solution : the usage of UTF8Char instead of AnsiChar did the trick. (see FINAL update)