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

(質問のコードに従って)バッファを1回割り当てたい場合は、次のようにコーディングできます。

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

TMemoryStreamまたはTBytesStreamクラスを使用できます。どちらも動的に拡張可能なメモリブロックを表します。TMemoryStreamはrawメモリブロックで動作しますが、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 に答える