Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2013.10.20;
Скачать: [xml.tar.bz2];

Вниз

Чисто теоретический вопрос на запись в файл в начало со сдвигом   Найти похожие ветки 

 
O'ShinW ©   (2013-05-06 16:01) [0]

т.е. в файл (пусть в 4Гб) надо записать 1 байт
не переписать начало, а именно вставить.

Получается, придется создать новый, записать туда байт, и скопировать остальное?

А никак документировано нельзя записать байт, а потом сказать (где-нибудь в таблице размещения блоков/еще как), что остальное брать вот оттуда ?


 
Inovet ©   (2013-05-06 16:09) [1]

Хотя бы кратно размеру кластера, и то лезть в структуры.


 
megavoid ©   (2013-05-06 16:13) [2]

Append в начало файла - только работая напрямую с ФС, да и то гемора будет предостаточно :(


 
clickmaker ©   (2013-05-06 16:14) [3]

Memory mapping?


 
DVM ©   (2013-05-06 16:16) [4]


> O"ShinW ©   (06.05.13 16:01) 

можно создать свой наследник TStream, который скомбинирует прозрачно содержимое  N других стримов, тогда добавление будет возможно, но файлов все равно будет несколько.


 
DVM ©   (2013-05-06 16:17) [5]


> clickmaker ©   (06.05.13 16:14) [3]
> Memory mapping?

А чем это поможет?


 
Павиа   (2013-05-06 16:19) [6]

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


 
DVM ©   (2013-05-06 16:20) [7]


> Павиа   (06.05.13 16:19) [6]

а как тогда в конец записать?


 
clickmaker ©   (2013-05-06 16:21) [8]

> [5] DVM ©   (06.05.13 16:17)

сдвинуть байты в памяти, не создавая новый файл


 
DVM ©   (2013-05-06 16:21) [9]

Единственный выход - страничная организация файла, как в субд разных.


 
DVM ©   (2013-05-06 16:24) [10]


> clickmaker ©   (06.05.13 16:21) [8]


> сдвинуть байты в памяти

Да сдвинуть можно и ничего никуда не отображая, данные внутри файла все равно переносить придется.


 
Павиа   (2013-05-06 16:29) [11]


> А никак документировано  нельзя записать байт, а потом сказать
> (где-нибудь в таблице размещения блоков/еще как), что остальное
> брать вот оттуда ?

Есть документированный API для создания дефрагментаторов. Там можно блоки перемешать как надо.


 
O'ShinW ©   (2013-05-06 17:03) [12]

вопрос с прочтением(отображение/интерпретацией) не стоит.
Можно писать как угодно(в конец файла, по внутренним структурам аля СУБД), и считать что это начало.
Нет, именно, вставить( на уровне ОС) данные в начало.


> данные внутри файла все равно переносить придется.

да вот и я так думаю.
если только не прибегнуть к хакам разным.

Пусть страница 4 кб, пусть пишем 1 байт, пусть.
Главное, что бы она(эта старница) стала первой потом
Есть документированный способ/ нет - не знай..


> Есть документированный API для создания дефрагментаторов.
>  Там можно блоки перемешать как надо.

не понял.
Пусть есть блок(страница) которая логически последняя на винте расположена в секторе QQQ
Дефрагментатор ее переместит в сектор WWWW - согласен. Но будет ли она логически первой?


 
robt2   (2013-05-06 17:21) [13]


> Получается, придется создать новый, записать туда байт,
> и скопировать остальное?

да


 
robt2   (2013-05-06 17:26) [14]

хотя можно новый и не создавать писать в тотже


 
Павиа   (2013-05-06 17:41) [15]


> не понял.Пусть есть блок(страница) которая логически последняя
> на винте расположена в секторе QQQДефрагментатор ее переместит
> в сектор WWWW - согласен. Но будет ли она логически первой?

Не страница, а кластер. Зачем ему блок перемешать? Можно просто поменяет в таблице кластеров запись и последний блок станет первым.


 
Inovet ©   (2013-05-06 17:53) [16]

> [7] DVM ©   (06.05.13 16:20)
> а как тогда в конец записать?

Ещё раз назад поменять.:)


 
Inovet ©   (2013-05-06 17:53) [17]

