2

我一直在寻找如何将文件内容(在本例中为 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;
4

1 回答 1

0

我们找到了解决方案:使用 UTF8Char 而不是 AnsiChar 就成功了。(见最终更新)

于 2017-09-26T13:10:55.643 回答