Newsgroup: it.comp.lang.c
Titolo: troncare un file ad una certa dimensione

Salve a tutti, il mio problema è questo:
ho un file binario di 33MB e vorrei eliminarne gli ultimi 3MB. Dal momento
che non ho mai gestito files binari in C, vi chiedo come posso fare a
risolvere il mio problema.
Posso usare lo stesso fgets & fputs? (credo di no, non essendo sicuro della
presenza di newline in un file binario)
Grazie per l'attenzione
Marco Coppo
University Of Sheffield

presenza di newline in un file binario)
No, in un file binario no.
--
Andrea Laforgia
andrea_...@bigfoot.com

 risolvere il mio problema. Posso usare lo stesso fgets & fputs?
No, devi utilizzare fgetc()/fputc() o fread()/fwrite() e assicurarti di
aprire il file in modalità binaria.
EMG

 ho un file binario di 33MB e vorrei eliminarne gli ultimi 3MB.
Se programmi su Amiga c'è ... (un momento che cerco il vecchio Amiga Rom
Kernel Manual)... eccola:
la funzione SetFileSize(file,offset,mode), presente nella dos.library.
Su unix, linux, windows non ci sono API che svolgano tale funzione, per cui
sei costretto a ricopiarti tutto il tuo file sino alla grandezza desiderata
su un file nuovo temporaneo, quindi cancellare il vecchio file e poi
rinominare il file temporaneo con il nome del file iniziale.
Maremma zucchina! Possibile che se uno ha, ad esempio, un disco da 1 giga e
vuole "scorciare" il suo file da 600 MB a 550 MB sia costretto a comprare un
hard disk nuovo?
Ciao
        gpb

In Pascal (o forse solo in Turbo Pascal), c'era la comoda funzione Trunc.
Forse il SO mette a disposizione qualcosa di analogo, ma bisognerebbe
spilciare tra la documentazione.
Altrimenti l'unica è copiare il file fino alla posizione desiderata, e poi
chiuderlo. (cambio di nome, cancellazione dell'originale, ecc)
--
Alessandro Monti

]

hard disk nuovo?
Come ho detto in un altro post non e' vero. In tutti i sistemi unix
like esiste truncate, secondo posix esiste ftruncate.
Windows va sempre per conto suo e, a meno che non si usi cygwin, per
cui vanno benissimo le precedenti, esiste chsize() 


 Hope whai ake\ Waewae takahia kia kino
che vor dģ?

cui vanno benissimo le precedenti, esiste chsize() 
Idem.
chsize() non e' ne' ANSI, ne' POSIX.
--
Andrea Laforgia
andrea_...@bigfoot.com

rinominare il file temporaneo con il nome del file iniziale.
Non e' vero, le "API" ci sono.
--
Andrea Laforgia
andrea_...@bigfoot.com

]

 fai un man ftruncate... (truncate non e' posix, ftruncate si')
Il DJGPP non lo dà come POSIX. Chi ha ragione?
EMG


Io uso egcs e la da' come POSIX, ieee standard 1003.1/96 (nelle
versioni precedenti dello standard molto porb. non esisteva)


 ftruncate() non e' ne' ANSI, ne' POSIX.
[root@fokhouse /root]# man ftruncate | col -b | grep -A 6 ^CONF
CONFORMING TO
       4.4BSD,  SVr4  (these function calls first appeared in BSD
       4.2).  SVr4 documents additional truncate error conditions
       EINTR,  EMFILE,  EMULTIHP,  ENAMETOOLONG, ENFILE, ENOLINK,
       ENOTDIR.  SVr4 documents for ftruncate  additional  EAGAIN
       and  EINTR  error conditions.  POSIX has ftruncate but not
       truncate.
[root@fokhouse /root]#
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

CONFORMING TO
[snip]
Dall'help del DJGPP :
int ftruncate(int file, off_t where);
Portability
-----------
not ANSI, not POSIX
--
Andrea Laforgia
andrea_...@bigfoot.com

fai un man ftruncate... (truncate non e' posix, ftruncate si')
Vedi risposta a Foco.
--
Andrea Laforgia
andrea_...@bigfoot.com


