[C] Scrivere all'inizio di un file senza sovrascrivere

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
LiNuXMaTh
Prode Principiante
Messaggi: 2
Iscrizione: sabato 18 ottobre 2014, 8:44
Desktop: Gnome FlashBack
Distribuzione: Ubuntu 14.04

[C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da LiNuXMaTh »

Salve, ho un file txt, devo aggiungere una riga in testa a tale file (ovvero devo creare un header) senza però sovrascrivere il suo contenuto. Una prima idea è stata quella di creare un file temporaneo scrivere l'header all'interno e copiare il file txt all'interno di quello temporaneo, salvare il nome del file originale , cancellarlo e quindi rinominare il file temporaneo in quello originale. Troppo lungooo... Scorciatoie?
ps. tutto questo in ambiente linux utilizzando quindi le system call.
Avatar utente
cortinico
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 477
Iscrizione: venerdì 15 maggio 2015, 16:49
Desktop: Unity
Distribuzione: Ubuntu 15.04 amd64
Sesso: Maschile
Località: Pisa
Contatti:

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da cortinico »

Apri il file in lettura, lo leggi completamente e te lo metti in memoria.
Poi lo chiudi e lo riapri in scrittura, scrivi l'header e riscrivi il resto del file.
"Look wide, and even when you think you are looking wide – look wider still!"
http://ncorti.com
Avatar utente
errullaiolo
Prode Principiante
Messaggi: 185
Iscrizione: giovedì 17 gennaio 2013, 14:09
Distribuzione: Ubuntu 14.04.2 LTS
Sesso: Maschile

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da errullaiolo »

E un editor testuale che ci permette di sballare a nostro piacimento il testo, come lo memorizza temporaneamente? Utilizza una matrice e nel momento del salvataggio scrive sequenzialmente il file?
« Una volta eliminato l'impossibile, ciò che resta, per quanto improbabile, deve essere la verità. »
(Sherlock Holmes)
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da SuperStep »

io utilizzerei una lista doppiamente puntata, in cui ogni nodo punta ad una riga rappresentato da un'array di caratteri; quando vuoi aggiungere/rimuovere una riga non ti basta che usare le normali operazioni di inserimento/rimozione. Quando hai finito sovrascrivi il file salvando il contenuto della lista in maniera sequenziale.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Avatar utente
errullaiolo
Prode Principiante
Messaggi: 185
Iscrizione: giovedì 17 gennaio 2013, 14:09
Distribuzione: Ubuntu 14.04.2 LTS
Sesso: Maschile

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da errullaiolo »

Ed il segnaposto lampeggiante ti fornisce l'indice di inserimento nell'array. Poi devi traslare tutti i caratteri per ogni inserimento o cancellazione e quando si arriva alla ine dell'array si procede con il successivo della lista. Si puó funzionare. Grande é da provare prima o poi!!;
« Una volta eliminato l'impossibile, ciò che resta, per quanto improbabile, deve essere la verità. »
(Sherlock Holmes)
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da SuperStep »

meglio traslare solo una riga che l'intero file... non vedo soluzioni migliori di queste (anche se probabilmente esistono). Conviene comunque riallocare la riga a blocchi di 80 caratteri.

Pensando alle strutture sarebbero una cosa del genere:

Codice: Seleziona tutto

riga{
    riga_ptr;
    allocated_size;
    riga_prev;
    riga_next;
}
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da M_A_W_ 1968 »

cortinico [url=http://forum.ubuntu-it.org/viewtopic.php?p=4771223#p4771223][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Apri il file in lettura, lo leggi completamente e te lo metti in memoria.
Poi lo chiudi e lo riapri in scrittura, scrivi l'header e riscrivi il resto del file.
In codesto modo sarebbe sufficiente un qualsiasi problema, ad esempio un banalissimo glitch dell'alimentazione o un problema del file system, per perdere il contenuto originale e quello nuovo in un colpo solo. :muro:
Robustezza e integrità dei dati non sono optional, la scelta della sovrascrittura è davvero rarissima nel software professionale del real world e lo era anche quando lo spazio sui supporti di massa si misurava in centinaia di kb o in Mb.

Per questo fin dai tempi di Altair e del CP/M, per non dire da quando i nomi dei file erano costituiti da un singolo carattere esadecimale, si usa la collaudata procedura di sicurezza che consiste in:
- Rinominare il vecchio file (tipica estensione .bak del sano vecchio DOS), regolandosi razionalmente in caso di errore (se esiste già un .bak, deciderò in fase di progettazione una policy adeguata, ad esempio cancellazione o estensioni multiple .b00 eccetera);
- Creare il nuovo file in scrittura, usando il nome originale; anche qui, programmazione difensiva e gestione errori;
- Inserire in un idoneo buffer lo header e quant'altro si desidera, tenendo nota dell'offset finale;
- Aprire il vecchio file in sola lettura;
- Leggerne (se possibile) interamente i contenuti nel buffer, all'offset della prima locazione libera;
- Chiudere il vecchio file;
- Eseguire il commit del buffer nel file di output, possibilmente in una singola operazione;
- Chiudere il nuovo file;
- Cancellare eventualmente il file .bak (a questo punto è sicuro farlo).


PS: Gli editor, fin dai tempi del C64 e del DOS, sfruttano trucchi molto più evoluti e controintuitivi per gestire fluidamente e con prestazioni accettabili le sigole linee di testo. Un editor ragionevolmente semplice anche per un neofita/studente, i cui sorgenti possono essere studiati e compresi con relativa facilità, è senz'altro il buon vecchio MBEdit, clone nientepopodimeno che del mitico AEdit della Intel; ma ce ne sono in giro molti altri analoghi, da circa trent'anni, di complessità comparabile e quindi proficui anche per l'apprendimento, disponibili un po' per tutti i sistemi operativi mainstream più diffusi (inclusi molti semplici editor come pico, gedit, bluefish eccetera - facenti parte di innumerevoli distribuzioni GNU/Linux).
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da SuperStep »

M_A_W potresti spiegare meglio queste operazioni:

Codice: Seleziona tutto

- Leggerne (se possibile) interamente i contenuti nel buffer, all'offset della prima locazione libera; 
- Chiudere il vecchio file;
- Eseguire il commit del buffer nel file di output, possibilmente in una singola operazione;
nel senso che copi prima il file interamente e poi lo rimodifichi?

oppure scarichi il vecchio file su un buffer. Modifichi quel buffer, e poi lo salvi?
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da M_A_W_ 1968 »

SuperStep [url=http://forum.ubuntu-it.org/viewtopic.php?p=4771257#p4771257][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: nel senso che copi prima il file interamente e poi lo rimodifichi?

oppure scarichi il vecchio file su un buffer. Modifichi quel buffer, e poi lo salvi?
Al punto in cui hai citato la procedura, abbiamo già scritto il nostro header (i "nuovi" dati) in un ampio buffer in memoria. Supponiamo, senza perdita di generalità, che l'intero contenuto del file originale possa essere contenuto nello spazio residuo di tale buffer.

A questo punto, leggiamo dal file originale (ora .bak) l'intero contenuto e lo poniamo nel nostro buffer, a partire dalla prima locazione non utilizzata.

Quindi chiudiamo per sicurezza il file originale, e andiamo semplicemente a scrivere l'intero buffer (che ora contiene tutto: i "nuovi" dati, anteposti ai "vecchi") sul file di output, mantenuto distinto dall'originale. A seguire, le altre operazioni elencate.

Risulta sufficientemente chiaro?
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da SuperStep »

si ma in questo modo non scrivi in "pre-append" del file?

se da una parte hai le modifiche, e da un'altra parte hai il vecchio file, e il buffer finale è composto mettendo in ordine il nuovo e poi il vecchio, non mi sembra in ordine.

A meno di non utilizzare un sistema di paginazione in cui la memoria è suddivisa in blocchi, e quello che si fa è sostituire i blocchi modificati nel loro ordine.

però questo comporta che se ad un determinato punto del file, modifichi aggiungendo anche un solo byte, tutti i blocchi successivi saranno modificati.

Quello che non mi è chiaro della tua procedura è come effettui il Join dei nuovi dati con i vecchi prima di salvarli sul disco.

[EDIT]
ah ok, ho capito adesso che questo modo serve solo per risolvere questo problema. Pensavo che questo fosse il metodo generale per sovrascrivere un file.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da M_A_W_ 1968 »

SuperStep [url=http://forum.ubuntu-it.org/viewtopic.php?p=4771273#p4771273][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: ah ok, ho capito adesso che questo modo serve solo per risolvere questo problema. Pensavo che questo fosse il metodo generale per sovrascrivere un file.
Sì. La sequenza proposta è articolata in modo specifico sulla richiesta dell'OP. Con minime variazioni, risulta comunque banale applicarla al caso generale massimizzando l'integrità dei dati, come previsto dai criteri generali del software engineering.
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Avatar utente
eaghezzi
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 725
Iscrizione: martedì 21 luglio 2009, 10:27
Desktop: Lubuntu
Distribuzione: Ubuntu 14.04.1 LTS i686
Sesso: Maschile
Località: Valleambrosia

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da eaghezzi »

la soluzione migliore mi sembra quella dell'OP con uso di un file temporaneo

apro destinazione in scrittura e scrivo header
apro sorgente in lettura ciclo sulle righe leggo e scrivo riga
chiudo i files
cancello e rinomino

per le altre soluzioni fantasiose suggerisco di provare con un file log di qualche mb il blocco del so è garantito.
tunnel_net
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1988
Iscrizione: venerdì 27 febbraio 2015, 15:48
Desktop: gnome
Distribuzione: ubuntu 10.04
Sesso: Maschile

Re: [C] Scrivere all'inizio di un file senza sovrascrivere

Messaggio da tunnel_net »

Le uniche due risposte "inforrmatiche" al problema sono quelle di M_A_W_ 1968 e di eaghezzi.

Nella domanda iniziale si intuisce che il problema posto è il cercare la soluzione "estempotanea" ad una propria necessità, in questo caso qualunqge soluzione anche un echo e cat vanno bene, però in questo caso non è chiarissimo:
se parliamo di un piccolo file o di milioni di record
se la cosa è una tantum, o una soluzione da mettere in procedura

Se il problema invece non è estemporaneo ma informatico i casi siono due:
o si usa la classica tecnica degli editor come suggerito da M_A_W_ 1968 (con le limitazioni date da memoria e grandezza del file)
o si usano le classiche regole, come suggerito da eaghezzi, adottate da sempre nelle procedure di merge di due (o più) file (l'header è comunque un record esterno e quindi un file), che funzionano con milioni di record e quindi si procede a seconda del tipo di merge se per ordine di file come in questo caso o per chiave con gestione del fine file a bretella eccetera...
apt-get moo
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 6 ospiti