Homepage  Il progetto dsy.it è l'unofficial support site dei corsi di laurea del Dipartimento di Scienze dell'Informazione e del Dipartimento di Informatica e Comunicazione della Statale di Milano. E' un servizio degli studenti per gli studenti, curato in modo no-profit da un gruppo di essi. I nostri servizi comprendono aree di discussione per ogni Corso di Laurea, un'area download per lo scambio file, una raccolta di link e un motore di ricerca, il supporto agli studenti lavoratori, il forum hosting per Professori e studenti, i blog, e molto altro...
In questa sezione è indicizzato in textonly il contenuto del nostro forum


.dsy:it. .dsy:it. Archive > Community > Tech
 
[Programmazione C] Problema di lettura di file video
Clicca QUI per vedere il messaggio nel forum
DarkGod
Ciao, devo realizzare un programma in C che legga e successivamente modifichi dei file video che hanno una struttura simile al formato AVI.
Conosco la struttura interna del file, gli header e le informazioni che contiene, ma ho un problema quando tento di leggere i vari frame, infatti in molti casi la lettura di un frame si interrompe a metà e non riesco più a proseguire nella lettura del file.

Facendo varie prove ho capito che probabilmente il problema nasce dalla presenza di una sequenza di "zeri" all'interno del file, che viene interpretata dalla funzione read() come un carattere NULL, e quindi "fine del file". Il file però non è affatto terminato, ma se provo a fare altre read() mi viene restituito sempre 0.

Come posso leggere (e memorizare) il contenuto del file così com'è, senza che la lettura si blocchi a metà?
Grazie mille per qualsiasi aiuto... :)

yeah
Hai provato byte a byte con fgetc()?

DeepBlue
Oppure, se conosci le dimensioni del file, dovresti poter usare fread() (che fra l'altro è ANSI/POSIX compliant, al contrario della read())

DarkGod
Originally posted by yeah
Hai provato byte a byte con fgetc()?


No... domani provo, grazie! :)

DarkGod
Originally posted by DeepBlue
Oppure, se conosci le dimensioni del file, dovresti poter usare fread() (che fra l'altro è ANSI/POSIX compliant, al contrario della read())


Perchè devo conoscere le dimensioni del file per usarla?

yeah
Mi sa che con l'idea di DeepBlue fai prima, puoi recuperare tutti i byte con una sola chiamata, invece che con n chiamate.


#include <stdio.h>

size_t fread(void *buffer, size_t size, size_t number, FILE *file);


Metti size a 1 e number alla dimensione del file e sei a posto :)

DarkGod
Originally posted by yeah
Mi sa che con l'idea di DeepBlue fai prima, puoi recuperare tutti i byte con una sola chiamata, invece che con n chiamate.



Metti size a 1 e number alla dimensione del file e sei a posto :)


Aspetta... ma così leggo tutto il file in una volta sola, giusto?
Io devo leggere i vari frame uno alla volta, perchè devo modificarli e sbatterli (ad uno ad uno) in un nuovo file che sto creando.

Leggendo tutto insieme, dopo dovrei scandire il buffer di memoria per trovare i vari frame... e mi servirebbe un buffer enorme, il filmato potrebbe essere di 100 MB per esempio. Leggendo invece un frame per volta posso allocare solo pochi KB...

DeepBlue
Originally posted by DarkGod
Aspetta... ma così leggo tutto il file in una volta sola, giusto?
Io devo leggere i vari frame uno alla volta, perchè devo modificarli e sbatterli (ad uno ad uno) in un nuovo file che sto creando.


Ok: tu sai quanto è grande un frame a priori? Se sì, allora puoi vedere un po' cosa riesci a combinare con fseek().

Se no, probabilmente visto che conosci le intestazioni dei frame, forse puoi calcolarne le dimensioni ed utilizzare fseek().

DarkGod
Originally posted by DeepBlue
Ok: tu sai quanto è grande un frame a priori? Se sì, allora puoi vedere un po' cosa riesci a combinare con fseek().


Sì sì, la struttura dei frame la conosco perfettamente, campo per campo. Ogni frame ha un header che contiene anche la dimensione del frame stesso.
Il problema è che, per esempio, se ho un frame di 200 byte, faccendo:

read (file_descriptor, buffer, 200)

in alcuni frame invece di ritornarmi il valore 200, me ne ritorna uno minore. A questo punto, se faccio altre read per proseguire nella lettura, mi restituisce sempre e solo 0 (quindi non legge più nulla), come se il file fosse finito (ma ovviamente non lo è).
Da quello che ho capito, questo succede quando c'è una sequenza di zeri all'interno di un frame, che probabilmente viene interpretato dalla read() come un EOF.

Cmq, fseek() server per scorrere il puntatore in un file... ma in questo modo salto dei pezzi, no?

yeah

Aspetta... ma così leggo tutto il file in una volta sola, giusto?
Io devo leggere i vari frame uno alla volta, perchè devo modificarli e sbatterli (ad uno ad uno) in un nuovo file che sto creando.

In quel caso sì, ma se al posto della dimensione del file metti la dimensione del frame ti leggi solo il frame :)

DarkGod
Originally posted by yeah
In quel caso sì, ma se al posto della dimensione del file metti la dimensione del frame ti leggi solo il frame :)


Ma scusa... non è quello che sto già tentandio di fare? O__o
Oppure la fread() non si blocca come la read() ?

yeah
Scusa, deve essere l'ora :) e abbiamo anche postato contemporaneamente, non me ne ero accorto :)

Cmq non ho mai usato read(),però è strano che ti si 'blocchi'... in sè dovrebbe (come vedo dalle man pages) leggere un tot di byte, come la fread(), la differenza è che fread() fa parte della libreria standard del C, mentre read() è, come ha detto Deep, POSIX, quindi la sua disponibilità dipende dall'ambiente e dal compilatore.

Se vuoi prova con fread() o con fgetc(), ma secondo me il problema è un altro... mi sembra strano che si fermi per una sequenza di zeri... le man non dicono nulla a riguardo

DarkGod
Originally posted by yeah
Scusa, deve essere l'ora :) e abbiamo anche postato contemporaneamente, non me ne ero accorto :)


Come ti capisco... io ho pure la febbre e raffreddore, eh eh... :(
infatti mi sa che fra un attimo vado a nanna :)

Cmq non ho mai usato read(),però è strano che ti si 'blocchi'... in sè dovrebbe (come vedo dalle man pages) leggere un tot di byte, come la fread(), la differenza è che fread() fa parte della libreria standard del C, mentre read() è, come ha detto Deep, POSIX, quindi la sua disponibilità dipende dall'ambiente e dal compilatore.

Se vuoi prova con fread() o con fgetc(), ma secondo me il problema è un altro... mi sembra strano che si fermi per una sequenza di zeri... le man non dicono nulla


Sì, anche secondo me è strano, però i manuali dicono che la read restituisce meno byte di quanti ne dovrebbe leggere solo nel caso in cui abbia raggiunto la fine del file... Ma naturalmente un filmato di 60MB non può certo finire dopo il quarto frame! ;)
Eppure lì si blocca e non va più avanti. In ogni file si blocca in un punto diverso naturalmente.
Indagando un po' all'interno del file, ho notato che dove si blocca c'è una lunga sequenza di zeri... e dato che se non erro il carattere NULL è formato da zeri e identifica la fine di un file........

yeah

e dato che se non erro il carattere NULL è formato da zeri e identifica la fine di un file........

No, in genere indica la fine delle stringhe ;)

Puoi postare del codice? Se trovo un avi provo a darci una occhiata

DarkGod
Originally posted by yeah
No, in genere indica la fine delle stringhe ;)

Puoi postare del codice? Se trovo un avi provo a darci una occhiata


Certo!
Ma ora non ho qui il codice... posto domani.
Ciauz! E grazie! :)

DeepBlue
Originally posted by DarkGod
Sì sì, la struttura dei frame la conosco perfettamente, campo per campo. Ogni frame ha un header che contiene anche la dimensione del frame stesso.
Il problema è che, per esempio, se ho un frame di 200 byte, faccendo:

read (file_descriptor, buffer, 200)

