Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-61077
grusta
2002-09-09 17:23
2002.09.19
Свой Bitmap в Polygon-е


1-61196
alexDaemon
2002-09-08 19:04
2002.09.19
Как работать с полноэкранной формой?


3-60938
Sergey V. Shadrin
2002-08-28 07:32
2002.09.19
консольное приложение


1-61052
liho26
2002-09-08 16:15
2002.09.19
Вот понять не могу!


1-61054
maxim2
2002-09-09 13:08
2002.09.19
Как сделать чтобы нельзя было добавлять потомка к потомку





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский