Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori
Il primo headset open-back della linea INZONE arriva a 200 euro con driver derivati dalle cuffie da studio MDR-MV1 e un peso record di soli 199 grammi
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA
Al .NEXT 2026 di Chicago, Nutanix ha mostrato quanto sia cambiata: una piattaforma software che gestisce VM, container e carichi di lavoro IA ovunque, dall’on-premise al cloud pubblico. Con un’esecuzione rapidissima sulle partnership e sulla migrazione da VMware
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta
Xiaomi Pad 8 Pro adotta il potente Snapdragon 8 Elite all'interno di un corpo con spessore di soli 5,75 mm e pannello LCD a 144Hz flicker-free, per un tablet che può essere utilizzato con accessori dedicati di altissima qualità. Fra le caratteristiche esclusive, soprattutto per chi intende usarlo con la tastiera ufficiale, c'è la modalità Workstation di HyperOS 3, che trasforma Android in un sistema operativo con interfaccia a finestre
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 21-05-2011, 01:56   #1
guylmaster
Senior Member
 
L'Avatar di guylmaster
 
Iscritto dal: Aug 2002
Messaggi: 2518
[C#] Leggere/Scrivere da file al contrario

Salve a tutti,
ho un problema, ovvero devo scrivere delle informazioni su un file, riga per riga, e poi devo poter prendere le 100 informazioni più recenti.

Presupponendo che non so quante righe ci possono essere su un file e che potrebbero essere anche tantissime (quindi no l'idea di leggersele tutte su un array e poi leggersi gli indici all'incotrario) allora mi chiedo se c'è un modo per ovviare il problema:

- O scrivendo sul file "all'incontrario", ovvero invece di appendere a fine file ogni nuova stringa di scriverla in testa;

- O leggendo dalla fine del file verso l'inizio;


Io attualmente per scrivere utilizzo il seguente codice:

Codice:
   path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
                   fs = new FileStream(path + @nomefile, FileMode.Append, FileAccess.Write);
                   streamwriter = new StreamWriter(fs);
                   streamwriter.WriteLine(linea);
                   streamwriter.Close();

Non c'è qualche modo rapido ed indolore per dirgli semplicemente di scrivere a inizio file e non a fine file?

Per leggere utilizzo analogalmente uno streamreader ed il corrispettivo metodo readline.

P.S: Contate che sto programmando un applicazione per smartphone e quindi dispongo della compact framework 3.5 e visual studio 2008, quindi magari non ho tutti i controlli possibili ed immaginabili.

Vi ringrazio in anticipo,
guylmaster.
guylmaster è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 10:13   #2
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12966
Potresti usare una struttura dati temporanea tipo Stack e poi scansionare quest'ultima scrivendo ogni elemento (riga) sul file .
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 11:53   #3
guylmaster
Senior Member
 
L'Avatar di guylmaster
 
Iscritto dal: Aug 2002
Messaggi: 2518
Quote:
Originariamente inviato da WarDuck Guarda i messaggi
Potresti usare una struttura dati temporanea tipo Stack e poi scansionare quest'ultima scrivendo ogni elemento (riga) sul file .
Il problema è che è un programma che deve stare sempre accesso, ricevere informazioni e scrivere su file. Per fare una cosa del genere dovrei avere un numero finito di informazioni, in modo che uno aspetta di leggerle tutte e poi le scrive su file. Se uno invece tiene il programma accesso per 8:00 ore che razza di stack deve fare? sopratutto poi se si blocca il programma perde 8 ore di dati..
guylmaster è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 14:26   #4
guylmaster
Senior Member
 
L'Avatar di guylmaster
 
Iscritto dal: Aug 2002
Messaggi: 2518
Ho provato ad adottare questo escamotage:
-Scrivo la nuova riga su un file temporaneo;
-Accodo nel file temporaneo le vecchie righe;
-cancello il vecchio file e faccio diventare il file temporaneo in file reale;

E' un operazione dispendiosa ma dovrebbe permettermi sostanzialmente di far apprire in testa l'ultima riga scritta, peccato che al momento di dover cancellare il file (non il temoporaneo, quello diciamo reale) mi dice sempre che il file è in uso e non può farlo e non mi raccapacito del perchè contando che:

-poco prima stavo leggendo e se il file era in uso in qualche altra parte del programma non avrei manco letto;
-subito dopo la lettura ho chiuso tutti gli stream;

Il codice è questo se riuscite a darmi qualche dritta sul dove sbaglio mi fate sicuramente un grandissimo favore:

Codice:
            //mi creo uno stremwriter temporaneo
            path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            string nomefile = "\\temp.txt";
            FileStream temp_fs_writer = new FileStream(path + @nomefile, FileMode.Append, FileAccess.Write);
            StreamWriter temp_stremwriter = new StreamWriter(temp_fs_writer);
            temp_stremwriter.WriteLine(linea);

            //mi creo uno streamreader temporaneo
            FileStream temp_fs_reader = new FileStream(path + this.@file_scrittura, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader temp_streamreader = new StreamReader(temp_fs_reader);
            string lettura = "";
            while (!temp_streamreader.EndOfStream)
            {
                lettura = temp_streamreader.ReadLine();
                temp_stremwriter.WriteLine(lettura);
            }

            temp_streamreader.Close();
            temp_stremwriter.Close();
            temp_fs_reader.Close();
            temp_fs_writer.Close();

            File.Delete(path + this.@file_scrittura);
            File.Move(path + @nomefile, path + this.@file_scrittura);
guylmaster è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 15:07   #5
Don[ITA]
Senior Member
 
L'Avatar di Don[ITA]
 
Iscritto dal: Jul 2006
Città: Bergamo
Messaggi: 401
Potresti usare una lista lincata: ogni volta che ricevi un dato lo aggiungi in testa alla lista e scrivi il tuo file, se stai inserendo il 101 esimo dato rimuovi la coda della lista, che in pseudo codice potrebbe essere qualcosa tipo:
Codice:
aggiungi(L, dato)
begin:
size := length(L)
if (size + 1 > 100)
    remove(L)     <--- rimuovi l'ultimo elemento della lista
add(L, dato)  <--- aggiungi il dato in testa alla lista L
salva(dato)   <--- scrivi il dato sul file
end;
Così in ogni istante hai al più una lista di dimensione 100 che contiene gli ultimi 100 dati ricevuti

cya
__________________
iMac 27" 5K

Ultima modifica di Don[ITA] : 22-05-2011 alle 15:01. Motivo: (corretto un errorino nel codice, ora ogni dato che ricevi viene salvato subito su file quindi non hai perdita)
Don[ITA] è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 15:54   #6
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12966
Se il programma deve girare per 8 ore secondo me ti conviene fare come ti abbiamo detto io e Don, fissando un intervallo programmato per fare le scritture (ad esempio ogni 5 minuti sovrascrivi il file).

Al massimo in caso di blocco perdi gli ultimi 5 minuti.

Comunque, c'è una necessità reale di scrivere l'evento più recente in cima al file?

Perché secondo me è solo una complicazione che potresti risparmiare.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 16:27   #7
guylmaster
Senior Member
 
L'Avatar di guylmaster
 
Iscritto dal: Aug 2002
Messaggi: 2518
Ma secondo voi il codice mio di sopra come mai mi dice che il file è in uso se lo chiudo?

A me serve scriverlo all'incontrario altrimenti poi come faccio a prendere gli ultimo 100?

Quello della lista linkata non è proprio il massimo comunque. Ripeto non vorrei rischiare la perdita di dati.
guylmaster è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 18:45   #8
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da guylmaster Guarda i messaggi
Il problema è che è un programma che deve stare sempre accesso, ricevere informazioni e scrivere su file. Per fare una cosa del genere dovrei avere un numero finito di informazioni, in modo che uno aspetta di leggerle tutte e poi le scrive su file. Se uno invece tiene il programma accesso per 8:00 ore che razza di stack deve fare? sopratutto poi se si blocca il programma perde 8 ore di dati..
Se il programma è sempre attivo quale sarebbe il problema a tenersi in memoria un'array con le ultime 100 informazioni inserite nel file?
Alla chiusura del programma eventualmente le salvi in un file separato così che al riavvio non hai bisogno di riparserizzare tutto il file principale, ma ti leggi questo file con le ultime informazioni inserite alla precedente esecuzione.

Quanto al tuo problema dell'impossibilità di cancellare un file aperto in precedenza è un fenomeno che ho notato anch'io. Io proverei comunque ad usare lo using ovunque serva in modo che venga fatto il dispose oltre al close degli oggetti.
In ogni caso ho verificato molto spesso che su Windows passa qualche secondo tra quando uno esegue il dispose e l'effettivo rilascio del file che risulta pertanto non cancellabile perchè in uso, suppongo sia tutto merito del gc.
Generalmente in questi casi utilizzo un thread separato che provvede alla cancellazione dei file in maniera asincrona, che consente la gestione arbitraria dei ritentativi di cancellazione, senza bloccare il flusso principale.
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 19:06   #9
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
La cosa affascinante è che qui sembra quasi che leggere le righe all'inizio del file e leggerle partendo dalla fine sia qualcosa di diverso.

No, è uguale: l'unica cosa che cambia è che nel buffer di lettura anziché fare un "enqueue" si fa un "push".

In pseudo codice sarebbe:

Codice:
buffer = un buffer di caratteri
file = un ipotetico flusso di lettura di caratteri
file.position(file.size-1)
while(file.position >= 0)
     char c = file.readChar
     file.position -= 1
     if(c == interruzione di linea)
         notificaLinea(buffer)
         buffer.clear
     else
         buffer.push(c)
Diversa è la questione della scrittura: coi filesystem a me noti i file sono fatti per crescere in una sola direzione.

In questo contesto scrivere il file al contrario è una pessima idea.

A seconda poi della frequenza con cui l'operazione di lettura deve essere fatta, potrebbe valere la pena di usare un meccanismo simile a quello indicato da Don[ITA], vale a dire un logger.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 20:14   #10
guylmaster
Senior Member
 
L'Avatar di guylmaster
 
Iscritto dal: Aug 2002
Messaggi: 2518
Dunque è un operazione che dovrebbe avvenire ogni 5 minuti, per roba come 8 ore al giorno, però l'idea che se succede qualcosa ti perdi 100 rievazioni non mi piace molto.

Comunque ho capito dov'era l'errore infimo del file non chiuso. C'era una classe A che specializzava una classe B e la classe A creava uno streaming su quel file, ed io a controllare e ricontrollare le classi che entravano in gioco non me ne ero accorto.

Ora va, anche se c'è da dire che già con meno di un 100 di informazioni prememorizzate da scansionare, la creazione dello storico con il mio metodo mi impiega già 1-2 secondi. Temo che se nel file ci mettessi chesso 1 mese di informazioni, che corrisponderebbero ad una riga di file ogni 5 minuti per 8 ore al giorno, finirebbe per metterci una vita a scandirsi il file e leggere le ultime 100.

Devo provare a sovraccaricare il file e vedere di quanto e palpabile questo rallentamento.
guylmaster è offline   Rispondi citando il messaggio o parte di esso
Old 21-05-2011, 21:44   #11
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12966
Quote:
Originariamente inviato da guylmaster Guarda i messaggi
Dunque è un operazione che dovrebbe avvenire ogni 5 minuti, per roba come 8 ore al giorno, però l'idea che se succede qualcosa ti perdi 100 rievazioni non mi piace molto.

Comunque ho capito dov'era l'errore infimo del file non chiuso. C'era una classe A che specializzava una classe B e la classe A creava uno streaming su quel file, ed io a controllare e ricontrollare le classi che entravano in gioco non me ne ero accorto.

Ora va, anche se c'è da dire che già con meno di un 100 di informazioni prememorizzate da scansionare, la creazione dello storico con il mio metodo mi impiega già 1-2 secondi. Temo che se nel file ci mettessi chesso 1 mese di informazioni, che corrisponderebbero ad una riga di file ogni 5 minuti per 8 ore al giorno, finirebbe per metterci una vita a scandirsi il file e leggere le ultime 100.

Devo provare a sovraccaricare il file e vedere di quanto e palpabile questo rallentamento.
E' semplice, ogni 5 minuti fai un PUSH su una struttura dati stack e poi sovrascrivi il file con le ultime 100 informazioni (ammesso che tu debba ripeto necessariamente scrivere "al contrario").

Al massimo perdi gli ultimi 5 minuti.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Sony INZONE H6 Air: il primo headset open-back di Sony per giocatori Sony INZONE H6 Air: il primo headset open-back d...
Nutanix cambia pelle: dall’iperconvergenza alla piattaforma full stack per cloud ibrido e IA Nutanix cambia pelle: dall’iperconvergenza alla ...
Recensione Xiaomi Pad 8 Pro: potenza bruta e HyperOS 3 per sfidare la fascia alta Recensione Xiaomi Pad 8 Pro: potenza bruta e Hyp...
NZXT H9 Flow RGB+, Kraken Elite 420 e F140X: abbiamo provato il tris d'assi di NZXT NZXT H9 Flow RGB+, Kraken Elite 420 e F140X: abb...
ASUS ROG Swift OLED PG34WCDN recensione: il primo QD-OLED RGB da 360 Hz ASUS ROG Swift OLED PG34WCDN recensione: il prim...
Ecovacs presenta la gamma 2026: paviment...
Efficienza energetica fino a 2.000 volte...
Lenovo 360: il programma di canale dell'...
Appena 10.000 qubit per rompere la critt...
Analisi dei transistor durante il funzio...
Attacco informatico a Booking.com: espos...
A quattro mesi dal divieto dei social ne...
NVIDIA GeForce RTX 5060 e 5060 Ti: in ar...
Rebellions, Arm e SK Telecom, nuova alle...
Modernizzazione delle app: Red Hat OpenS...
Nel mirino di Google c'è il back ...
PRAGMATA in bundle con GeForce RTX 5000:...
Le novità MOVA per il 2026: robot e impi...
Windows, stop all'attivazione telefonica...
ASUS porta la serie TUF nel formato Mini...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 00:24.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v