Scusa, non mi sono spiegato bene prima: al posto di read usa fread, che non dovrebbe soffrire degli stessi problemi della read.

Per quanto riguarda la read, potete leggere qui e qui

Cmq, fseek() server per scorrere il puntatore in un file... ma in questo modo salto dei pezzi, no?

Ti serve se hai la necesità di chiudere un file e riaprirlo iniziando a leggere da un punto ben preciso (il frame n).

DarkGod
Originally posted by yeah
[B]No, in genere indica la fine delle stringhe ;)


Cavolo, hai ragione, ho fatto confusione io!
Cmq se non è per la fine del file, perchè mai la read() si blocca?? O_o

DarkGod
Originally posted by DeepBlue
al posto di read usa fread, che non dovrebbe soffrire degli stessi problemi della read.


Ok, grazie, provo con la fread! :)

DarkGod
Originally posted by DeepBlue
Scusa, non mi sono spiegato bene prima: al posto di read usa fread, che non dovrebbe soffrire degli stessi problemi della read.

Per quanto riguarda la read, potete leggere qui e qui


Leggo dal primo link che mi hai indicato:

The return value is the number of bytes actually read. This might be less than size; for example, if there aren't that many bytes left in the file or if there aren't that many bytes immediately available. The exact behavior depends on what kind of file it is. Note that reading less than size bytes is not an error.

A value of zero indicates end-of-file (except if the value of the size argument is also zero). This is not considered an error. If you keep calling read while at end-of-file, it will keep returning zero and doing nothing else.


Questo è esattamente quello che capita a me: faccio diverse read(), leggo correttaente alcuni frame, poi, all'improvviso, una read() mi restituisce MENO byte di quelli che ho indicato, e facendo successive read() mi ritorna sempre il valore zero.
Secondo la documentazione, questo dovrebbe significare che ho raggiunto la fine del file, ma non è così. La lettura di un filmato mi si è bloccata al frame 4, mentre con un altro filmato addirittura al primo frame!
Notare cmq che non sono errori casuali, ma con ogni filmato si blocca sempre allo stesso punto.

giulio
Originally posted by DarkGod
Secondo la documentazione, questo dovrebbe significare che ho raggiunto la fine del file, ma non è così. La lettura di un filmato mi si è bloccata al frame 4, mentre con un altro filmato addirittura al primo frame!
Notare cmq che non sono errori casuali, ma con ogni filmato si blocca sempre allo stesso punto. [/B]


dunque:

dal manuale di read:
code:
NAME read - read from a file descriptor


dal manuale di fread:
code:
NAME fread, fwrite - binary stream input/output


La parola chiave e' binary , che compare nel manuale di fread.
Quindi devi usare quest'ultima, perche' read interpreta come eof eventuali byte con valore 0, peraltro totalmente legittimi anche nel bel mezzo di un file binario.

DarkGod
Per usare la fread() invece della read() devo aver aperto il file con una fopen()? Perchè la fread() vuole un puntatore al file, mentre la open() mi restituisce un file descriptor integer...

giulio
Originally posted by DarkGod
Per usare la fread() invece della read() devo aver aperto il file con una fopen()? Perchè la fread() vuole un puntatore al file, mentre la open() mi restituisce un file descriptor integer...


yep!
fopen, fread, fwrite e fclose al posto di open, read, write e close.

DarkGod
Prima di sostituire tutte le funzioni, ho provato a compilarlo sotto linux (più precisamente all'interno dell'ambiente "Cygwin", che emulla linux all'interno di windows) e lì la read() funziona perfettamente, non si blocca mai!
Da cosa può dipendere? Da una diversa codifica di EOF e NULL?

DarkGod
FUNZIONA!!!! :D:D:D

Utilizzando fread e fwrite (invece di read e write) in modalità binaria, il programma funziona sia sotto win che linux!

Grazie mille per i consigli... ;)

Powered by: vbHome (lite) v4.1 and vBulletin v2.3.1 - Copyright ©2000 - 2002, Jelsoft Enterprises Limited
Mantained by dsy crew (email) | Collabora con noi | Segnalaci un bug | Archive | Regolamento |Licenze | Thanks | Syndacate