Posix pre-96 credo di si' (vedi mia risposta ad EMG). Prob. il djgpp non
e' il massimo dell'aggiornamento

 Prob. il djgpp non e' il massimo dell'aggiornamento
A me risulta invece uno dei compilatori più aggiornati. Forse magari è
quel particolare punto della documentazione a non essere aggiornato.
Poco importante comunque.
EMG

 not ANSI, not POSIX
Sembrerebbe un problema di documentazione poco aggiornata...
Che versione del compilatore e delle librerie usa il DJGPP ?


 Che versione del compilatore e delle librerie usa il DJGPP ?
2.95.
EMG

Sembrerebbe un problema di documentazione poco aggiornata...
Cosi' pare, anche se mi sto convincendo che forse e' un errore di
scrittura dell'help...
Il CD da cui ho tratto il DJGPP e' del 1997.
--
Andrea Laforgia
andrea_...@bigfoot.com



Poco importante comunque.
Probabilmente hanno commesso un errore di trascrizione.
--
Andrea Laforgia
andrea_...@bigfoot.com

 2.95.
Questa dovrebbe essere la versione dell'egcs. E la libc ?


 Questa dovrebbe essere la versione dell'egcs. E la libc ?
Uhm, come la vedo?
EMG

 Uhm, come la vedo?
Se non lo sai tu...8)
Forse qualcosa tipo
[root@fokhouse /root]# strings /lib/
libc-2.1.2.so
  | grep 'GNU C Lib'
GNU C Library stable release version 2.1.2, by Roland McGrath et al.
[root@fokhouse /root]#


 [root@fokhouse /root]#
Niente. Ho provato in tutti i modi e non sono riuscito a capire quale
sia la versione delle librerie C fornite con il DJGPP. Qualcuno lo sa?
EMG


Ok, però se quello che penso è giusto, ci metterà mezz'ora... ti faccio un
esempio. 
Io ho fatto una cosa simile (in Delphi, non in C, ma credo che a livello di SO
le operazioni siano le stesse), per il calcolo della bolletta. Praticamente, Win
mette nel log della connessione (che io uso per calcolare il tempo di
navigazione) alcuni caratteri che le procedure per leggere le stringhe
interpretano come fine di file. Allora prima di leggere le righe una dopo
l'altra devo eliminare questi pseudo-EOF. Allora apro il file in binario e leggo
un carattere alla volta, controllo che non sia EOF, nel qual caso lo cancello, e
poi chiudo il file.
Beh, in soldoni, per calcolare la bolletta con un file di 57 Kb ci mette 20
secondi (ho appena finito di fare la prova), per cui con un file di 30 Mb ci
metterebbe circa 1000 sec=16.6 minuti... e non ho contato che devi poi
riscrivere il file. Lavoro con un PII300, e HD Quantum 13,6 Gb UDMA66 (ma
utilizzato a UDMA33).
Non so se è un problema del mio PC, del mio programma, o di Delphi, ma i dati
sono questi.
Bye,
            BackSlash

 Ok, però se quello che penso è giusto, ci metterà mezz'ora...
Allora potresti provare ad impostare una bufferizzazione per gli stream
con un codice simile a questo:
if ( setvbuf( fp1, 0, _IOFBF, 16384 ) != 0 )
{
    printf( "\nImpossibile allocare il buffer per fp1\n" );
    exit( EXIT_FAILURE );
}
EMG
PS. Non sono sicuro che sia standard. Sul TurboC++ 1.01 funziona e
velocizza enormemente.

metterebbe circa 1000 sec=16.6 minuti... 
E' davvero strano, comunque, che Delphi ci metta tanto.
Forse perche', diversamente dal C, non adotta bufferizzazione ?
In C ho scritto un programma che riempie casualmente un file di 30 Mb
di caratteri casuali, scrivendo uno ogni dieci una 'A'. 
Ho scritto un banalissimo programma per il calcolo dei tempi
d'esecuzione e ho sottoposto il programma di estrazione dei caratteri
diversi da 'A' al timer.
Il risultato e' stato che per estrarre 27 Mb di dati e riscriverli, ci
ha messo 36 secondi. Un tempo del tutto accettabile a mio avviso.
--
Andrea Laforgia
andrea_...@bigfoot.com