PDA

View Full Version : [Java] Problema in lettura di un file di testo


Xizor
07-07-2009, 09:20
Salve a tutti, ho un problema con questo programma in Java:
devo aprire in lettura il seguente file di testo, leggerlo tutto ed estrapolare da esso le intere righe che mi interessano e scriverle su un altro file. Le righe che interessano sono SOLO QUELLE che indicano operazioni svolte dall'amministratore in questo file di Log. Potete darmi una mano? Non capisco perchè non funziona...:muro: :muro:

Tipo,Data,Ora,Origine,Categoria,Evento,Utente,Computer
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.29,Security,Accesso/fine sess. ,538,MAGA02$,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,540,FAR15$,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.24,Security,Accesso/fine sess. ,540,MAGA02$,SERVER
Operazioni riuscite,06/07/2009,12.07.20,Security,Accesso/fine sess. ,538,cbibiani,SERVER




import java.io.*;
import java.lang.*;
import java.util.*;

class Log {
public static void main (String args[]) {

int a=1;
char thischar=' '; //char per la lettura di un singolo carattere
String s=null; //string per la lettura di una linea

try {

FileReader f = new FileReader("protezione2.txt");
BufferedReader fIN = new BufferedReader(f);
FileWriter f2 = new FileWriter("EventLog.txt",true);
PrintWriter fOUT = new PrintWriter(f2);

s=fIN.readLine();
System.out.println(s);

do {
while(fIN.read()!=-1){
thischar=(char) fIN.read();
System.out.print(thischar);
if(thischar=='A') { //SE il carattere è 'A'
thischar=(char) fIN.read(); //leggi il carattere successivo
if(thischar=='d') { //SE il carattere successivo è 'd'
thischar=(char) fIN.read(); //leggi il carattere successivo
fOUT.println(s);
}}}
s=fIN.readLine();
}
while(s!=null);

}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}}}

banryu79
07-07-2009, 09:35
Riposto il codice, identato in modo da redere il tutto più leggibile:

import java.io.*;
import java.lang.*;
import java.util.*;

class Log
{
public static void main (String args[])
{
int a=1;
char thischar=' '; //char per la lettura di un singolo carattere
String s=null; //string per la lettura di una linea

try
{
FileReader f = new FileReader("protezione2.txt");
BufferedReader fIN = new BufferedReader(f);
FileWriter f2 = new FileWriter("EventLog.txt",true);
PrintWriter fOUT = new PrintWriter(f2);

s=fIN.readLine();
System.out.println(s);

do
{
while(thischar!='?')
{
thischar=(char) fIN.read();
System.out.print(thischar);
if(thischar=='A') { //SE il carattere è 'A'
thischar=(char) fIN.read(); //leggi il carattere successivo
if(thischar=='d') { //SE il carattere successivo è 'd'
thischar=(char) fIN.read(); //leggi il carattere successivo
fOUT.println(s);
}
}
}
s=fIN.readLine();
}
while(s!=null);
}
catch(IOException e)
{
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}
}
}


Primo "problema" che salta all'occhio:
- sia che le operazioni di I/O vadano a buon fine oppure no, gli stream non vengono chiusi.

Invece per quanto riguarda il codice che rappresenta la logica di estrazione delle stringhe desiderate:
- notiamo che ogni stringa è formata sempre da 8 campi (Tipo,Data,Ora,Origine,Categoria,Evento,Utente,Computer) separati dal carette di virgola, e quello che ci interessa è il campo Utente (il settimo): quando è uguale alla stringa "Amministratore" l'intera riga letta va inserita nel nuovo file.
- potresti realizzare semplicemente la cosa usando un oggetto java.util.Scanner (http://java.sun.com/javase/6/docs/api/java/util/Scanner.html) che supporta il parsing di String mediante uno o più delimitatori personalizzabili: nel tuo caso, dato un oggetto String che rappresenta una riga del file di input, il delimitatore per il parsing è il carattere ','.

Come procederei io:
- tramite BufferedReader leggo tutte le righe del file di input e le salvo in un array di String; chiudo il file di input.
- creo una java.util.List<String> che conterrà le String da scrivere nel nuovo file di output.
- ciclo l'array di String, per ogni String nell'array: tramite uno Scanner (con delimitatore personalizzato sul carattere di virgola) faccio il parsing della String per prendere il settimo 'token' e confrontarlo con la String "Administrator": se è uguale allora lo aggiungo alla java.util.List<String>.
- ciclo la lista di String e tramite un PrintWriter le scrivo tutte sul file di output; chiudo il file di output.

Xizor
07-07-2009, 09:43
Giusto :D
Prima del catch ma dentro il try ho messo


f.close();
f2.flush();
f2.close();


Poi credo che nel while, dove faccio il controllo con fIN.read() e -1, viene usata la funzione read, leggendo un carattere in più che invece andrebbe assegnato sempre a thischar.

Xizor
07-07-2009, 09:45
Invece per quanto riguarda il codice che rappresenta la logica di estrazione delle stringhe desiderate:
- notiamo che ogni stringa è formata sempre da 8 campi (Tipo,Data,Ora,Origine,Categoria,Evento,Utente,Computer) separati dal carette di virgola, e quello che ci interessa è il campo Utente (il settimo): quando è uguale alla stringa "Amministratore" l'intera riga letta va inserita nel nuovo file.
- potresti realizzare semplicemente la cosa usando un oggetto java.util.Scanner (http://java.sun.com/javase/6/docs/api/java/util/Scanner.html) che supporta il parsing di String mediante uno o più delimitatori personalizzabili: nel tuo caso, dato un oggetto String che rappresenta una riga del file di input, il delimitatore per il parsing è il carattere ','.

Ok, grazie, non l'ho mai usata o sentita...ma proverò a vedere come funziona da qualche parte..
E' come StringTokenizer?

ally
07-07-2009, 09:49
...potresti scorrere riga per riga e controllare se all'interno esiste la stringa "administrator" senza controllare carattere per carattere...inoltre se usi java 5 puoi utilizzare uno scanner...



Scanner in = new Scanner(new File("/home/user/miofile"));
while(in.hasNextLine()) {
String line = in.nextLine();
if(in.nextLine().indexOf("administrator")>-1)
System.out.println(line);
}


...ciao Andrea...

banryu79
07-07-2009, 09:54
Giusto :D
Prima del catch ma dentro il try ho messo


f.close();
f2.flush();
f2.close();


Poi credo che nel while, dove faccio il controllo con fIN.read() e -1, viene usata la funzione read, leggendo un carattere in più che invece andrebbe assegnato sempre a thischar.
Se il codice entra nel catch è perchè c'è stata un'eccezione di I/O e tu non sai se gli stream sono comunque stati tutti aperti o no: quindi sia nel caso venga lanciata un'eccezione che nel caso contrario bisognerebbe assicurarsi di chiudere gli stream, inserendo la chiusura nel blocco finally (e assicurandosi di invocare il metodo close solo su reference non nulle).

Xizor
07-07-2009, 10:03
La lettura delle righe nel file di input va effettuata in un ciclo while(true) ? Cioè, leggere fino a che non finisce il file?

banryu79
07-07-2009, 10:06
La lettura delle righe nel file di input va effettuata in un ciclo while(true) ? Cioè, leggere fino a che non finisce il file?
A cosa ti riferisci? Al fatto di leggerlo con un BufferedReader?
In tal caso sfrutti il metodo readLine che torna una String contente la riga letta, altrimenti torna null (e vuol dire che hai già letto tutte le righe).

Quindi imposti un ciclo su questa condizione: finchè la riga letta è diversa da null.

ally
07-07-2009, 10:07
La lettura delle righe nel file di input va effettuata in un ciclo while(true) ? Cioè, leggere fino a che non finisce il file?

...se la lettura va fatta fino a che non ha finito le righe da leggere il condizionale del while non puo' essere true (ciclo infinito)...

...ciao Andrea...

Xizor
07-07-2009, 10:12
int i=0;
String s=null;
String lines[] = new String[1000];

try {
FileReader f = new FileReader("protezione2.txt");
BufferedReader fIN = new BufferedReader(f);

s=fIN.readLine();

while(s!=null) {
i++;
s=fIN.readLine();
lines[i]=s;
}
f.close();
}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}

Così dovrebbe andare... :)

creo una java.util.List<String> che conterrà le String da scrivere nel nuovo file di output.


Come si crea? Non l'ho mai sentita :(

ally
07-07-2009, 10:22
int i=0;
String s=null;
String lines[] = new String[1000];

try {
FileReader f = new FileReader("protezione2.txt");
BufferedReader fIN = new BufferedReader(f);

s=fIN.readLine();

while(s!=null) {
i++;
s=fIN.readLine();
lines[i]=s;
}
f.close();
}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}

Così dovrebbe andare... :)



Come si crea? Non l'ho mai sentita :(

...se leggi lo stream e ti assicuri che non sia nullo perchè lo rileggi all'interno del while prima dell'assegnazione?...ti consiglio di commentare i vari passaggi del tuo metodo...

...ciao Andrea...

Xizor
07-07-2009, 10:27
...se leggi lo stream e ti assicuri che non sia nullo perchè lo rileggi all'interno del while prima dell'assegnazione?...ti consiglio di commentare i vari passaggi del tuo metodo...

...ciao Andrea...

[CODE]
s=fIN.readLine(); //leggo la prima riga

while(s!=null) { //verifico che non sia finito il file
lines[i]=s; //assegno la riga a ciascun elemento dell'array
i++; //incremento l'indice dell'array
s=fIN.readLine(); //assegno ad s la riga letta
}
f.close(); //chiudo il file di input
}CODE]

Giusto, grazie :)

ally
07-07-2009, 10:33
...c'è un altro errorino legato al counter dell'array...infine l'uso di un array inizializzato ad un valore standard puo' creare problemi...

...ciao Andrea...

Xizor
07-07-2009, 10:37
s=fIN.readLine(); //leggo la prima riga

while(s!=null) { //verifico che non sia finito il file
lines[i]=s; //assegno la riga a ciascun elemento dell'array
i++; //incremento l'indice dell'array
s=fIN.readLine(); //assegno ad s la riga letta
}
f.close(); //chiudo il file di input
}


Ok sistemato il contatore.
Per quanto riguarda l'inizializzazione non è obbligatorio inizializzare l'indice?

ally
07-07-2009, 10:41
s=fIN.readLine(); //leggo la prima riga

while(s!=null) { //verifico che non sia finito il file
lines[i]=s; //assegno la riga a ciascun elemento dell'array
i++; //incremento l'indice dell'array
s=fIN.readLine(); //assegno ad s la riga letta
}
f.close(); //chiudo il file di input
}


Ok sistemato il contatore.
Per quanto riguarda l'inizializzazione non è obbligatorio inizializzare l'indice?

...si è obbligatorio...stai solo attento che le righe lette non superino la dimensione dell'array...altrimenti sei costretto a trovare una soluzione...interrompere la lettura,incrementare la dimesnione dell'array o trovare un oggetto che non dia crucci legati alla dimensione come le List...

...ciao Andrea...

Xizor
07-07-2009, 10:47
...si è obbligatorio...stai solo attento che le righe lette non superino la dimensione dell'array...altrimenti sei costretto a trovare una soluzione...interrompere la lettura,incrementare la dimesnione dell'array o trovare un oggetto che non dia crucci legati alla dimensione come le List...

...ciao Andrea...


Vector line = new Vector();

while(s!=null) { //verifico che non sia finito il file
line.addElement(s); //assegno la riga a ciascun elemento dell'array
i++; //incremento l'indice dell'array
s=fIN.readLine(); //assegno ad s la riga letta
}


