我一直在寻找如何将文件内容(在本例中为 excel 文件)流式传输到控制台输出的问题。在为 Windows 编译时,使用 aTHandleStream
与 STDOUT(控制台输出)的句柄组合起来就像在公园里散步。它使用 Win32 API,因此在为 Linux (顺便说一下 Debian)编译时显然不起作用。
我正在寻找与此等效的:
...
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
...
更新:以下似乎适用于 Windows,但是一旦我切换到 Linux,它就无法编译,因为PAnsiChar
未知。
...
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);
你能找出一些可能有帮助的东西吗?
更新:
嗨,雷米,
再次感谢您的帮助!我快到了,还在为最后一点挣扎。你提到我应该能够对 system.output 做一个 BlockWrite 。但是,BlockWrite 期望 var F: File 作为第一个参数,而 System.Output 的类型是 TEXT ?
此外,我正在使用“字节文件”而不是“文件”来读取我正在阅读的文件,我不确定如何正确转换为输出到控制台?
这是这个 linux POC 的当前状态:
这部分工作正常:阅读 details.xlsx 并将内容写入 test.xlsx(基本上是副本)。目标文件与源文件相同。
这部分还没有工作,但最终是我需要的:将 details.xlsx 的内容写入标准输出:
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;
最终更新:
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;