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

Вниз

Запись в файл   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.014 c
1-61121
LexusU
2002-09-10 12:41
2002.09.19
Как работать с zip файлами (по типу WinAMP)


3-60936
michael_b
2002-08-27 21:41
2002.09.19
Можно ли работать с Decision Cube через IBX?


6-61237
dimushkin
2002-07-12 13:04
2002.09.19
Вопрос такой...


6-61230
Alibaba
2002-07-16 13:58
2002.09.19
Как подождать результата соединения клиента с сервером?


14-61274
Jee
2002-08-23 11:37
2002.09.19
Библиотека SynEdit