> [15] Павиа   (06.05.13 17:41)
> Можно просто поменяет в таблице кластеров запись

1 байт надо.


 
Павиа   (2013-05-06 18:00) [18]


> 1 байт надо.

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


 
Игорь Шевченко ©   (2013-05-06 18:31) [19]


> Получается, придется создать новый, записать туда байт,
> и скопировать остальное?


Да


 
Rouse_ ©   (2013-05-06 18:40) [20]

Это вообще - разовая или постоянная операция?
Если разовая, то просто создай новый файл в котором размести данные как тебе нужно, а если постоянная - советую пересмотреть формат хранения данных.
Ну на коленке в виде списка блоков, где 4 байта (N) размер блока, 8 байт оффсет на следующий и N байт сам блок. Замена одного блока на другой в два этапа, записью нового и правкой оффсета со старого на новый.


 
Inovet ©   (2013-05-06 19:29) [21]

> [18] Павиа   (06.05.13 18:00)
> После меняешь указатель начало файла, так чтобы на последний
> байт кластера указывал.

Указатель где?


 
Павиа   (2013-05-06 20:47) [22]


> Указатель где?

Вопрос был теоретический. А практически мне лень искать но в ФС он есть.


 
Игорь Шевченко ©   (2013-05-06 23:12) [23]


> А практически мне лень искать но в ФС он есть.


В какой ?


 
O'ShinW ©   (2013-05-07 08:26) [24]


> Это вообще - разовая или постоянная операция?

Да как сказать..
Уже переписал все заново (неправильно хидеры сформировал сразу, просчитался на пару байт)
Потом задумался, вот ведь на пару байт ошибся, а вставить без перезаписи файла, какого бы он размера не был, не получается.
Как-то не оптимально, что ли..


 
DevilDevil ©   (2013-05-07 09:33) [25]

> O"ShinW ©   (06.05.13 16:01) 

файловая система слишком специфична, чтобы была возможность вставить 1 байт :)
новый файл создавать не нужно. Открываешь TFileStream(fmOpenReadWrite) и через буфер переносишь данные в конец, а потом записываешь 1 байт


 
"Добрый Сок"   (2013-05-07 09:45) [26]


> DevilDevil ©   (07.05.13 09:33) [25]

есть сомнения
что если файл большой - быстрее создать и перекопировать


 
DevilDevil ©   (2013-05-07 09:52) [27]

надо тестировать
самому интересно


 
Игорь Шевченко ©   (2013-05-07 09:54) [28]


> Как-то не оптимально, что ли..


Больно слышать


 
O'ShinW ©   (2013-05-07 10:01) [29]


> Игорь Шевченко ©   (07.05.13 09:54) [28]

Это почему?


 
Inovet ©   (2013-05-07 10:22) [30]

> [26] "Добрый Сок"   (07.05.13 09:45)
> что если файл большой - быстрее создать и перекопировать

Это почему ещё?


 
clickmaker ©   (2013-05-07 11:34) [31]

