Форум: "Основная";
Текущий архив: 2002.09.19;
Скачать: [xml.tar.bz2];
ВнизЗапись в файл Найти похожие ветки
← →
Viktor Kushnir (2002-09-07 08:45) [0]Требуется в произвольное место файла фставить некоторые данные, то есть:
было так: ХХХХХХХ
стало так: ХХХХПППХХХ
Вопрос: как это сделать проще чем созданием нового файла, копирования в него XXXX, затем записи ППП и копирование оставшегося ХХХ. После его старый удаляется а новый переименовывается по имени старого.
Понятно?
← →
MBo (2002-09-07 08:47) [1]Да в общем другого пути нет
← →
Viktor Kushnir (2002-09-07 08:58) [2]гм, обидно. файлы временами бывают большими, а винты медленными :(
← →
MBo (2002-09-07 09:12) [3]Ну в fat же не полезешь для изменения цепочки кластеров.
А MapView может иногда ускорить
← →
les (2002-09-07 12:56) [4]Ну еще можно делать как Word - записивать в конец но пототм при чтении конечно нужно помнить ето и читать файл хитрее...
А?
← →
Севостьянов Игорь (2002-09-07 13:57) [5]>> les (07.09.02 12:56)
Это актуально только для того случая, когда работаешь со своим форматом файла...
← →
Anatoly Podgoretsky (2002-09-07 14:04) [6]Viktor Kushnir © (07.09.02 08:45)
А насколько большой файл, может проще в буфер, начиная с позиции ППП, затем вставка и остаток из буфера, до 100 мб не страшно.
Вообще то надо бороться увеличением размера оперативной памяти.
← →
Сергей Медяник (2002-09-07 18:45) [7]У меня есть готовые процедуры. Передается FileVar - файловая переменная (file без типа), открытый Reset(f, 1), т.е. с информационной единицей 1 байт.
Позиция с 0.
//В позицию Pos1 вставляет Num неопределенных байт.
//После вызова область файла начиная с Pos1 длиной Num
//в твоем распоряжении.
procedure InsertBlockBytes(var FileVar :file; Pos1, Num :Integer);
var
Buf :Pointer;
MovedBlock :Integer;
begin
MovedBlock:=FileSize(FileVar)-Pos1;
GetMem(Buf, Num);
Seek(FileVar, FileSize(FileVar));
BlockWrite(FileVar, Buf^, Num);
FreeMem(Buf, Num);
if MovedBlock<>0 then
begin
GetMem(Buf, MovedBlock);
Seek(FileVar, Pos1);
BlockRead(FileVar, Buf^, MovedBlock);
Seek(FileVar, Pos1+Num);
BlockWrite(FileVar, Buf^, MovedBlock);
FreeMem(Buf, MovedBlock);
end;
end;
//Перемещает блок в файле (с перекрытием существующих данных)
//Pos1 - откуда, Pos2 - куда, Num - количество байт
procedure MoveBlockBytes(var FileVar :file; Pos1, Pos2, Num :Integer);
var
Buf :Pointer;
begin
if Num<>0 then
begin
GetMem(Buf, Num);
Seek(FileVar, Pos1);
BlockRead(FileVar, Buf^, Num);
Seek(FileVar, Pos2);
BlockWrite(FileVar, Buf^, Num);
FreeMem(Buf, Num);
end;
end;
//Удалает блок байт, смещая хвост.
//Работает аналогично Delete для строк
procedure DeleteBlockBytes(var FileVar :file; Pos1, Num :Integer);
var
Buf :Pointer;
MovedBlock :Integer;
begin
MovedBlock:=FileSize(FileVar)-(Pos1+Num);
GetMem(Buf, MovedBlock);
Seek(FileVar, Pos1+Num);
BlockRead(FileVar, Buf^, MovedBlock);
Seek(FileVar, Pos1);
BlockWrite(FileVar, Buf^, MovedBlock);
FreeMem(Buf, MovedBlock);
Seek(FileVar, FileSize(FileVar)-Num);
Truncate(FileVar);
end;
//использование:
var
F :File;
begin
AssignFile(F, "MYFILE.DAT");
Reset(F, 1);
//после 10 байта вставим 1Mb
InsertBlockBytes(F, 10, 1000000);
CloseFile(F);
end.
Работа проверена.
Предвижу бурную критику :-) Между прочим работает довольно быстро, при этом все на стандартных вызовах.
← →
Viktor Kushnir (2002-09-08 08:59) [8]Буду испытовать, спасибо.
← →
Serg Gurin (2002-09-09 03:29) [9]InsertBlockBytes - честно говоря вызывает сомнения в работоспособности. Так что работа проверена, как мне кажется, была плохо. Видимо на абстакциях и проверялась. Возможно автор хотел написать следующее:
procedure InsertBlockBytes(var FileVar: file; Pos1, Num: Integer);
var
Buf: Pointer;
MovedBlock: Integer;
begin
MovedBlock := FileSize(FileVar) - Pos1;
---- <
|
| if MovedBlock <> 0 then // перемещаем блок
| begin
| GetMem(Buf, MovedBlock);
| Seek(FileVar, Pos1);
| BlockRead(FileVar, Buf^, MovedBlock);
| Seek(FileVar, Pos1+Num);
| BlockWrite(FileVar, Buf^, MovedBlock);
| FreeMem(Buf, MovedBlock);
| end;
|
-> GetMem(Buf, Num); // и только затем пишем вставку, причем не в конец файла, а в позицию куда необходимо вставить
Seek(FileVar, Pos1); //именно Pos1, а не FileSize(FileVar)
BlockWrite(FileVar, Buf^, Num);
FreeMem(Buf, Num);
end;
← →
Serg Gurin (2002-09-09 03:31) [10]И работает это относительно быстро, смотря какой размер файла и как часто туда надо вставлять.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.09.19;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.006 c