Potrei usare la classe Vector no?:)

banryu79
07-07-2009, 10:51
Mi corrego in una cosa rispetto alla procedura passo-passo che ho detto che avrei seguito:
invece di leggere tutto il file di input in un array di String per poi estrarre dall'array le String interessanti e memorizzarle su una java.util.List<String> per poi iterare su di essa farei così:
leggo tutto il file di input creando subito la List<String>; procedo iterando sulla lista e rimuovendo tutte le String che non mi interessano; quindi scrivo la List così depurata nel file di output.

In 2 parole:
java.util.List è un'interfaccia che rappresenta una collezione ordinata di elementi ovvero una sequenza ; permette all'utente l'accesso a un elemento della sequenza tramite il suo indice, nonchè la possibilità di inserire un elemento in un punto preciso; inoltre l'utente può eseguire una ricerca specificando l'elemento richesto e ottentendo come risposta la prima posizione trovata (se l'elemento è presente).
List permette l'inserimento di elementi duplicati (cioè uguali).
Fornisce all'utente un java.util.Iterator per eseguire l'iterazione della lista, inoltre fornisce lo speciale ListIterator (ha delle capacità in più rispetto al solito iteratore).

Fa parte della Collection Framework inclusa nel JDK della Sun, racchiusa nel package java.util (cha ha anche altre utilità oltre le Collection).

Un'implementazione di una List (che appunto è solo un'interfaccia) da usare nel tuo caso potrebbe essere ArrayList (questa è una classe che implementa List).

Il fatto di dire che vogliamo una List<String> significa dire che gli elementi della lista saranno di tipo String. Questa feature si chiama "Generics" ed è stata introdotta da Java 5.

Fatti un giro nella javadoc a dai un occhio alla descrizione del package java.util.

Esempio s'uso:

// creo una lista di stringhe, inzialmente vuota;
List<String> inputFile = new ArrayList<String>();

// supponiamo che 'reader' sia un BufferedReader di un file di testo aperto in lettura
String line = reader.readLine();
while(line != null)
{
inputFile.add(line);
line = reader.readLine();
}


Esempio: stampo tutte le stringhe nella list

// inputFile è la lista di prima, il costrutto for che uso qui sotto è un
// costrutto speciale introdotto con i Generics.
// Puoi leggerlo così: per ogni String 'line' in 'inputFile'... (in pratica è una sorta di for each)
for (String line : inputFile)
System.out.println(line);

