2

我使用 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 以便它实际上附加到末尾?

4

2 回答 2

5

像这样:

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 ...

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

于 2012-08-03T14:06:11.030 回答
2

您可以使用TMemoryStreamorTBytesStream类。两者都代表一个可动态增长的内存块。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;
于 2012-08-03T23:45:33.627 回答