PDA

View Full Version : [Java] Lettura scrittura file txt


divincodin
29-04-2009, 22:38
Ultimo step del mio pregetto :D
Se nelle cose precedenti ero scarso,qui sono zero tagliato :D
Cmq,in sostanza ho dei file txt.Ogni riga del file txt contiene un commento (riferito ad una determinata immagine jpg).Ogni volta che passo alla visualizzazione della foto corrente,deve cambiare anche il commento correte (che verrà visualizzato in un 'area di testa).Quello che in sostanza faccio è di caricare tutti i commenti in un ArrayList.Poi attraverso l'area di testo dovrei poter dare la possibilità di modificare il commento corrente e poi tramite un bottone "salva" andarlo ad aggiornare nel file txt.
Quello che chiedo è se in questo caso dovrei usare l'accesso sequenziale o casuale?

PGI-Bis
30-04-2009, 01:10
Se quello che vuoi fare è dire: ok, l'utente ha cambiato il commento numero 10, adesso prendo il file e riscrivo solo la riga 10 la scelta dell'accesso casuale o sequenziale in sè è irrilevante. Un file è una successione di byte, se vuoi andare a rimpiazzare una riga con un'altra devi sovrascrivere tutti i byte che occupa quella riga nel file assicurandoti che l'ultimo sia un ritorno a capo. Se la stringa è più corta possiamo anche pensare di riempire lo spazio che resta con dei caratteri vuoti ma se è più lunga impastrocchi la linea successiva.

Se stabilisci che i commenti devano avere tutti la stessa dimensione in byte allora puoi andare a rimpiazzare un blocco con un altro con l'accesso casuale.

Ma è un approccio un po' primitivo. Tieni conto che a scrivere un file di testo di un megabyte l'hardware odierno impiega un amen e di commenti in un megabyte ne puoi mettere a bizzeffe. Magari frammenti un po' l'hard disk dell'utente. Alla fine sarebbe meglio un bel database embedded a là berkeley DB. Con dieci righe di codice scrivi tutti i commenti che vuoi senza doverti preoccupare del numero di caratteri.

pequeno
30-04-2009, 11:22
Penso che la soluzione proposta da PGI (utilizzare un db embedded) sia la cosa migliore. Ti evita diversi problemi, tipici dei file di testo.
In alternativa, se proprio vuoi utilizzare dei file, usa xml che ti consente di strutturare in maniera più determinata i dati, rispetto ad un semplice file txt e ti solleva da questioni tipo lunghezza dei campi, ritorno a capo etc...
Ovviamente il tutto dipende dalla quantità di dati da leggere/memorizzare.

divincodin
04-05-2009, 17:45
Prima di scrivere qui ho chiesto un pò ad alcuni amici e pure loro mi hanno consigliato l'utilizzo di un db,ma a me è stato chiesto di farlo con file txt.
Alla fine i file txt devono contenere 64 righe ciascuno,ognuna delle quali conterrà un commento.
Io francamente su lettura e scrittura file sn ignorante in materia e non so proprio come fare.Ho provato a buttare giù qualcosa del tipo:

try
{
RandomAccessFile raf = new RandomAccessFile(FileDiTestodir,"rw");
raf.seek(indexcorrente);
raf.write(TextArea.getText());
raf.close();
}

catch(IOException exx)
{}


dove indexcorrente è:

indexcorrente=ListaIcone.getSelectedIndex();


in sostanza l'indice dell'i-esimo elemento cliccato della lista di icone.
Quindi il 1° elemento della lista è 0,1,2...e così via.Passando questo indice al RandomAccessFile nel seek vorrei andare a scrivere nella riga specificata il contenuto della textArea.Ma forse mi sa che non ho ben capito il funzionamento del puntatore seek!
Me la invento bene la programmazione,vero??! :D

banryu79
05-05-2009, 08:44
Ultimo step del mio pregetto :D
Se nelle cose precedenti ero scarso,qui sono zero tagliato :D
Cmq,in sostanza ho dei file txt.Ogni riga del file txt contiene un commento (riferito ad una determinata immagine jpg).Ogni volta che passo alla visualizzazione della foto corrente,deve cambiare anche il commento correte (che verrà visualizzato in un 'area di testa).Quello che in sostanza faccio è di caricare tutti i commenti in un ArrayList.Poi attraverso l'area di testo dovrei poter dare la possibilità di modificare il commento corrente e poi tramite un bottone "salva" andarlo ad aggiornare nel file txt.
Quello che chiedo è se in questo caso dovrei usare l'accesso sequenziale o casuale?
e

Prima di scrivere qui ho chiesto un pò ad alcuni amici e pure loro mi hanno consigliato l'utilizzo di un db,ma a me è stato chiesto di farlo con file txt.
Alla fine i file txt devono contenere 64 righe ciascuno,ognuna delle quali conterrà un commento
....


A questo punto, la cosa più semplice secondo me sarebbe questa:
- all'avvio dell'applicazione oppure al momento opportuno (caricamento della finestra/pannello dove vengono visualizzate le immagini con i commenti editabili) ti leggi tutto il file dei commenti in un colpo solo, riga per riga, e ogni riga la memorizzi in una collezione di String in memoria;
- quando l'utente edita un commento, in pratica viene modificata solo la singola String nella tua collezione in memoria;
- alla chiusura dell'applicazione oppure al momento opportuno (chiusura della finestra/pannello dove vengono visualizzate le immagini con i commenti editabili) iteri la tua collezione di String in memoria e le stampi sul file i testo, andando in pratica a sovvrascriverlo.

Questo perchè per modificare una singola riga nel file di testo dovresti riscriverlo tutto con la riga modificata, ogni volta, il che non è il massimo della praticità, secondo me.

divincodin
05-05-2009, 18:36
Sto provando a seguire il tuo consiglio.
In sostanza prima leggo il file e carico riga x riga il contenuto in un Arraylist


BufferedReader input=newBufferedReader(newFileReader(newFile(FileDiTestodir)));
String linea=raf.readLine();
righe=new ArrayList();
//riempio l' ArrayList
while(linea!=null)
{
righe.add(linea); // aggiunge una linea letta alla lista di String
linea=raf.readLine();
}


Poi ho creato un array di stringhe "righeToArra" che avrà lo stesso contenuto dell'Arraylist...e per salvare le modifiche temporanee,userò questo.
L'aggiornamento va fatto sempre xkè,con l'applicazione aperta,l'utente può aprire un'altra cartella con altre immagini,quindi la sovrascrittura dei commenti nel file va fatta ogni volta che c'è una modifica.
Infatti ogni volta che si preme il bottone "salva" scorro l'array di stringhe e lo copio dentro l'ArrayList.
(ancora dovrei fare la vera a propria scrittura sul file...x adesso ho solo sostituito la modica nell'i-esima posizione dell'array temporaneo)
Però almeno temporaneamente dovrebbe essere aggiornato il commento,no?
Invece se premo su di un'altra foto e poi ripremo su quella alla quale ho cambiato il commento...c'è sempre il vecchio commento!


if(source==salva)
{
//riempio l'array di stringhe che userò per salvare le modifiche temporanee
//ai commenti,fatte tramite la JTextArea.
String[] righeToArray=(String[])righe.toArray(new String[1]);


//prendo il contenuto della JTextArea e salvo il commento appena modificato
//nella posizione "indexcorrente" dell'array "righeToArray"
righeToArray[indexcorrente]=TextArea.getText();
for(int i=0;i<righeToArray.length;i++)
{
righe.add(righeToArray[i]);
}
}

Dov'è che sbaglio?

banryu79
06-05-2009, 08:26
Avevo risposto punto per punto, poi mi sono partite un paio di ditate di troppo e ho perso il messaggio.
Riassumo brutalmente quello che prima avevo scritto con molta più calma:

a) non hai bisogno di copiare il contenuto della collezione di String in un array di String; è inutile e anzi prono ad errori.

b) l'errore potrebbe essere dovuto dal fatto che tu carichi la collezione di String dal file, e poi te ne fai una copia sotto forma di array di String: magari usi una di queste due collezioni di String per aggiornare il contenuto della JTextArea però poi usi l'altra per memorizzare le modifiche a runtime dei commenti.