hFile := CreateFile(szFileName, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
dwFileSize := GetFileSize(hFile, nil) + 1;
hMap := CreateFileMapping(hFile, nil, PAGE_READWRITE, 0, dwFileSize, "");
pView := MapViewOfFile(hMap, FILE_MAP_READ or FILE_MAP_WRITE, 0, 0, dwFileSize);
MoveMemory(pView + 1, pView, dwFileSize - 1);
pView^ := $AA;
FlushViewOfFile(pView, dwFileSize);
CloseHandle(hMap);
CloseHandle(hFile);


 
DVM ©   (2013-05-07 12:21) [32]


> clickmaker ©   (07.05.13 11:34) [31]

C 4 Гб файлом может и не заработать, т.к. здесь dwFileSize 32 бит.

dwFileSize := GetFileSize(hFile, nil) + 1;

Ну и разумеется для 4 гб надо 64 бит систему и 64 бит программу


 
reonid ©   (2013-05-07 12:32) [33]

2clickmaker ©  

А CreateFileMapping вообще сработает
при dwFileSize большем, чем реальный размер файла?

я обычно в таком случае добавлял увеличение размера с помощью
SetFilePointer, SetEndOfFile


 
NoUser ©   (2013-05-07 13:17) [34]


> Ну и разумеется для 4 гб надо 64 бит систему и 64 бит программу

Не обязательно, на то оно и MapViewOfFile


> А CreateFileMapping вообще сработает
> при dwFileSize большем, чем реальный размер файла?

Он его и увеличит.


 
DVM ©   (2013-05-07 22:45) [35]


> NoUser ©   (07.05.13 13:17) [34]


> Не обязательно, на то оно и MapViewOfFile

Как это необязательно? Адресное пространство сверх 4 Гб откуда возьмется у 32 бит программы, чтобы туда отображать файл? Мало того, нужен еще непрерывный свободный блок, вероятность чего стремится к 0. На деле 2 Гб уже отобразить проблема.


 
DVM ©   (2013-05-07 22:49) [36]


> NoUser ©

Можно отображать кусками, но тогда почти не имеем выгоды по сравнению с просто блочным чтением файла и переносом блоков, уже обсуждалось.


 
asail ©   (2013-05-07 23:34) [37]


> clickmaker ©   (07.05.13 11:34) [31]

Я, если честно, с MemoryMappedFiles особо дел не имел, но разве тут
FlushViewOfFile(pView, dwFileSize);
не произойдет все та же перезапись всех 4х гигабайт + 1 байт на диск? И в чем тогда выигрыш по сравнению со страничным/блочным переносом?


 
Inovet ©   (2013-05-07 23:54) [38]

> [37] asail ©   (07.05.13 23:34)
> И в чем тогда выигрыш по сравнению со страничным/блочным
> переносом?

Прямее будет, без дополнительных прослоек.


 
NoUser ©   (2013-05-08 01:26) [39]

> Как это необязательно?
Последовательно, кусками ~  512MB [cViewSize] (+64KB для 1-го добавочного байта) начиная с последнего куска
 Low(qwFileSize) := GetFileSize(hFile, @High(qwFileSize));
 qwOffset:=qwFileSize;
 Inc(qwFileSize, 1);

 hMap := CreateFileMapping((hFile, nil, PAGE_READWRITE, High(qwFileSize) ,Low(qwFileSize), "");

 for i := qwFileSize div cViewSize downto 1 do begin
   Dec(qwOffset,cViewSize);

   pView = MapViewOfFile(hMap, FILE_MAP_READ or FILE_MAP_WRITE, High(qwOffset) , Low(qwOffset) , cViewSize + 1 );
   MoveMemory(pView + 1, pView, cViewSize );

   if i=1 then pView^ := $AA;

   FlushViewOfFile(pView, cViewSize + 1 );
   UnmapViewOfFile(pView);                    
 end;

 CloseHandle(hMap);


> Мало того, нужен еще непрерывный свободный блок

Ну, было бы не плохо, но, не обязательно,

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


 
NoUser ©   (2013-05-08 01:44) [40]


> DVM ©   (07.05.13 22:49) [36]
> ... но тогда почти не имеем выгоды по сравнению с просто блочным
> чтением файла и переносом блоков

2 x CopyMemory  vs  1 x MoveMemory
?



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

Форум: "Прочее";
Текущий архив: 2013.10.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.003 c
15-1367688703
brother
2013-05-04 21:31
2013.10.20
проблеммы GDI?


2-1359255545
Drowsy
2013-01-27 06:59
2013.10.20
Нарисовать зеркальную картинку.


15-1367927202
delphistorm
2013-05-07 15:46
2013.10.20
Где находится Exception Types to Ignore


15-1367775508
NailMan
2013-05-05 21:38
2013.10.20
Еще не забыли летуна?


15-1367851241
Писатель
2013-05-06 18:40
2013.10.20
Delphi XE5(поддержка Андроид)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский