![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с чтением нетипизированного файла
2012 © (2011-08-17 13:32:00)Здравствуйте, объясните пожалуйста, в чем у меня ошибка. Есть нетипизированный файл, хранящий в себе различного рода другие файлы. Дописываю в файл так:
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 байт?
Подскажите пожалуйста в чем ошибка и как исправить?
Спасибо)
delpfir (2011-08-19 19:53:00) [1]
> Не надо нагнетать и преувеличивать )
+1. Пользую периодически, как и ассемблерные вставки :)
Омлет (2011-08-19 19:49:00) [2]> _Юрий (19.08.11 19:06) [13]
Вы так преподносите, будто BlockRead/BlockWrite что-то подобны ассемблерным вставкам, ужас-ужас. В то время, как это обычные, вполне удобные функции, ничего архисложного в них нет. Не надо нагнетать и преувеличивать )
_Юрий (2011-08-19 19:06:00) [3]
> Германн © (19.08.11 00:51) [9]
> А позвольте спросить. Чем этот способ плох?
Скажем так, для большинства задачэтот способ относительно плох, если сравнивать его со способом через стрим.
Чем - приблизительно тем же самым, чем для большинства задачпроцедурное программирование хуже, чем ООП.
Стриминг лучше хотя бы возможностью абстрагироваться от реализации хранилища-приемника (работать с абстрактным TStream).
Если программист знает оба способа - это прекрасно.
Если он не знает ни одного, то сначаланужно научиться способу через стрим.
Именно потому, что он лучше подходит для большинства задач.
А тут все наоборот.
> Омлет © (19.08.11 09:30) [11]
> Оба способа производят чтение, вызывая ReadFile из kernel32.
> dll. Только обертка разная.
Обертка - это и есть принципиальная разница. Вообще, разные языки программирования - это ни что иное, как разные обертки вокруг одних и тех же команд процессора.
В данном случае стриминг - это обертка более высокого уровеня.
В наше время спуск на низкий уровень может быть оправдан только очень вескими причинами. Например, если критична производительность, а вы при этом настоящий ас, и сумеете написать лучше, чем авторы прикладных библиотек, которые вообще то далеко не дураки.
Dennis I. Komarov (2011-08-19 16:13:00) [4]
> 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 09:30:00) [5]> _Юрий (17.08.11 19:10) [4]
О какой такой древности речь?
Оба способа производят чтение, вызывая ReadFile из kernel32.dll. Только обертка разная.
Anatoly Podgoretsky (2011-08-19 08:51:00) [6]> Германн (19.08.2011 00:51:09) [9]
Ничем и даже наоборот, но надо уметь работать.
То что устаревшее не играет роли.
Германн (2011-08-19 00:51:00) [7]
> Юрий (17.08.11 19:10) [4]
>
> Интересно, почему многие начинающие пытаются читать\писать
> файлы именно так - способом, актуальным для 1980-х годов.
>
А позвольте спросить. Чем этот способ плох?
Amoeba_ (2011-08-18 21:38:00) [8]> Подскажите пожалуйста статейку или пример как это реализовать
> через стрим)
А вот и статья:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=844
_Юрий (2011-08-18 20:22:00) [9]
> Подскажите пожалуйста статейку или пример как это реализовать
> через стрим)
http://www.google.ru/search?q=TFileStream+example
DiamondShark (2011-08-18 13:01:00) [10]
> 2012 (17.08.11 21:25) [5]
> И да, меня так учат.
Беги оттуда. Тебя там плохому научат.
Тебя не научили, что BlockWrite может использовать свою внутреннюю буферизацию, а GetFileSize выдаёт размер файла на диске и понятия не имеет про особенности реализации BlockWrite?
Зачем тут вообще GetFileSize? Ты сам не можешь посчитать, сколько байт ты сам действительно переписал? У тебя вся информация на руках.
2012 (2011-08-17 21:25:00) [11]Подскажите пожалуйста статейку или пример как это реализовать через стрим)И да, меня так учат.. Это задание для самостоятельной работы) Но вот беда - я никак не сделаю так, чтобы данные считывались верно. Нашел решение вот таким способом :
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
until
(GetFileSize(CreatedFile) >= OriginalFileByteCount) or
(NumRead = 0) or (NumWritten <> NumRead);
Тогда файлы записываются на диск вполне работоспособными, но, превышающими размер оригинала на пару байт)
Вообще в кратце программа такова:
имеется СтрингГрид, в который при выполнении оупэндиалога записываются данные файла: а) название; б) длина;. После чего файл из оурэндиалога записывается \ дописывается в файл "архив". При клике на строке в тринггриде этот файл должен вычленяться из "архивного" с тем же именем или другим, если понадобится. Сейчас все работает, но смотрится как то слишком уж глупо(
Был бы очень признателен, если бы вы меня ткнули моськой в статью где описано подобная реализация через файлстрим) Спасибо)
_Юрий (2011-08-17 19:10:00) [12]Интересно, почему многие начинающие пытаются читать\писать файлы именно так - способом, актуальным для 1980-х годов.
Толи какие то древние книги читают, толи их так учат.
Предполагаю второе. И это очень печально.
Используйте TFileStream
stas (2011-08-17 14:50:00) [13]По моему проще использовать TFileStream.
Anatoly Podgoretsky (2011-08-17 14:25:00) [14]Тут счетчик нужен.
2012 (2011-08-17 13:52:00) [15]Хм, наверное лучше спросить : Как считать из нетипизированного файла определенное число байт и на этом остановиться?)