Форум: "Основная";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
ВнизКак реализовать динамический буффер в BlockRead? Найти похожие ветки
← →
guard_gg © (2006-06-17 00:14) [0]Как реализовать динамический буффер в BlockRead?
Я хочу что бы весь файл грузился за один заход. Реально ли это?
Procedure SomeProcedure;
Var
Buf : array of Char;
F : File;
FSize,
Readed : LongWord;
Begin
AssignFile(F, ‘test.gpp’);
Reset(F, 1)
FSize := FileSize(F);
SetLength(Buf, FSize); // До энтого момента все прекрасно, Buf = (#00, #00, #00, ... )
BlockRead(F, Buf, FSize, Readed); // А после этой процедуры "умирает" Buf = ()
if buf[1] = #13 then ... // Здесь возникает вполне понятное исключение, но вопрос был не в этом.
...
...
...
End;
← →
Rial © (2006-06-17 00:28) [1]BlockRead(F,Pointer(Buf)^, FSize, Readed);
Buf - это указатель на массив. То есть в Вашем коде считываются данные
не в сам массив, а в 4-байтный указатель, и в область
памяти, находящуюся ЗА ним, а не ту, НА КОТОРУЮ он указывает.
← →
GanibalLector © (2006-06-17 00:36) [2]Не пойму зачем такие сложности??? Ведь есть куча классов : TStream,TFileStream. Почему бы Вам ими не воспользоваться?
← →
guard_gg © (2006-06-17 01:10) [3]To GanibalLector
> Не пойму зачем такие сложности??? Ведь есть куча классов
> : TStream,TFileStream. Почему бы Вам ими не воспользоваться?
>
Не люблю пользоваться чужими модулями, и модулями библиотеки VCL;
Программирую практически только процедурами и функциями WinAPI.
← →
guard_gg © (2006-06-17 01:15) [4]To Rial.
Малость ошибся когда набирал тему на форуме.
Я вливал данные не в сам указатель, забыл "^" поставить
BlockRead(F, Buf^, FSize, Readed);
Так есть способы заливать файл целиком, это всетаки гораздо быстрее?
← →
Джо © (2006-06-17 01:18) [5]
BlockRead(F, Buf[0], FSize, Readed);
← →
DrPass © (2006-06-17 01:29) [6]
> это всетаки гораздо быстрее?
Нет, не гораздо. По-большому счету, одна команда blockread не гарантирует, что файл будет заливаться целиком за один раз. Да он и не будет - файл будет читаться поблочно, постепенно заполняя буфер
← →
Rial © (2006-06-17 01:41) [7]Проводил тесты.
Максимальная производительность при чтении, равно как и при записи
достугается, очевидно, при размере буфера, кратном размеру
кластера файловой системы.
То есть для стандартной NTFS этот буфер имеет размер 4096 байт.
Макс. скорость чтения будет при размере буфера от
1 до 10 размеров кластера, т.е. 4096 - 40960 байт.
Далее скорость чтения/записи снижается.
При размере буфера порядка 100 МБ скорость уменьшается вдвое.
Тесты проводились на фалах большого размера, чтобы
исключить влияние дисковых буферов при повторном чтении.
Поэтому TMemoryStream при работе с большими файлами пришлось переписать.
Чтобы читать весть файл сразу сделай так:
Type TVoidArray=Array[0..0]of Byte;
ptVoidArray=^VoidArray;
function FileGetSize(Const Bad:Integer):Int64;//Только тут TFileStream помог
var
Pos: Int64;
begin
Pos := Seek(0, soCurrent);
Result := Seek(0, soEnd);
Seek(Pos, soBeginning);
end;
Var N:Int64;
ptV:ptVoidArray;
begin
FileOpen(..);
Try
N:=FileGetSize(Bad);
GetMem(ptV,N);
Try
FileRead(Bad,Buf^,N);
...
Finally
FreeMem(ptV,N);
end;
Finally
FileClose(Bad);
end;
← →
Defunct © (2006-06-17 08:55) [8]guard_gg © (17.06.06 01:10) [3]
Глупость какая-то.
Поверьте TFileStream будет работать куда лучше чем задуманная вами галиматья с BlockRead
← →
begin...end © (2006-06-17 09:00) [9]> Defunct © (17.06.06 08:55) [8]
Что значит "лучше"?
← →
Defunct © (2006-06-17 09:11) [10]То и значит.
← →
begin...end © (2006-06-17 09:21) [11]> Defunct © (17.06.06 09:11) [10]
Гы. Тогда зайдём с другой стороны: ПРИЧИНУ "лучшести" можно узнать?
← →
Defunct © (2006-06-17 09:27) [12]begin...end © (17.06.06 09:21) [11]
Читать сабж и станет ясно, надеюсь,
если с кодом TFileStream знакомы.
← →
begin...end © (2006-06-17 09:33) [13]> Defunct © (17.06.06 09:27) [12]
Зря надеетесь, ибо сабж я, разумеется, уже прочитал. С тем, как работает TFileStream и BlockRead, я тоже знаком, и уже давно.
Так в чём выигрыш в случае TFileStream будет? Приоткроем завесу таинственности, или как?
← →
Defunct © (2006-06-17 09:58) [14]> Зря надеетесь
понятно, но на растолковывание не располагаю ни желанием, ни временем.
> Приоткроем завесу таинственности, или как?
приоткрывайте, вы ж написали, что знакомы.
подсказка - совместимость со всеми наследниками TStream
← →
Leonid Troyanovsky © (2006-06-17 10:11) [15]
> Defunct © (17.06.06 09:58) [14]
> понятно, но на растолковывание не располагаю ни желанием,
> ни временем.
Однако, выдвинуть неочевидный тезис, время же нашлось?
Как, собс-но, и желание не промолчать.
--
Regards, LVT.
← →
begin...end © (2006-06-17 10:11) [16]> Defunct © (17.06.06 09:58) [14]
> на растолковывание не располагаю ни желанием, ни временем.
А ничего особенно растолковывать и не требуется. Требуется только сказать, чем использование TFileStream лучше использования BlockRead. Например, написать: "скорость", "простота кода" и т.д.
> приоткрывайте, вы ж написали, что знакомы.
Да, я знаком. Но таинственность напустил не я, а Вы. Поэтому и приоткрывать её -- Вам, а не мне. И объяснять, что Вы имели в виду в своём высказывании, можете Вы, но никак не я.
> подсказка - совместимость со всеми наследниками TStream
Спасибо за подсказку, но из неё, к сожалению, ничего не понятно. Во-первых, неясно, зачем нужна некая "совместимость" для задачи чтения файла в память. А во-вторых, неясно, откуда взяться этот самой "совместимости" со всеми наследниками TStream (если принять во внимание, что TFileStream является наследником THandleStream).
← →
Defunct © (2006-06-17 10:21) [17]Leonid Troyanovsky © (17.06.06 10:11) [15]
> Однако, выдвинуть неочевидный тезис, время же нашлось?
> Как, собс-но, и желание не промолчать.
Я могу обосновать сказанное, но только не begin...end. Т.к. очевидно, что он цепляется не к сказанному, а к сказавшему.
begin...end © (17.06.06 10:11) [16]
Милый друг, скажу прямо, мне просто противно общаться конкретно с вами.
← →
Leonid Troyanovsky © (2006-06-17 10:27) [18]
> guard_gg © (17.06.06 01:10) [3]
> Программирую практически только процедурами и функциями
> WinAPI.
Ну, а к чему тогда BlockRead? Тогда уж ReadFile.
> guard_gg © (17.06.06 01:15) [4]
> Так есть способы заливать файл целиком, это всетаки гораздо
> быстрее?
Зависит от.
--
Regards, LVT.
← →
begin...end © (2006-06-17 10:30) [19]> Defunct © (17.06.06 10:21) [17]
Слив засчитан.
← →
Leonid Troyanovsky © (2006-06-17 10:31) [20]
> Defunct © (17.06.06 10:21) [17]
> Я могу обосновать сказанное, но только не begin...end. Т.
> к. очевидно, что он цепляется не к сказанному, а к сказавшему.
Во-первых, не "могу", а "обязан", и не кому-то, а 2All.
Во-вторых, замечание уважаемого begin...end © было, IMHO,
вполне корректно как по форме, так и по содержанию.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2006-06-17 10:35) [21]
> begin...end © (17.06.06 10:30) [19]
А где выдержка?
--
Regards, LVT.
← →
Defunct © (2006-06-17 10:55) [22]Leonid Troyanovsky © (17.06.06 10:31) [20]
> Во-первых, не "могу", а "обязан", и не кому-то, а 2All.
Ок, По порядку.
> Глупость какая-то.
относится к [3]
>> Программирую практически только процедурами и функциями WinAPI.
Т.к. BlockRead не относится к WinAPI, а является приблудой Borland Pascal, которая перекочевала в Delphi для совместимости с более ранними версиями.
Далее:
> Поверьте TFileStream будет работать куда лучше чем задуманная вами галиматья с BlockRead
Относится к тому, что TFileStream много ближе к WinAPI хотя бы тем, что названия методов созвучны API функциям, а реализация использует непосредственно Api функции.
TFileStream является стандартым компонентом и присутсвует во всех версиях Delphi. Является очень удачной и простой в использовании оберткой над файловыми операциями, а также наследуется от TStream, что позволяет использовать его в качестве источника данных в очень многих уже написанных классах как VCL так и не VCL (например множество классов для работы с сетью могут в качестве данных использовать TStream). Множество разнообразных классов содержат метод LoadFromStream, в то время как многие наследники TStream включают метод LoadFromFile. Таким образом, единожды разобравшись с нехитрым TFileStream, автор вопроса может переключиться на класс, в котором его задача уже полностью реализована, а именно это класс TMemoryStream с его чудесными методами LoadFromStream/LoadFromFile.
> Во-вторых, замечание уважаемого begin...end © было, IMHO,
Уважаемый в узких кругах begin...end только и умеет, что делать замечания, якобы корректно и якобы содержательно.
← →
Defunct © (2006-06-17 10:56) [23]> Leonid Troyanovsky
ps: и никому, ничего я здесь не обязан.
← →
begin...end © (2006-06-17 11:20) [24]> Defunct © (17.06.06 10:55) [22]
>> Поверьте TFileStream будет работать куда лучше чем задуманная
>> вами галиматья с BlockRead
> Относится к тому, что TFileStream много ближе к WinAPI
LOL. Вы ясно сказали: "TFileStream будет работать куда лучше". Из того, что TFileStream якобы "ближе к WinAPI", вовсе не следует, что TFileStream будет лучше работать.
> ближе к WinAPI хотя бы тем, что названия методов созвучны
> API функциям
То есть если я напишу свою функцию ReadFile, в которой буду только вызывать BlockRead, то моя функция окажется ближе к WinAPI, чем BlockRead? LOL.
> реализация использует непосредственно Api функции
LOL. Открою секрет -- BlockRead/BlockWrite тоже используют API-функции. Причём те же самые, что и TFileStream.
Итого: LOL. 3 раза.
← →
Defunct © (2006-06-17 11:23) [25]Удалено модератором
← →
Leonid Troyanovsky © (2006-06-17 11:26) [26]
> Defunct © (17.06.06 10:55) [22]
> Относится к тому, что TFileStream много ближе к WinAPI хотя
> бы тем, что названия методов созвучны API функциям, а реализация
> использует непосредственно Api функции.
Дык, реализация всех паскалевских i/o также использует WinAPI.
Ну, а ближе-дальше - здесь на столько тонко, что не дает
уверенности в "лучше работает".
Т.е., правильно сформулированный ответ выглядел бы примерно так:
начинающим (одним из которых, по всей видимости, является вопрошающий)
не стоит пользоваться ни паскалевскими функциями в/в, так как они их,
все равно, не знают, ни WinAPI, а сосредоточится на изучении TStream и
его потомков, бо это проще и полезней для них, а каких либо потерь
эффективности против WinAPI они (на этапе обучения) и не заметят
(на фоне большого количества неэффективностей другого рода).
Вот последнее тебе удалось раскрыть, правда, не сразу :)
--
Regards, LVT.
← →
Leonid Troyanovsky © (2006-06-17 11:35) [27]
> Defunct © (17.06.06 10:56) [23]
> ps: и никому, ничего я здесь не обязан.
Нет уж. Т.е., есть этикет, ну, или, скажем, правила общения.
Общаешься с All - будь любезен придерживаться.
Иначе и общения не получится.
> Defunct © (17.06.06 11:23) [25]
Допустим, что форма изложения тебя чем-то раздражает,
однако, по существу-то все верно. Не так ли?
--
Regards, LVT.
← →
Defunct © (2006-06-17 12:05) [28]Leonid Troyanovsky © (17.06.06 11:35) [27]
> Нет уж. Т.е., есть этикет, ну, или, скажем, правила общения.
Общаешься с All - будь любезен придерживаться.
Иначе и общения не получится.
Ну правила, само собой. А вот то, что я обязан пояснять свои ответы, тому с кем вообще не хочу разговаривать?? это уже сверх правил IMHO.
Допустим, что форма изложения тебя чем-то раздражает,
однако, по существу-то все верно. Не так ли?
Со стороны b..e? Нет не так.
насчет [26] возможно вам лучше удалось изложить мысль, чем мне.
← →
Leonid Troyanovsky © (2006-06-17 12:31) [29]
> Defunct © (17.06.06 12:05) [28]
> Ну правила, само собой. А вот то, что я обязан пояснять
> свои ответы, тому с кем вообще не хочу разговаривать?? это
Не. Нужно быть готовым обосновать свои высказывания всегда.
И не важно, по чьему требованию.
Бо, обсуждения публичные, несмотря на адресность ответов,
а целью здешнего общения является, IMHO, избавление его
участников от ошибочного восприятия действительности
(данной нам в Delphi).
Т.е., All безразличны какие-то межличностные отношения
участников обсуждения, а важна лишь истина.
Кстати, именно поэтому, человек задавший первоначальный
вопрос (или автор топика) не имеет на него (топик) каких
либо особенных прав. Но, это так, к слову.
--
Regards, LVT.
← →
Defunct © (2006-06-17 12:52) [30]Leonid Troyanovsky © (17.06.06 12:31) [29]
Ок, принял к сведению.
спасибо за разъяснение. ;>
← →
guard_gg © (2006-06-18 03:38) [31]Вот так с "Classes" скомпилированный проект неожиданно вырос
c 8kb до 113kb =), не, мне такое точно не подходит. Я и так
за каждый киллобайт exe-шника борюсь.
to Rial;
{
BlockRead(F,Pointer(Buf)^, FSize, Readed);
Buf - это указатель на массив. То есть в Вашем коде считываются данные
не в сам массив, а в 4-байтный указатель, и в область
памяти, находящуюся ЗА ним, а не ту, НА КОТОРУЮ он указывает.
}
Спасиб, дошло как юзать blockread.
Я просто немного запутался по началу с pointerami, теперь понял
что buf сразу является указателем на массив.
Я вначале вообще планиравал
New(buf);
...
Dispose(buf);
Потому и написал что ошибся когда тему набирал - нет не ошибся
В общем спасиб те большое!
Еще хотелось бы задать пару вопросов:
1. Как программным способом можно узнать размер кластера файловой системы?
2. Не подскажет ли кто-нибудь ссылку на документацию к ассемблеру.
Не знаю с чего лучше начать изучение ентой темы.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.013 c