Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

не верное копирование файла через BlockWrite/BlockRead


Страницы:   1 2

brother ©   (2009-05-15 08:52:00) 

Доброго времени суток!
Суть вот в чем:
Есть файл, из него читаю нужный объем байт и записываю в другой файл, код (черновой):
 assignfile(FromF, 'c:\1.txt');
 reset(FromF, 1);

 seek(FromF, header.obj[spinedit1.Value]._seek);

  count:=0;

   AssignFile(ToF, 'c:\'+header.obj[spinedit1.Value]._shortname);
   Rewrite(ToF, 1);
   repeat
     BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
     inc(count, NumRead);
     if count>header.obj[spinedit1.Value]._size
     then
       BlockWrite(ToF, Buf, count-header.obj[spinedit1.Value]._size, NumWritten)
     else
       BlockWrite(ToF, Buf, NumRead, NumWritten);
   until (NumRead = 0) or (NumWritten <> NumRead);
   CloseFile(ToF);

Проблемма такая: при окончании копирования, на тестовом файле не дописывается 48 байт.
Отладчиком проверил все переменные:
header.obj[spinedit1.Value]._size = 50200 - корректно
inc(count, NumRead); увеличивает коррекно по 2048
count-header.obj[spinedit1.Value]._size на последнем шаге дает 1000.
не понимаю где я ошибаюсь?


Slym   (2009-05-15 10:58:00) [21]

или можно так:
   Source.ReadBuffer(Header,SizeOf(Header));
   Offset:=SizeOf(Header)+(Header.maxobj-1)*SizeOf(TObj);
   if Source.Seek(Offset,soBeginning)<> Offset then raise Exception.Create('bad file');
   Source.ReadBuffer(Obj,SizeOf(Obj));
   with Obj do
   begin


Slym   (2009-05-15 10:52:00) [22]

упс криво...
type
 TObj = packed record
  _shortname : string[100]; // имя файла без путей
  _size : longword ;  // размер файла
  _seek : longword ;  // смещение относительно начала файла
end;

THeader = packed record
  caption:string[10];
  version:string[3];
  size : longword ; // размер Header
  maxobj : integer; // всего добавлено файлов
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 Source,Dest:TFileStream;
 Header:THeader;
 Objs:array of TObj;
 i:integer;
begin
 Source:=TFileStream.Create('c:\1.txt',fmOpenRead);
 try
   Source.ReadBuffer(Header,SizeOf(Header));
   SetLength(Objs,Header.maxobj);
   for i:=0 to Header.maxobj do
     Source.ReadBuffer(objs[i],SizeOf(TObj));
   with Objs[1{spinedit1.Value}] do
   begin
     if Source.Seek(_seek+_size,soBeginning)<>_seek then raise Exception.Create('bad file');
     if Source.Seek(_seek,soBeginning)<>_seek then raise Exception.Create('bad file');
     Dest:=TFileStream.Create('c:\'+_shortname,fmCreate);
     try
       Dest.CopyFrom(Source,_size);
     finally
       Dest.Free;
     end;
   end;
 finally
   Source.Free;
 end;
end;


Slym   (2009-05-15 10:51:00) [23]

var
 Source,Dest:TFileStream;
 Header:THeader;
 Objs:array of TObj;
 i:integer;
begin
 Source:=TFileStream.Create('c:\1.txt',fmOpenRead);
 try
   Source.ReadBuffer(Header,SizeOf(Header));
   SetLength(Objs,Header.maxobj);
   for i:=0 to Header.maxobj do
     Source.ReadBuffer(objs[i],SizeOf(TObj));
   with Objs[1{spinedit1.Value}] do
   begin
     if Source.Seek(_seek+_size,soBeginning)<>_seek then raise Exception.Create('bad file');
     if Source.Seek(_seek,soBeginning)<>_seek then raise Exception.Create('bad file');
     Dest:=TFileStream.Create('c:\'+_shortname,fmCreate);
     try
       Dest.CopyFrom(Source,_size);
     finally
       Dest.Free;
     end;
   end;
 finally
   Source.Free;
 end;
end;


Smile   (2009-05-15 10:00:00) [24]

> brother ©   (15.05.09 09:50) [11]

понятно


brother   (2009-05-15 09:50:00) [25]

> c:\1.txt

зы, он НЕ текстовый, это для отладки


brother   (2009-05-15 09:48:00) [26]

> сюда 100 - 150 байт файла c:\1.txt

в первых 3384 байтах этого файла находится Header, и он корректно считывается


Smile   (2009-05-15 09:43:00) [27]

> brother ©

Структура понятна, но все-таки приведи (выложи) сюда 100 - 150 байт файла c:\1.txt


brother   (2009-05-15 09:27:00) [28]

структура исходного файла:
заголовок (header)
файл1
файл2
файл N


brother   (2009-05-15 09:26:00) [29]

> Что из себя представляют ToF и FromF?

 FromF, ToF: file;


> структура header.


 TObj = record
   _shortname : string[100]; // имя файла без путей
   _size : longword ;  // размер файла
   _seek : longword ;  // смещение относительно начала файла
 end;

 THeader = record
   caption:string[10];
   version:string[3];
   size : longword ; // размер Header
   maxobj : integer; // всего добавлено файлов
   obj : array [1..30] of TObj;
 end;


Smile   (2009-05-15 09:21:00) [30]

> brother ©   (15.05.09 08:52)

Что из себя представляют ToF и FromF?

Textfile, File
или еще что-то?


Anatoly Podgoretsky   (2009-05-15 09:19:00) [31]

Может и так, но нам то это неизвестно, особенно структура header.
Кстати и выбор цикла неверный, нужен while
И весь алгоритм вызывает какое то сопротивление, вместо простого и понятного, запутаный.


brother   (2009-05-15 09:12:00) [32]

> Наверно здесь
>
> >  seek(FromF, header.obj[spinedit1.Value]._seek);

нет, заголовок то файла правильный, я проверил


brother   (2009-05-15 09:11:00) [33]

> это условие - ошибочно

все верно, по этому, я в конце копирую не весь буфер а только count-header.obj[spinedit1.Value]._size те 1000 байт и потом это является признаком выхода из цикла


Anatoly Podgoretsky   (2009-05-15 09:11:00) [34]

Наверно здесь

>  seek(FromF, header.obj[spinedit1.Value]._seek);


Palladin   (2009-05-15 08:53:00) [35]


>  or (NumWritten <> NumRead);

это условие - ошибочно


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо