Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.12.04;
Скачать: CL | DM;

Вниз

Проблема с чтением нетипизированного файла   Найти похожие ветки 

 
2012   (2011-08-17 13:32) [0]

Здравствуйте, объясните пожалуйста, в чем у меня ошибка. Есть нетипизированный файл, хранящий в себе различного рода другие файлы. Дописываю в файл так:

var
 FromF, ToF: file;
 NumRead, NumWritten: Integer;
 Buf: array[1..2048] of byte;
begin
   AssignFile(FromF, "c:\1.wav");
   Reset(FromF, 1);
   AssignFile(ToF, "c:\test");
   Reset(ToF, 1);
   seek(tof, GetFileSize("g:\test"));

     repeat
       BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
       BlockWrite(ToF, Buf, NumRead, NumWritten);
     until
      (NumRead = 0) or (NumWritten <> NumRead);

     CloseFile(FromF);
     CloseFile(ToF);
end;


Для чтения, какого то файла из файла "тэст" надо указать начало и длину читаемого файла. Делаю так:


var
 FromF, ToF: file;
 NumRead, NumWritten, FSize1, FSize2: Integer;
 Buf: array[1..20480] of byte;
 b: byte;
begin
FSize1 := GetFileSize("с:\1.wav");
FSize2 := GetFileSize("с:\2.wav");

   AssignFile(FromF, "c:\test");
   Reset(FromF, 1);
   seek(FromF, FSize1);
   AssignFile(ToF, "c:\test.wav");
   rewrite(ToF, 1);

     repeat
       BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
       BlockWrite(ToF, Buf, NumRead, NumWritten);
     until
      (FilePos(FromF) >= FSize2) or
      (NumRead = 0) or (NumWritten <> NumRead);

     CloseFile(FromF);
     CloseFile(ToF);
end;


Так вот, почему у меня FilePos показывает что прочтено правильное количество байтов, а окончательный файл на диске получается меньше, и соотвественно не работает? Например считываемый файл длиной 1.700.000 байт, и прочтено 1.700.000 байт, а размер файла на диске получается к примеру 1.300.000 байт?
Подскажите пожалуйста в чем ошибка и как исправить?
Спасибо)


 
2012   (2011-08-17 13:52) [1]

Хм, наверное лучше спросить : Как считать из нетипизированного файла определенное число байт и на этом остановиться?)


 
Anatoly Podgoretsky ©   (2011-08-17 14:25) [2]

Тут счетчик нужен.


 
stas ©   (2011-08-17 14:50) [3]

По моему проще использовать TFileStream.


 
_Юрий   (2011-08-17 19:10) [4]

Интересно, почему многие начинающие пытаются читать\писать файлы именно так - способом, актуальным для 1980-х годов.
Толи какие то древние книги читают, толи их так учат.
Предполагаю второе. И это очень печально.
Используйте TFileStream


 
2012   (2011-08-17 21:25) [5]

Подскажите пожалуйста статейку или пример как это реализовать через стрим) И да, меня так учат.. Это задание для самостоятельной работы) Но вот беда - я никак не сделаю так, чтобы данные считывались верно. Нашел решение вот таким способом :

repeat
       BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
       BlockWrite(ToF, Buf, NumRead, NumWritten);
     until
      (GetFileSize(CreatedFile) >= OriginalFileByteCount) or
      (NumRead = 0) or (NumWritten <> NumRead);


Тогда файлы записываются на диск вполне работоспособными, но, превышающими размер оригинала на пару байт)
Вообще в кратце программа такова:
имеется СтрингГрид, в который при выполнении оупэндиалога записываются данные файла: а) название; б) длина;. После чего файл из оурэндиалога записывается \ дописывается в файл "архив".  При клике на строке в тринггриде этот файл должен вычленяться из "архивного" с тем же именем или другим, если понадобится. Сейчас все работает, но смотрится как то слишком уж глупо(
Был бы очень признателен, если бы вы меня ткнули моськой в статью где описано подобная реализация через файлстрим) Спасибо)


 
DiamondShark ©   (2011-08-18 13:01) [6]


> 2012   (17.08.11 21:25) [5]
> И да, меня так учат.

Беги оттуда. Тебя там плохому научат.
Тебя не научили, что BlockWrite может использовать свою внутреннюю буферизацию, а GetFileSize выдаёт размер файла на диске и понятия не имеет про особенности реализации BlockWrite?
Зачем тут вообще GetFileSize? Ты сам не можешь посчитать, сколько байт ты сам действительно переписал? У тебя вся информация на руках.


 
_Юрий   (2011-08-18 20:22) [7]


