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

Вниз

Глюк с TFileStream   Найти похожие ветки 

 
Fenix ©   (2003-02-24 08:55) [0]

Уважаемые мастера, помогите разобраться с такой проблемой:
мне нужно в середину файла вставить пару байтов. Ставлю position,
а он пишет в начало файла, причём не вставляет, а заменяет часть файла.


function TForm1.CopyPaste(FileName: string; pos: integer; buf: PChar): boolean;
var
old: TFileStream;
bt: byte;
begin
old:=TFileStream.Create(filename, fmOpenReadWrite);
try
old.Position:=pos;
old.WriteBuffer(buf, sizeof(buf));
except
Result:=false;
FreeAndNil(old);
Exit;
end;
FreeAndNil(old);
Result:=true;
end;


 
Юрий Зотов ©   (2003-02-24 09:29) [1]

> а он пишет в начало файла
Pos=0, вот и пишет в начало. Проверьте отладчиком.

> причём не вставляет, а заменяет часть файла.
Что умеет, то и делает. См. F1.

> Глюк с TFileStream
Нет, глючит здесь не TFileStream. Глюк совсем в другом месте - в драйвере "руки.sys".

Одним потоком Вы задачу вставки не решите, нужно 2 - источник и приемник:
Источник.Читать_файл.
Приемник.Size := Источник.Size + 2;
Приемник.CopyFrom
Приемник.WriteBuffer
Приемник.CopyFrom
Приемник.Записать_файл.

И в итоге получится двойной расход памяти. А вот без потоков, с использованием просто файловых функций, было бы лучше.


 
Романов Р.В. ©   (2003-02-24 09:48) [2]

Приведенная тобой функция предназначена не для вставки байтов, а для замены. В ней допущен целый ряд ошибок и неточностей

> old.WriteBuffer(buf, sizeof(buf));

Будет записывать 4 байта т.к. sizeof(buf) у тебя определяет размер указателя PChar, а он в данное время как раз 4 байта.

Вот этот кусок

> try
> old.Position:=pos;
> old.WriteBuffer(buf, sizeof(buf));
> except
> Result:=false;
> FreeAndNil(old);
> Exit;
> end;
> FreeAndNil(old);
> Result:=true;

Это не верно. Для освобождения ресурсов нужно испольховать конструкцию try finally. Например так
Result := False;
with TFileStream.Create(..) do
try
// Работа с потоком
Result := True;
finally
Free;
end;

Теперь по делу. Я уже тебе говорил как вставить байты в файл. Повторю еще раз. Для вставки информации в середину файла нужно использовать в общем случае 2 потока (когда файлы небольшие их можно сохранить в памяти и работать с 1 потоком). Представь что тебе нужно в середину магнитофонной касеты записать еще одну песню, при этом сохранить те пени которые уже есть. Для этого ты возьмешь исходную old:=TFileStream.Create(filename, fmOpenRead) и пустую кассету tmp := TFileStream.Create(tmpfilename, fmOpenWrite) и перепишешь на нее половину песен tmp.CopyFrom(old, old.size div 2). Затем пишешь то что ты хотел добавить tmp.WriteBuffer(buf, count). А потом дописываешь отатки tmp.CopyFrom(old, old.size - old.size div 2)
Теперь выбрасываем старую касету DeleteFile и вместо нее используем новую MoveFile.


 
Tundra   (2003-02-24 10:31) [3]

А разве нельзя использовать один поток - просто смещать даные на величину вставляемых данных ?


 
Юрий Зотов ©   (2003-02-24 11:04) [4]

> Tundra (24.02.03 10:31)

С TMemoryStream - можно, конечно.


 
Anatoly Podgoretsky ©   (2003-02-24 11:17) [5]

Tundra (24.02.03 10:31)
Можно, но это более сложный путь, чем использование двухTFileStream



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

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

Наверх




Память: 0.48 MB
Время: 0.018 c
3-16853
Alex_xelA
2003-02-14 11:07
2003.03.06
ADO


9-16845
SashaS
2002-10-02 17:33
2003.03.06
странная dxInput.mouse


1-17039
MikeFW
2003-02-25 09:27
2003.03.06
Как на чужой exe-шник навесить свой пароль?


1-17115
AZ
2003-02-22 08:56
2003.03.06
Необходимость создания кистей и перьев


1-17191
AZ
2003-02-22 19:03
2003.03.06
Редактировние графического компонента