oppure con un iterator (il for each dietro le quinte usa l'iterator della list)

Iterator<String> iterator = inputFile.iterator();
while (iterator.hasNext())
{
String line = iterator.next();
if (line.indexOf("Administrator") != -1)
iterator.remove();
}


@EDIT:
Potresti anche usare Vector, solo che Vector rispetto a List è un pochino meno performante, poichè Vector ha i metodi sincronizzati per potere essere utilizzato in contesti di multithreading, mentre List no.

ally
07-07-2009, 10:56
Mi corrego in una cosa rispetto alla procedura passo-passo che ho detto che avrei seguito:
invece di leggere tutto il file di input in un array di String per poi estrarre dall'array le String interessanti e memorizzarle su una java.util.List<String> per poi iterare su di essa farei così:
leggo tutto il file di input creando subito la List<String>; procedo iterando sulla lista e rimuovendo tutte le String che non mi interessano; quindi scrivo la List così depurata nel file di output.


...si è una soluzione...io sinceramente scorrerei ogni linea del file di testo e se rispetta le clausole di appartenenza ("administrator") la scriverei direttamente sul file di destinazione senza passare per una lista...anche se questo sistema puo' creare piu' problemi nella gestione di eccezioni...

...ciao Andrea...

Xizor
07-07-2009, 11:02
...si è una soluzione...io sinceramente scorrerei ogni linea del file di testo e se rispetta le clausole di appartenenza ("administrator") la scriverei direttamente sul file di destinazione senza passare per una lista...anche se questo sistema puo' creare piu' problemi nella gestione di eccezioni...



Usando la classe Vector, per la " clausola di appartenenza" ("administrator") devo utilizzare lo scanner di prima?

ally
07-07-2009, 11:03
Usando la classe Vector, per la " clausola di appartenenza" ("administrator") devo utilizzare lo scanner di prima?

...Xizor...la cosa migliore da fare in questi casi è "smanacciare" con un po' di coerenza...scrivi il tuo codice...al massimo lo si corregge...eh eh...

...ciao Andrea...

banryu79
07-07-2009, 11:05
...si è una soluzione...io sinceramente scorrerei ogni linea del file di testo e se rispetta le clausole di appartenenza ("administrator") la scriverei direttamente sul file di destinazione senza passare per una lista...anche se questo sistema puo' creare piu' problemi nella gestione di eccezioni...

...ciao Andrea...
Sì, sono d'accordo.
Io preferisco spezzare l'operazione e avere la copia dei dati sottomano tra le due operazioni; poi uno valuta che approccio usare anche a seconda della situazione.

Xizor
07-07-2009, 11:06
import java.io.*;
import java.lang.*;
import java.util.*;

class Log {
public static void main (String args[]) {

int i=0; //indice dell'array di stringhe
String s=null;
List inputFile = new ArrayList();

try {
FileReader f = new FileReader("protezione2.txt"); //apro il file di input in lettura
BufferedReader fIN = new BufferedReader(f);

String line = fIN.readLine();

while(line != null) {
inputFile.add(line);
line = fIN.readLine();
}

Iterator iterator = inputFile.iterator();
while (iterator.hasNext()){
String line = iterator.next();
if (line.indexOf("administrator") != -1)
iterator.remove();
}

}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}

}}

ally
07-07-2009, 11:07
Sì, sono d'accordo.
Io preferisco spezzare l'operazione e avere la copia dei dati sottomano tra le due operazioni; poi uno valuta che approccio usare anche a seconda della situazione.

...assolutamente...spezzare la cosa in metodi diversi sarebbe cosa gradita...dipende appunto dalle situazioni e dalla complessità...

...ciao Andrea...

Xizor
07-07-2009, 11:20
import java.io.*;
import java.lang.*;
import java.util.*;

class Log {
public static void main (String args[]) {

int i=0;
String s=null;
List inputFile = new ArrayList();

try {
FileReader f = new FileReader("protezione2.txt");
BufferedReader fIN = new BufferedReader(f);

String line = fIN.readLine();

while(line != null) {
inputFile.add(line);
line = fIN.readLine();
}

Iterator iterator = inputFile.iterator();
while (iterator.hasNext()){
line = (String) iterator.next();
if (line.indexOf("administrator") != -1)
iterator.remove();
}

}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}

}}

Ecco, va bene così?

ally
07-07-2009, 11:24
...se funziona si...

...ciao Andrea...

Xizor
07-07-2009, 11:35
Si, non ci sono errori in compilazione.
Il problema è che non so da dove ricavare l'output, le linee dove sono salvate? :confused:

ally
07-07-2009, 11:38
Si, non ci sono errori in compilazione.
Il problema è che non so da dove ricavare l'output, le linee dove sono salvate? :confused:

...le linee corrette dovrebbero essere all'interno dell'arrayList...sempre che la condizione usata per eliminare le stringhe errate non usi una logica sbagliata...e sempre che le linee eliminate siano state tolte dalla lista e non dall'iteratore usato per scorrerle...

...la cosa piu' semplice da fare è quella di scorrere l'array ottenuto e stampare a video ogni singola stringa contenuta...

...ciao Andrea...

Xizor
07-07-2009, 11:43
...le linee corrette dovrebbero essere all'interno dell'arrayList...sempre che la condizione usata per eliminare le stringhe errate non usi una logica sbagliata...e sempre che le linee eliminate siano state tolte dalla lista e non dall'iteratore usato per scorrerle...

