将缓冲区添加到ByteArray

时间:2012-08-03 13:56:36

标签: delphi-7 delphi

我使用winsock接收这样的1024字节缓冲区:

var
 buffer    : array[0..1023] of byte; 
 endarray  : array of byte;
 hFile     : THandle;
 dwWritten : DWORD;
 dwRead    : DWORD;
begin
 SetLength (endarray, 3000); //fixxed size (doesn't really matter here, cause I know the size)
 hFile := CreateFileW('test.bin', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, 0, 0);
 SetFilePointer(hFile, 0, nil, FILE_BEGIN);
 repeat
 dwRead := recv(MySock, Buffer, 1024, 0);
 WriteFile(hFile, buffer[0], dwRead, dwWritten, nil); // works fine!
 // Add the buffer to the endarray but how?
 until (dwRead = 0) or (dwRead = -1)
 [...]
 CloseHandle (hFile);
end;

如何自动将缓冲区添加到endarray,以便实际将其附加到结尾?

2 个答案:

答案 0 :(得分:4)

像这样:

var
  PrevLen: Integer;
....
dwRead := recv(MySock, Buffer, 1024, 0);
if dwRead>0 then
begin
  PrevLen := Length(endarray);
  SetLength(endarray, PrevLen+dwRead);
  Move(Buffer[0], endarray[PrevLen], dwRead);
end;

还要从预先分配endarray的函数中删除第一行代码。

如果您宁愿分配缓冲区一次(根据问题中的代码),那么您可以这样编码:

var
  endarrayLen: Integer;
.....
endarrayLen := 0;
repeat
  dwRead := recv(MySock, Buffer, 1024, 0);
  if dwRead>0 then
  begin
    Move(Buffer[0], endarray[endarrayLen], dwRead);
    inc(endarrayLen, dwRead);
  end;
  .....
until ...

但这是一个等待发生的缓冲区溢出!

答案 1 :(得分:2)

您可以使用TMemoryStreamTBytesStream课程。两者都代表可动态增长的内存块。 TMemoryStream在原始内存块上运行,而TBytesStream在动态字节数组上运行。例如:

var 
  buffer    : array[0..1023] of byte;  
  endarray  : TMemoryStream; 
  hFile     : THandle; 
  iRead     : Integer; 
  dwWritten : DWORD; 
begin 
  endarray := TMemoryStream.Create;
  try
    hFile := CreateFileW('test.bin', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, 0, 0); 
    try
      repeat 
        iRead := recv(MySock, buffer, sizeof(buffer), 0); 
        if iRead < 1 then Break;
        WriteFile(hFile, buffer[0], iRead, dwWritten, nil);
        endarray.WriteBuffer(buffer[0], iRead);
      until False; 
      [...] 
    finally
      CloseHandle (hFile); 
    end; 
    // use endarray.Memory as needed, up to endarray.Size number of bytes ...
  finally
    endarray.Free;
  end;
end;

var 
  buffer    : array[0..1023] of byte;  
  endarray  : TBytesStream; 
  hFile     : THandle; 
  iRead     : Integer; 
  dwWritten : DWORD; 
begin 
  endarray := TBytesStream.Create(nil);
  try
    hFile := CreateFileW('test.bin', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, 0, 0); 
    try
      repeat 
        iRead := recv(MySock, buffer, sizeof(buffer), 0); 
        if iRead < 1 then Break;
        WriteFile(hFile, buffer[0], iRead, dwWritten, nil);
        endarray.WriteBuffer(buffer[0], iRead);
      until False; 
      [...] 
    finally
      CloseHandle (hFile); 
    end; 
    // use endarray.Bytes as needed, up to endarray.Size number of bytes ...
  finally
    endarray.Free;
  end;
end;