Domanda

Quando si utilizzano file mappati in memoria, sembra che sia di sola lettura o di sola scrittura. Con questo intendo che non puoi:

      
  • ne hai uno aperto per la scrittura e in seguito decidi di non salvarlo   
  • sono aperti per la lettura e in seguito decidono di salvarlo

La nostra applicazione utilizza un file mappabile in memoria scrivibile per salvare i file di dati, ma poiché l'utente potrebbe voler uscire senza salvare le modifiche, dobbiamo usare un file temporaneo che l'utente modifica effettivamente. Quando l'utente sceglie di salvare le modifiche, il file originale viene sovrascritto con il file temporaneo in modo che abbia le ultime modifiche. Questo è ingombrante perché i file possono essere molto grandi (> 1GB) e richiede molto tempo per copiarli.

Ho provato molte combinazioni dei flag utilizzati per creare il mapping dei file, ma nessuno sembra consentire la flessibilità del salvataggio su richiesta. Qualcuno può confermare questo è il caso? La nostra applicazione è scritta in Delphi, ma utilizza l'API standard di Windows per creare il mapping, nel nostro caso

FMapHandle := CreateFileMapping(FFileHandle, nil, PAGE_READWRITE, 0, 2 * 65536, nil);
FBasePointer := MapViewOfFile(FileMapHandle, FILE_MAP_WRITE, FileOffsetHigh,
FileOffsetLow, NumBytes);
È stato utile?

Soluzione

Non penso che tu possa. Con ciò intendo che potresti essere in grado, ma per me non ha alcun senso :-)

L'intero punto di un file mappato in memoria è che è una finestra sul file reale. Se non desideri apportare modifiche al file, probabilmente dovrai fare qualcosa come raggruppare le modifiche in una struttura di dati (ad es. Una matrice di indirizzo di base, dimensioni e dati) e applicarle durante il salvataggio.

In tal caso, in realtà non devi il file mappato in memoria, basta leggere e conservare i blocchi che si desidera modificare (bloccare prima il file se esiste la possibilità di accesso multiutente ).

Aggiornamento:

Hai pensato alla possibilità di, quando si effettua un salvataggio, eliminare il file originale e rinominare il file temporaneo con il nome del file originale? È probabile che sia molto più veloce della copia di 1G di dati da temporaneo a originale. In questo modo, se non lo desideri, è sufficiente eliminare il file temporaneo e conservare l'originale.

Dovrai comunque copiare i dati originali nel file temporaneo durante il caricamento, ma non dovrai copiare nuovamente i dati temporanei (che tu li salvi o meno) - ciò dimezzerebbe il tempo impiegato.

Altri suggerimenti

Possibile, ma non banale.

Devi comprendere le basi della memoria mappata e la differenza tra le tre modalità dei file mappati nella memoria. Entrambi mettono da parte una parte del tuo spazio di indirizzi virtuale e creano una voce di mappatura in una tabella interna. Nessuna RAM fisica è inizialmente allocata. Pertanto, quando si tenta di accedere alla memoria, gli errori della CPU e il sistema operativo devono essere corretti. Lo fa copiando il contenuto del file su RAM e mappando la RAM sul processo, all'indirizzo di errore.

Ora, la differenza tra le tre modalità è come i descrittori sono impostati sulle pagine mappate. In tutti i casi si ottiene l'accesso in lettura alle pagine. (La prima modalità). Tuttavia, se si richiede l'accesso in scrittura e successivamente si scrive ad esso, alla prima scrittura la pagina è contrassegnata come scrivibile e sporca. Può quindi essere riscritto nel file originale, a discrezione del sistema operativo (seconda modalità). Infine, è possibile ottenere la semantica della copia su scrittura. Si inizia ancora con l'accesso in sola lettura alla pagina in memoria. Quando ci si scrive, la CPU continua a guastarsi e il sistema operativo deve ripararlo. Con copy-on-write, tale correzione viene eseguita impostando il backing store della pagina modificata sul file di pagina, anziché sul file mappato originale.

Quindi, nel tuo caso, vuoi usare la modalità copia su scrittura. Se l'utente decide di annullare le modifiche, nessun problema. Basta scartare la mappatura della memoria. Tutte le pagine che sono state modificate in memoria e supportate dal file di pagina vengono anch'esse eliminate.

Se l'utente decide di salvare, hai un compito leggermente più difficile. Ora devi capire quali parti del file sono cambiate. Tali modifiche sono in memoria ed è necessario riapplicarle al file di origine. Puoi farlo con Page Guards . Pertanto, quando l'utente decide di salvare, copia tutte le pagine modificate in un blocco di memoria separato, rimappa il file (invariato) per la scrittura e applica le modifiche.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top