...la cosa piu' semplice da fare è quella di scorrere l'array ottenuto e stampare a video ogni singola stringa contenuta...

...ciao Andrea...

String line = fIN.readLine();

while(line != null) {
inputFile.add(line);
line = fIN.readLine();
}

Iterator iterator = inputFile.iterator();
while (iterator.hasNext()){
line = (String) iterator.next();
if (line.indexOf("administrator") != -1)
iterator.remove();
}


Facendo iterator.remove() mi sa che le cancello dall'iteratore ma non sono sicuro...Come posso scorrere ArrayList dato che non è un array dotato di indici?

ally
07-07-2009, 11:47
...basta un ciclo for...


for(int i=0;i<inputFile.size();i++)
System.out.println(inputFile.get(i));


...ciao Andrea...

Xizor
07-07-2009, 11:52
In output escono tutte le righe :mc:

ally
07-07-2009, 11:54
...le linee corrette dovrebbero essere all'interno dell'arrayList...sempre che la condizione usata per eliminare le stringhe errate non usi una logica sbagliata...e sempre che le linee eliminate siano state tolte dalla lista e non dall'iteratore usato per scorrerle...

...ciao Andrea...

Xizor
07-07-2009, 12:05
QUOTE=ally;28128253]...le linee corrette dovrebbero essere all'interno dell'arrayList...sempre che la condizione usata per eliminare le stringhe errate non usi una logica sbagliata...e sempre che le linee eliminate siano state tolte dalla lista e non dall'iteratore usato per scorrerle...

...ciao Andrea...[/QUOTE]

import java.io.*;
import java.lang.*;
import java.util.*;

class Log {
public static void main (String args[]) {

String s=null;
List inputFile = new ArrayList();

try {
FileReader f = new FileReader("protezione.txt");
BufferedReader fIN = new BufferedReader(f);

String line = fIN.readLine();

while(line != null) {
inputFile.add(line);
line = fIN.readLine();
}

Iterator iterator = inputFile.iterator();
while (iterator.hasNext()){
line = (String) iterator.next();
if (line.indexOf("administrator") != -1)
iterator.remove(); //inputFile.remove(line)
}

for(int i=0;i<inputFile.size();i++)
System.out.println(inputFile.get(i));

}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}

}}


inputFile.remove(line) dovrebbe cancellarle dalla lista e non dall'iteratore giusto?

banryu79
07-07-2009, 12:18
inputFile.remove(line) dovrebbe cancellarle dalla lista e non dall'iteratore giusto?
Non ha nessun senso fare una distinzione concettuale tra "le righe dell'iteratore" e "le righe della lista" poichè l'iteratore è restituito dalla lista e opera sulla lista stessa.

Il metodo remove dell'iteratore rimuove dalla collezione sottostante (cioè quella che ha fornito l'iteratore stesso) l'ultimo elemento che è stato restituito dal metodo next dell'iteratore.

Se hai dubbi su qualche metodo consulta i javadoc ;)

Il problema è un'altro: tu nel tuo codice fai tutto tranne che alla fine scrivere la lista filtrata sul file di output...

banryu79
07-07-2009, 12:23
Se comunque alla fine ti stampa tutte le righe vuol dire che c'è un problema con il controllo della condizione per la rimozione.

questa dovrebbe essere giusta:

Iterator iterator = inputFile.iterator();
while (iterator.hasNext())
{
line = (String) iterator.next();
if (line.indexOf("Administrator") == -1)
iterator.remove();
}

Rimuovo la riga solo SE NON trovo la stringa "Administrator".

Xizor
07-07-2009, 12:54
import java.io.*;
import java.lang.*;
import java.util.*;

