Delphi Tokyo for Linux:将文件内容流式传输到stdout(控制台输出)

时间:2017-09-19 07:03:55

标签: linux delphi debian delphi-10.2-tokyo

我一直在寻找有关如何将文件内容(在本例中为excel文件)流向控制台输出的一段时间。在为Windows编译时,使用THandleStream和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类型的?

此外,我正在使用'File of Byte'而不是'File'来处理我正在阅读的文件,我不确定如何正确地将输出转换为控制台?

这是这个linux POC的当前状态:

这部分工作正常:阅读details.xlsx并将内容写入test.xlsx(基本上是副本)。目标文件与源文件相同。

这部分还不行,但最终还是我需要的:将详细内容写入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;

最终更新

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;

1 个答案:

答案 0 :(得分:0)

我们找到了解决方案:使用UTF8Char代替AnsiChar就可以了。 (见最终更新)