Форум: "Основная";
Текущий архив: 2003.03.06;
Скачать: [xml.tar.bz2];
ВнизГлюк с 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;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.008 c