Форум: "Начинающим";
Текущий архив: 2011.12.04;
Скачать: [xml.tar.bz2];
ВнизПроблема с чтением нетипизированного файла Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.004 c