> Подскажите пожалуйста статейку или пример как это реализовать
> через стрим)


http://www.google.ru/search?q=TFileStream+example


 
Amoeba_   (2011-08-18 21:38) [8]

> Подскажите пожалуйста статейку или пример как это реализовать
> через стрим)

А вот и статья:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=844


 
Германн ©   (2011-08-19 00:51) [9]


> Юрий   (17.08.11 19:10) [4]
>
> Интересно, почему многие начинающие пытаются читать\писать
> файлы именно так - способом, актуальным для 1980-х годов.
>

А позвольте спросить. Чем этот способ плох?


 
Anatoly Podgoretsky ©   (2011-08-19 08:51) [10]

> Германн  (19.08.2011 00:51:09)  [9]

Ничем и даже наоборот, но надо уметь работать.
То что устаревшее не играет роли.


 
Омлет ©   (2011-08-19 09:30) [11]

> _Юрий   (17.08.11 19:10) [4]

О какой такой древности речь?
Оба способа производят чтение, вызывая ReadFile из kernel32.dll. Только обертка разная.


 
Dennis I. Komarov ©   (2011-08-19 16:13) [12]


> var
>  FromF, ToF: file;
>  NumRead, NumWritten: Integer;
>  Buf: array[1..2048] of byte;
> begin
>    AssignFile(FromF, "c:\1.wav");
>    Reset(FromF, 1);
>    AssignFile(ToF, "c:\test");
>    Reset(ToF, 1);
>    seek(tof, GetFileSize("g:\test"));
>
>      repeat
>        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
>        BlockWrite(ToF, Buf, NumRead, NumWritten);
>      until
>       (NumRead = 0) or (NumWritten <> NumRead);
>
>      CloseFile(FromF);
>      CloseFile(ToF);
> end;


 
_Юрий   (2011-08-19 19:06) [13]


> Германн ©   (19.08.11 00:51) [9]


> А позвольте спросить. Чем этот способ плох?


Скажем так, для большинства задач этот способ относительно плох, если сравнивать его со способом через стрим.
Чем - приблизительно тем же самым, чем для большинства задач процедурное программирование хуже, чем ООП.
Стриминг лучше хотя бы возможностью абстрагироваться от реализации хранилища-приемника (работать с абстрактным TStream).  

Если программист знает оба способа - это прекрасно.
Если он не знает ни одного, то сначала нужно научиться способу через стрим.
Именно потому, что он лучше подходит для большинства задач.
А тут все наоборот.


> Омлет ©   (19.08.11 09:30) [11]



> Оба способа производят чтение, вызывая ReadFile из kernel32.
> dll. Только обертка разная.


Обертка - это и есть принципиальная разница. Вообще, разные языки программирования - это ни что иное, как разные обертки вокруг одних и тех же команд процессора.
В данном случае стриминг - это обертка более высокого уровеня.
В наше время спуск на низкий уровень может быть оправдан только очень вескими причинами. Например, если критична производительность, а вы при этом настоящий ас, и сумеете написать лучше, чем авторы прикладных библиотек, которые вообще то далеко не дураки.


 
Омлет ©   (2011-08-19 19:49) [14]

> _Юрий   (19.08.11 19:06) [13]

Вы так преподносите, будто BlockRead/BlockWrite что-то подобны ассемблерным вставкам, ужас-ужас. В то время, как это обычные, вполне удобные функции, ничего архисложного в них нет. Не надо нагнетать и преувеличивать )


 
delpfir   (2011-08-19 19:53) [15]


> Не надо нагнетать и преувеличивать )


+1. Пользую периодически, как и ассемблерные вставки :)



Страницы: 1 вся ветка

Текущий архив: 2011.12.04;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.009 c
15-1310660161
Kerk
2011-07-14 20:16
2011.12.04
Кому инвайты в Google+


8-1221068545
Age
2008-09-10 21:42
2011.12.04
Работа с плеером


15-1313170131
Leon-Z
2011-08-12 21:28
2011.12.04
Delphi 2007.


2-1313252643
lazy BEGINner
2011-08-13 20:24
2011.12.04
Получение массива строк из шаблона со счетчиками


1-1276083003
Омлет
2010-06-09 15:30
2011.12.04
TDateTimePicker - ввод максимальной даты с клавиатуры