Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente bannato
    Registrato dal
    Sep 2012
    Messaggi
    465

    Problema con lettura buffer

    Non voglio risolvere il problema (ho già trovato un altro codice funzionante) ma vorrei con il vostro aiuto capire perché il codice seguente legge solo i primi 80 caratteri del file file.txt. Se fosse possibile (credo di no, ho già provato io in vari modi) mi piacerebbe trovare un sistema per far lavorare il codice per file di dimensioni molto più grandi però ripeto sarebbe un problema secondario perché ho trovato un codice che con un ciclo while e qualche altro artifizio mi risolve il problema. Ho postato solo a scopo didattico per capire l'errore che commetto.

    codice:
    	public static void leggifile() {// Metodo non funzionante
    
    		String percorso = "file.txt";
    		int dimensione = 0;
    		try {
    			File oo = new File(percorso);
    			FileReader ooo = new FileReader(oo);
    			dimensione = ooo.read();
    			ooo.close();
    			System.out.println(dimensione);// Perché 80?
    			File ff = new File(percorso);
    			FileReader fff = new FileReader(ff);
    			char[] in = new char[dimensione];
    			dimensione = fff.read(in);
    			System.out.println("Caratteri presenti: " + dimensione);
    			System.out.println("Il contenuto del file è il seguente:");
    			for (int i = 0; i < dimensione; i++)
    				System.out.print(in[i]);
    			fff.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    
    	}

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Mi sa che, come al solito, non hai letto la documentazione della classe che ti spiega esattamente cosa fanno i metodi.

    In particolare, il metodo read() legge un solo carattere e lo restituisce sottoforma di intero (ovvero, restituisce il codice ASCII del carattere).

    codice:
    dimensione = ooo.read();
    Il metodo read() non restituisce la dimensione, né del file, né di quello che è stato letto, né di altro. Restituisce il codice ASCII dell'unico carattere letto.

    Scommetto quello che vuoi che il primo carattere di quel file è "P", ovvero codice ASCII 80.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente bannato
    Registrato dal
    Sep 2012
    Messaggi
    465
    Originariamente inviato da LeleFT
    Mi sa che, come al solito, non hai letto la documentazione della classe che ti spiega esattamente cosa fanno i metodi.

    In particolare, il metodo read() legge un solo carattere e lo restituisce sottoforma di intero (ovvero, restituisce il codice ASCII del carattere).

    codice:
    dimensione = ooo.read();
    Il metodo read() non restituisce la dimensione, né del file, né di quello che è stato letto, né di altro. Restituisce il codice ASCII dell'unico carattere letto.

    Scommetto quello che vuoi che il primo carattere di quel file è "P", ovvero codice ASCII 80.


    Ciao.
    ora capisco la definizione in inglese... scommessa vinta! grazie mille!

    Saresti in grado di ipotizzare un arrangiamento?

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da peruzzo
    ora capisco la definizione in inglese... scommessa vinta! grazie mille!

    Saresti in grado di ipotizzare un arrangiamento?
    Un arrangiamento per fare cosa? Leggere un file di testo?
    codice:
    public static void leggiFile() {
       FileReader fr = null;
       try {
          File f = new File("file.txt");
          System.out.println("Caratteri presenti: " + f.length());
          fr = new FileReader( f );
          char[] buffer = new char[1024];   // Leggo (al più) 1 KB alla volta
          int byteLetti = 0;
          System.out.println("Il contenuto del file è:");
          while((byteLetti = fr.read(buffer)) >= 0) {
             for(int i=0; i<byteLetti; i++) System.out.println( buffer[i] );
          }
       } catch (Exception e) {
          e.printStackTrace();
       } finally {
          if (fr != null) {
             try { fr.close(); } catch (Exception e) { }
          }
       }
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Originariamente inviato da peruzzo
    Saresti in grado di ipotizzare un arrangiamento?
    Io ipotizzerei un classico due chitarre, basso e batteria.





    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente bannato
    Registrato dal
    Sep 2012
    Messaggi
    465
    Originariamente inviato da MItaly
    Io ipotizzerei un classico due chitarre, basso e batteria.







    MItaly come al solito sei simpaticissimo ma l'applauso va a LeleFT che è stato davvero molto bravo!
    Vorrei farvi ancora qualche domanda per essere sicuro di aver compreso a fondo il funzionamento di read(vettore di char).

    1)

    Il codice seguente:
    fr.read(buffer)
    carica in un vettore di char di nome buffer i primi 1024 caratteri presenti nel file e sposta l'inizio delle letture sucessive nel file stesso alla fine del 1024-esimo carattere o i-esimo carattere con i<1024 se il file ha meno di 1024 caratteri. Al termine della procedura conta il numero di valori diversi da null e li salva nel valore primitivo byteLetti. E' esatto quello che scrivo?
    Il ciclo while termina quando si raggiunge la fine del file e l'ultimo assegnamento a byteLetti genera un numero pari a -1 ovvero buffer con tutti valori pari a null ovvero fine della lettura del file. E' giusto anche questo?

    2)

    Hai creato un metodo try per la chiusura del file, per quale ragione? E' sbagliato chiudere fr nel primo try? (qui mi devi spiegare bene le ragioni della tua scelta...)

    3)

    Quali sono le differenze tra il sistema di LeleFT e quello che avevo pensato di usare ovvero il seguente:
    codice:
    	public static void altrasoluzione() {
    		System.out.println("Il contenuto del file è:");
    		File name = new File("dati.txt");
    		if (name.isFile()) {
    			try {
    				BufferedReader input = new BufferedReader(new FileReader(name));
    				StringBuffer buffer = new StringBuffer();
    				String text;
    				while ((text = input.readLine()) != null)
    					buffer.append(text + "\n");
    				input.close();
    				System.out.println(buffer.toString());
    			} catch (IOException ioException) {
    			}
    		}
    	}
    e soprattutto quale dei 2 mi consigliereste di usare? (PRO e CONTRO di uno e dell'altro...)

    P.S.:LeleFT volevi scrivere "System.out.print(buffer[i]);" giusto?

  7. #7
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da peruzzo
    1)

    Il codice seguente:
    fr.read(buffer)
    carica in un vettore di char di nome buffer i primi 1024 caratteri presenti nel file e sposta l'inizio delle letture sucessive nel file stesso alla fine del 1024-esimo carattere o i-esimo carattere con i<1024 se il file ha meno di 1024 caratteri. Al termine della procedura conta il numero di valori diversi da null e li salva nel valore primitivo byteLetti. E' esatto quello che scrivo?
    Ni. E' giusto fino al primo "."
    Molto più semplicemente, il metodo read(buffer) legge fino ad un massimo di buffer.length caratteri (ovvero, se buffer è un char[1024] legge fino ad un massimo di 1024 caratteri), i byte letti dal file vengono, ovviamente, portati dentro al vettore di caratteri (a partire dalla prima posizione) e il metodo restituisce il numero effettivo di byte letti (che può essere 1024 o meno, se il file termina prima). Viene, di conseguenza, spostato il puntatore di lettura del file dopo l'ultimo carattere letto.

    Il ciclo while termina quando si raggiunge la fine del file e l'ultimo assegnamento a byteLetti genera un numero pari a -1 ovvero buffer con tutti valori pari a null ovvero fine della lettura del file. E' giusto anche questo?
    Anche qui, parzialmente.
    Il ciclo termina quando si raggiunge la fine del file, ovvero quando si tenta di leggere "oltre" la fine del file, il metodo non scrive nulla dentro al vettore e si limita a ritornare il valore "-1" (valore di ritorno che viene salvato nella variabile "byteLetti"), che indica, appunto, che non ci sono altri dati da leggere.

    Stiamo lavorando con tipi primitivi, quindi non c'è niente che possa essere "null", né alcunchè da convertire.

    2)
    Hai creato un metodo try per la chiusura del file, per quale ragione? E' sbagliato chiudere fr nel primo try? (qui mi devi spiegare bene le ragioni della tua scelta...)
    Veramente ho aggiunto la sezione "finally".
    Il costrutto è il seguente:
    codice:
    try {
       ...   // operazioni che possono sollevare eccezioni
    } catch (XYZException e) {
       ... // Cattura dell'eccezione XYZException
    } finally {
       ...   // Operazioni da svolgersi SEMPRE, anche in caso di eccezioni
    }
    E' sempre consigliabile mettere le operazioni di chiusura dei file (ed, in generale, delle risorse) nel blocco finally in modo da assicurarsi che esse vengano eseguite sempre, anche nel caso vi siano state eccezioni. Non è corretto inserire la chiusura del file nel blocco try, poichè se viene sollevata un'eccezione, la chiusura potrebbe non essere effettuata:

    codice:
    try {
       FileInputStream fis = ...   // Apro il file
       ... // Uso il file
       fis.close();
    } catch (Exception e) {
       ...
    }
    Se viene sollevata un'eccezione nella parte in grassetto, l'esecuzione salta immediatamente all'area catch e la chiusura non verrà effettuata.

    3)

    Quali sono le differenze tra il sistema di LeleFT e quello che avevo pensato di usare ovvero il seguente:
    ...
    e soprattutto quale dei 2 mi consigliereste di usare? (PRO e CONTRO di uno e dell'altro...)
    Il mio metodo legge il file come se fosse una sequenza di caratteri, il tuo come se fosse una sequenza di "righe di testo". Dal punto di vista pratico, a parte l'uso di String e del consumo di memoria, non c'è alcuna differenza, dal punto di vista "concettuale" è una cosa diversa. Il mio metodo non fa alcuna supposizione sul contenuto del file, quel che c'è c'è e lo mangia; il tuo presuppone che vi siano linee di testo separate dal carattere di newLine, carattere che viene "soppresso" dalla lettura perchè si suppone non sia "un dato interessante". Ai fini pratici, l'uno e l'altro si equivalgono. Il mio potrebbe essere più efficiente, in quanto non viene fatta alcuna parserizzazione dei dati alla ricerca del newLine, quando questo viene trovato il mio non lo rimuove, tu poi lo vai ad aggiungere a mano...

    P.S.:LeleFT volevi scrivere "System.out.print(buffer[i]);" giusto?
    Sì, ormai il println() mi va in automatico con le dita...

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    Utente bannato
    Registrato dal
    Sep 2012
    Messaggi
    465


    Grazie per tutte le info!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.