Questo invece merita un quote e relativa risposta:

Poi ho creato un array di stringhe "righeToArra" che avrà lo stesso contenuto dell'Arraylist...e per salvare le modifiche temporanee,userò questo.
L'aggiornamento va fatto sempre xkè,con l'applicazione aperta,l'utente può aprire un'altra cartella con altre immagini,quindi la sovrascrittura dei commenti nel file va fatta ogni volta che c'è una modifica.

All'evento "aperturta di un'altra cartella con altre immagini" l'applicazione potrebbe rispondere così:
- iterazione di ogni String nella collezione in memoria e sua stampa sul file dei commenti aperto in sovvrascrittura.
- chiusura del file.
- apertura in lettura del nuovo file dei commenti (quello della nuova cartella immagini).
- caricamento della collezione di String che rappresenta i commenti contenuti nel file.


L'idea sarebbe quella di modificare al volo la collezione di String in memoria; il file dei commenti verrebbe soltanto toccato in lettura e in scrittura rispettivamente al momento dell'apertura di una cartella con immagini e al momento dell'abbandono della cartella corrente.

divincodin
07-05-2009, 16:37
Mi sa che,ad aggiornare temporaneamente l'Arraylist,ci sono riuscito:

if(source==salva)
{
//con "set" sostituisco il commento modificato con quello corrispondente
righe.set(indexcorrente,TextArea.getText());

//una volta salvato il contenuto della JTextArea,riporto
//il bottone "salva" inattivo
salva.setEnabled(false);
}


Adesso non mi resta che richiamare un metodo che riscriva tutto il contenuto dell'arraylist nel corrispondente file txt...non appena l'utente sta x aprire una nuova cartella oppure sta x chiudere l'applicazione.