class Log {
public static void main (String args[]) {

String s=null;
List inputFile = new ArrayList();

try {
FileReader f = new FileReader("protezione.txt");
BufferedReader fIN = new BufferedReader(f);

String line = fIN.readLine();

while(line != null) {
inputFile.add(line);
line = fIN.readLine();
}

Iterator iterator = inputFile.iterator();
while (iterator.hasNext())
{
line = (String) iterator.next();
if (line.indexOf("Administrator") == -1)
iterator.remove();
}

for(int i=0;i<inputFile.size();i++)
System.out.println(inputFile.get(i));

}
catch(IOException e) {
System.out.println("Si e' verificata un'eccezione "+e.getMessage());
}

}}


In esecuzione dice :

Exception in thread "main" java.lang OutOfMemoryError: Java heap space

cos'è?

banryu79
07-07-2009, 13:11
In esecuzione dice :

Exception in thread "main" java.lang OutOfMemoryError: Java heap space

cos'è?
E' un messaggio di errore della JVM; significa che la memoria allocata dal SO alla JVM è terminata (!).

Non so come mai: ma il file protezione.txt quanto grande è?

Comunque ho provato il codice che hai costruito fino a qui e postato con un file di input così fatto:

Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.29,Security,Accesso/fine sess. ,538,MAGA02$,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,540,FAR15$,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.24,Security,Accesso/fine sess. ,540,MAGA02$,SERVER
Operazioni riuscite,06/07/2009,12.07.20,Security,Accesso/fine sess. ,538,cbibiani,SERVER


e ottengo (correttamente) questo output:

Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.30,Security,Accesso/fine sess. ,576,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,540,Administrator,SERVER
Operazioni riuscite,06/07/2009,12.07.28,Security,Accesso/fine sess. ,576,Administrator,SERVER

Xizor
07-07-2009, 13:22
Grazie 1000 :)

Allora quelle righe sono soltanto una piccolissima parte del file "protezione.txt" , le ho prese come esempio.
Compilando il codice per queste poche righe in effetti funziona correttamente come testato da te. :read:

Quando ho provato ad eseguirlo sul file intero mi ha dato che messaggio di errore. Il file protezione intero è grande 32 MB :cool:

Se esiste un metodo per evitare quel problema bene, altrimenti bene lo stesso perchè l'algoritrmo funziona. Sapevo che Java aveva una quantità impressionante di classi e metodi, infatti questi non li conoscevo. Grazie infinite lo stesso ;) ;)

banryu79
07-07-2009, 13:30
Se esiste un metodo per evitare quel problema bene, altrimenti bene lo stesso perchè l'algoritrmo funziona.

Certo che esiste: basta istruire la JVM passandole un parametro apposito che ne fissa esplicitamente la memoria massima che può richiedere al sistema operativo.
Io con ste cose non ci azzecco: non mi ricordo mai di default quant'è: a te basterebbe specificare l'ordine di grandezza successivo (es: se è 32M ne chiedi 64M, se è 64M ne chiedi 128M e così via).


Sapevo che Java aveva una quantità impressionante di classi e metodi, infatti questi non li conoscevo. Grazie infinite lo stesso ;) ;)
Beh, oserei dire che usare Java per programmare senza avvalersi del JDK ha poco senso...

Trovi tutto online (con la possibilità di scaricarti in locale la documentazione che ti interessa); due sono le risorse più utili, secondo me:
1) i javadoc del JDK
2) Quella cosa chiamata "The Really Big Index" (compendio di tutorial della Sun su quasi tutto quello che vorresti sapere del linguaggio Java e del JDK).

ally
07-07-2009, 13:31
Non ha nessun senso fare una distinzione concettuale tra "le righe dell'iteratore" e "le righe della lista" poichè l'iteratore è restituito dalla lista e opera sulla lista stessa.

Il metodo remove dell'iteratore rimuove dalla collezione sottostante (cioè quella che ha fornito l'iteratore stesso) l'ultimo elemento che è stato restituito dal metodo next dell'iteratore.

Se hai dubbi su qualche metodo consulta i javadoc ;)

Il problema è un'altro: tu nel tuo codice fai tutto tranne che alla fine scrivere la lista filtrata sul file di output...

...mio grosso errore...grazie per il chiarimento...

...ciao Andrea...