не могу нормально пользоваться ReadFile
От: balykovdron Россия  
Дата: 17.04.03 07:02
Оценка:
Вот код. Вопросы:
1. Почему в конце возникает "Access Violation..."
2. Почему, если я ставлю BlockSize = больше чем 2К (например я хочу читать блоками по 64К = 65536, например для больших файлов), то ReadFile возвращает 'Fuck again'.
3. И если все успешно, то в BP оказываются считанные данные. У меня не получается загнать это в строку.

Подскажите уважаемые гуру что я делаю не так

procedure TForm1.Button1Click(Sender: TObject);
var
  fSrc: string;
  StartByte: integer;
  BP : array of byte;
  hFile, cRet, BytesWorked, BlockSize: Cardinal;
  srcFileSize: DWORD;
  bRet: Boolean;
begin
  fSrc := 'C:\autoexec.bat';
  hFile := CreateFile(PChar(fSrc), GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  srcFileSize := GetFileSize(hFile, nil);
  //ShowMessage('File size = ' + IntToStr(srcFileSize) + ' Err = ' + IntToStr(GetLastError));
  StartByte := 0;
  BlockSize := 1024;
  cRet := SetFilePointer(hFile, StartByte, nil, FILE_BEGIN);
  SetLength(BP, Sizeof(byte) * BlockSize);
  bRet := ReadFile(hFile, BP, BlockSize, BytesWorked, nil);
  if BytesWorked > 0 then
    ShowMessage('OK')
  else
    ShowMessage('Fuck again! :(');
  CloseHandle(hFile);
end;
Re: не могу нормально пользоваться ReadFile
От: mitja_r Россия  
Дата: 17.04.03 12:15
Оценка: -1
Не вполне уверен, что Вас это спасет, но если обявить массив как
var BP: array[0..XXX] of Byte;

(т.е. размер массива фиксирован) и убрать SetLength, то все три Ваши проблемы решаются. Можно даже как
var BP: array[0..XXX] of Char;

Тогда и в строку проще преобразовывать...

Здравствуйте, balykovdron, Вы писали:

B>Вот код. Вопросы:

B>1. Почему в конце возникает "Access Violation..."
B>2. Почему, если я ставлю BlockSize = больше чем 2К (например я хочу читать блоками по 64К = 65536, например для больших файлов), то ReadFile возвращает 'Fuck again'.
B>3. И если все успешно, то в BP оказываются считанные данные. У меня не получается загнать это в строку.

B>Подскажите уважаемые гуру что я делаю не так


B>
B>procedure TForm1.Button1Click(Sender: TObject);
B>var
B>  fSrc: string;
B>  StartByte: integer;
B>  BP : array of byte;
B>  hFile, cRet, BytesWorked, BlockSize: Cardinal;
B>  srcFileSize: DWORD;
B>  bRet: Boolean;
B>begin
B>  fSrc := 'C:\autoexec.bat';
B>  hFile := CreateFile(PChar(fSrc), GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
B>  srcFileSize := GetFileSize(hFile, nil);
B>  //ShowMessage('File size = ' + IntToStr(srcFileSize) + ' Err = ' + IntToStr(GetLastError));
B>  StartByte := 0;
B>  BlockSize := 1024;
B>  cRet := SetFilePointer(hFile, StartByte, nil, FILE_BEGIN);
B>  SetLength(BP, Sizeof(byte) * BlockSize);
B>  bRet := ReadFile(hFile, BP, BlockSize, BytesWorked, nil);
B>  if BytesWorked > 0 then
B>    ShowMessage('OK')
B>  else
B>    ShowMessage('Fuck again! :(');
B>  CloseHandle(hFile);
B>end;
B>
Re: не могу нормально пользоваться ReadFile
От: jhfrek Россия  
Дата: 17.04.03 15:18
Оценка:
Здравствуйте, balykovdron, Вы писали:

B>Вот код. Вопросы:

B>1. Почему в конце возникает "Access Violation..."

потому что надо вместо

bRet := ReadFile(hFile, BP, BlockSize, BytesWorked, nil);

писать

bRet := ReadFile(hFile, BP[0], BlockSize, BytesWorked, nil);


B>2. Почему, если я ставлю BlockSize = больше чем 2К (например я хочу читать блоками по 64К = 65536, например для больших файлов), то ReadFile возвращает 'Fuck again'.


По той же причине. Только чтобы это выяснить надо не ругаться, а написать

var lpMsgBuf : array[0..1024] of char{PChar};

    FormatMessage(
              FORMAT_MESSAGE_FROM_SYSTEM,
              nil,
              GetLastError(),
              LANG_NEUTRAL,
              lpMsgBuf,
              1024{0},
              nil
             );
    ShowMessage(string(lpMsgBuf));


И получишь более информативное сообщение Invalid access to memory location

B>3. И если все успешно, то в BP оказываются считанные данные. У меня не получается загнать это в строку.



  str := string(BP);
Re[2]: не могу нормально пользоваться ReadFile
От: balykovdron Россия  
Дата: 17.04.03 18:28
Оценка:
J>
J>bRet := ReadFile(hFile, BP[0], BlockSize, BytesWorked, nil);
J>


Да верно. Еще вот так у меня получилось.
bRet := ReadFile(hFile, BP^, BlockSize, BytesWorked, nil);


B>2. Почему, если я ставлю BlockSize = больше чем 2К (например я хочу читать блоками по J>По той же причине. Только чтобы это выяснить надо не ругаться, а написать

J>
J>var lpMsgBuf : array[0..1024] of char{PChar};
J>    FormatMessage(
J>              FORMAT_MESSAGE_FROM_SYSTEM,
J>              nil,
J>              GetLastError(),
J>              LANG_NEUTRAL,
J>              lpMsgBuf,
J>              1024{0},
J>              nil
J>             );
J>    ShowMessage(string(lpMsgBuf));
J>


За этот кусок болошое спасибо. У меня на VB такой кусок был все лень было переписать на D.

B>3. И если все успешно, то в BP оказываются считанные данные. У меня не получается загнать это в строку.

J>
J>  str := string(BP);
J>


Спасибо! Все пучком!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.