Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader
Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader
BOOX Go 6 Gen II porta per la prima volta il supporto allo stilo su un e-reader da 6 pollici, affiancando 3 GB di RAM al collaudato Snapdragon 665 e un design rivisto con scocca posteriore a costolature. Su carta la proposta è interessante, ma Android 11 fuori supporto, l'assenza di un alloggiamento per il pennino e un'autonomia ridotta rispetto agli e-reader tradizionali sono i compromessi da accettare
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro
Lenovo Idea Tab Plus prova a portare un display da 12,1 pollici 2.5K, quattro speaker Dolby Atmos e una batteria da 10.200 mAh sotto la soglia psicologica dei 300 euro, penna inclusa. Lo abbiamo usato per oltre una settimana per capire dove l'azienda ha tagliato e dove invece ha tenuto il punto
Oltre il contante e le crypto: tutto sull'Euro Digitale e la nuova sovranità monetaria europea
Oltre il contante e le crypto: tutto sull'Euro Digitale e la nuova sovranità monetaria europea
L'euro digitale è una valuta fiat che entrerà in vigore nei prossimi anni. L'obiettivo principale è quello di ridurre la dipendenza dalle piattaforme di pagamento digitali statunitensi e offrire ai cittadini un modo semplice per trasferire denaro. Anche offline, anche in maniera (pseudo)anonima
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 01-08-2008, 13:52   #1
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
[Java] Come fare un log parser che simula tail -f?

Ciao a tutti. Avrei bisogno di un consiglio su come realizzare l'oggetto del topic. Fin'ora non ho mai scritto programmi che non utilizzassero gli stream per leggere da file di input, mentre ora avrei bisogno di:

mettermi in "tail" su un certo log
possibilmente filtrare la roba che viene effettivamente caricata in memoria
parsare la roba che viene caricata in memoria

Il punto 3 è ok in quanto è virtualmente analogo a ciò che ho gia, i primi due sono più oscuri. Qualcuno mi sa indicare una libreria o qualcosa di utile?

Grazie,
TD
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 01-08-2008, 16:44   #2
ally
Bannato
 
L'Avatar di ally
 
Iscritto dal: Jan 2003
Città:
Messaggi: 4423
...mi verrebbe da consigliare l'uso di librerie ssh come le jsch e catturare l'output della console...

...ciao...
ally è offline   Rispondi citando il messaggio o parte di esso
Old 01-08-2008, 16:52   #3
ally
Bannato
 
L'Avatar di ally
 
Iscritto dal: Jan 2003
Città:
Messaggi: 4423
...ma a volte la soluzione è piu' banale...

Codice:
public class Tail {
	
	public static void main(String[] args)  {
		
		new Tail("c:/test.txt");
		
	}
	
	public Tail(String file){
		
		try{
			Reader fileReader = new FileReader(file);
			BufferedReader input = new BufferedReader(fileReader);
			String line = null;
			while (true) {
				if ((line = input.readLine()) != null) {
					System.out.println(line);
					continue;
				}
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException x) {
					Thread.currentThread().interrupt();
					break;
				}
			}
			input.close();
		}catch(Exception e){
			System.out.println(e);
		}
	}
}
...ciao...
ally è offline   Rispondi citando il messaggio o parte di esso
Old 01-08-2008, 20:46   #4
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
Innanzitutto grazie mille perchè dovrebbe andare bene!
Avrei però un paio di domande...

1) immagino che non sia possibile evitare di fare polling ogni x secondi, ma innescare una read solo quando lo stato del file cambia?

2) scusa ma dove vai di next() sulla linea che leggi?


EDIT: l' ho provato e questo è quello che fa...

ho scritto
x
y
z

su un file, e un programma ke scrivesse sullo stesso file
x
y
z
a
b
c

Ho lanciato prima il programma di tail, che mi ha quindi stampato
x
y
z

dato che nel file erano gia presenti. Poi ho lanciato lo scrittore, che è andato a sovrascrivere il precedente file, tuttavia riscrivendo i primi 3 caratteri identici a quelli che c'erano prima.
Con mio grande stupore ho notato che il programma di tail però NON li ha ristampati, ha stampato solo i nuovi, quindi
x
y
z
a
b
c

mentre mi sarei per lo meno aspettato
x
y
z
x
y
z
a
b
c

Umm, sono un po' confuso...

EDIT2: il continue serve a non mandare il thread in wait finchè ho linee da processare, giusto?

Ultima modifica di tylerdurden83 : 01-08-2008 alle 21:42.
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 04-08-2008, 09:57   #5
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
mi sorge un dubbio, non è che rilegge il log dall'inizio?...
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 04-08-2008, 10:01   #6
ally
Bannato
 
L'Avatar di ally
 
Iscritto dal: Jan 2003
Città:
Messaggi: 4423
Quote:
Originariamente inviato da tylerdurden83 Guarda i messaggi
mi sorge un dubbio, non è che rilegge il log dall'inizio?...
...dal tuo post precedente si capisce il contrario...come giustamente dovrebbe comportarsi...cioè il programma scive solamente le nuove linee aggiunte al file di testo come un tail -f fa...

...ciao...
ally è offline   Rispondi citando il messaggio o parte di esso
Old 06-08-2008, 09:02   #7
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
Quote:
Originariamente inviato da ally Guarda i messaggi
...dal tuo post precedente si capisce il contrario...come giustamente dovrebbe comportarsi...cioè il programma scive solamente le nuove linee aggiunte al file di testo come un tail -f fa...

...ciao...
si lasciamo perdere pensavo di scrivere in append sul file di input...

anyway, ho una domanda:

Reader fileReader = new FileReader(log);
BufferedReader input = new BufferedReader(fileReader);
String line = null;

while (true) {
if ((line = input.readLine()) != null) {

se non ho capito male, il BufferedReader legge tutto il file di input, readLine ne legge riga per riga, sia quelle già presenti al lancio che quelle che si aggiungono successivamente, però alla fine input contiene una bufferizzazzione di tutto il log, anche quando, una volta letto tutto, resto in ascolto e quindi catturo solo le nuove righe.
In pratica, se il file di input è un log enorme, lo bufferizza, legge e lavora, ma quando si mette effettivamente in tail, non svuota il buffer con tutta la roba preesistente...
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 06-08-2008, 11:18   #8
incipit1970
Member
 
Iscritto dal: Mar 2007
Messaggi: 298
Quote:
Originariamente inviato da tylerdurden83 Guarda i messaggi
si lasciamo perdere pensavo di scrivere in append sul file di input...

anyway, ho una domanda:

Reader fileReader = new FileReader(log);
BufferedReader input = new BufferedReader(fileReader);
String line = null;

while (true) {
if ((line = input.readLine()) != null) {

se non ho capito male, il BufferedReader legge tutto il file di input, readLine ne legge riga per riga, sia quelle già presenti al lancio che quelle che si aggiungono successivamente, però alla fine input contiene una bufferizzazzione di tutto il log, anche quando, una volta letto tutto, resto in ascolto e quindi catturo solo le nuove righe.
In pratica, se il file di input è un log enorme, lo bufferizza, legge e lavora, ma quando si mette effettivamente in tail, non svuota il buffer con tutta la roba preesistente...
No, BufferedReader non bufferizza tutto il file, semplicemente usa un buffer intermedio per evitare di leggere dallo stream sottostante ad ogni richiesta. Puoi indicare le dimensioni del buffer nel costruttore del BufferedReader, e se non lo specifichi usa una dimensione fissa di 8Kb. Quindi puoi leggere un file di qualsiasi dimensione, il BufferedReader terrà in buffer solo gli ultimi 8kb letti.

Il codice di ally dovrebbe funzionare bene, l'unico dettaglio è che legge sempre tutto il file, mentre il tail -f apre il file "dalla fine", non scoda tutto il contenuto. Una variazione semplice che tenga questo di conto potrebbe essere:

Codice:
public class TailLogger {

	public static void main(String[] args) throws Exception {
		new TailLogger("C:/test.txt");
	}
	
	public TailLogger(String file) {
		try{
			FileInputStream fs = new FileInputStream(file);
			fs.skip(fs.available());
			Reader fileReader = new InputStreamReader(fs);
			BufferedReader input = new BufferedReader(fileReader);
			String line = null;
			while (true) {
				if ((line = input.readLine()) != null) {
					System.out.println(line);
					continue;
				}
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException x) {
					Thread.currentThread().interrupt();
					break;
				}
			}
			input.close();
		}catch(Exception e){
			System.out.println(e);
		}
	}
}
In pratica, si apre lo stream e si skippa tutto il contenuto del file prima di mettersi in tail sul file stesso. Altrimenti, se ti vai a mettere in coda su un file grosso, ti tocca prima leggerti tutto il contenuto. Questo è un problema se, invece di semplicemente stampare il contenuto del file, devi farci ad esempio dei conteggi o qualcosa del genere. Poi dipende del tipo specifico di uso che devi dare al codice, forse rileggere tutto il file dal inizio prima di metterti in coda ti serve proprio...
incipit1970 è offline   Rispondi citando il messaggio o parte di esso
Old 06-08-2008, 11:33   #9
ally
Bannato
 
L'Avatar di ally
 
Iscritto dal: Jan 2003
Città:
Messaggi: 4423
Quote:
Originariamente inviato da incipit1970 Guarda i messaggi

Il codice di ally dovrebbe funzionare bene, l'unico dettaglio è che legge sempre tutto il file, mentre il tail -f apre il file "dalla fine", non scoda tutto il contenuto. Una variazione semplice che tenga questo di conto potrebbe essere:
...si giustissimo...effettivamente il tail al massimo recupera le ultime 5 righe del file che si sta esaminando...

...ciao...
ally è offline   Rispondi citando il messaggio o parte di esso
Old 06-08-2008, 22:59   #10
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
Grazie di nuovo ad entrambi per i consigli!

La storia del leggere tutto il log, di per sè, direi che mi farebbe anche comodo, ti spiego da dove m'è sorto quel quesito però.

In pratica, lanciando il jar sotto windows, e dandogli in pasto un log di prova con una 30 di entry, vedo ke il processo occupa sui 17 mega di ram.

Mentre, lanciandolo sotto unix, e dandogli in pasto un log di migliaia di entry (log che comunque pesava max 10 mega), il processo inspiegabilmente occupa 623 mega! Tu mi dirai, se pure bufferizzasse tutto il log da 10 mega, come ci arriva a 600+? Non ne ho idea ad essere sincero, il jar è lo stesso, cambiano solo il log e l'SO...

Per quanto riguarda il mio primissimo quesito posto, cioè come si spostasse senza usare una funzione next(), solo ora ho trovato una spiegazione, le api potrebbero spiegare un pochino meglio cosa fa esattamente readline() invece di dire solo legge una riga...
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 07-08-2008, 09:21   #11
incipit1970
Member
 
Iscritto dal: Mar 2007
Messaggi: 298
Riguardo al next(), il reader non è un Iterator e dunque non c'è motivo per cui dovrebbe avere una funzione next(). Quasi tutte le API di I/O di Java usano degli stream, ed i Reader hanno dunque la logica di uno stream (leggi lo stream andando in avanti, quindi quando leggi una riga con readLine() il puntatore del file si sposta di conseguenza e la prossima lettura parte da dove è rimasta la precedente). E' poco ovvio ma quando ci hai fatto l'abitudine non ci pensi più.

Per quanto riguarda l'utilizzo di memoria, i fattori possono essere tanti, JVM diverse e diversa gestione della garbage collection e quant'altro. In ogni caso ti confermo che, nella jvm 1.5, il BufferedReader usa una cache di 8kb, ho verificato nella sorgente della libreria. Direi dunque che il problema sia che per ogni lettura che fai crei da qualche parte un oggetto String che contiene la riga letta. Prova a ridurre la quantità di memoria per la vm (opzione -xmx), metti una quantità piccola, 30M o giù di lì, e vedi come va.
incipit1970 è offline   Rispondi citando il messaggio o parte di esso
Old 08-08-2008, 18:12   #12
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
Allora, il comando per forzare il processo ad occupare max 30 mega è andato bene, anche se alla fine facendo TOP mi dice sui 34, comunque meglio di 600!

Mi sfugge ancora una cosa sugli stream. Metti che creo lo stream di un file, salta il contenuto pre-esistente e si mette in tail.

Se da shell faccio > nomelog.log, il programma rimane running ma non leggerà mai più da quel log...
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2008, 08:38   #13
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
UPDATE:

ragazzi, ho di nuovo bisogno del vostro aiuto.

Ho messo su l'applicazione. Avendo necessità di mettermi in tail su due log diversi ho fatto in modo di creare un thread per ogni log, che si mette in

while (true) {
if ((line = input.readLine()) != null) {

su di essi, così come mi avevate suggerito.
Ulteriore complicazione era la rotazione dei log una volta raggiunta una certa dimensione, per cui ho messo un controllo, se la dimensione precedente è > della corrente rigrea lo stream etc, e sta funzionando.

Il problema enorme è però che si perde qualche riga. Mi spiego, facendo dei controlli rispetto ai log originali, mettendo delle print su un nuovo log subito dopo la
if ((line = input.readLine()) != null) {
mi sono accorto che alcune righe non le ha proprio lette.

So che è difficile debuggare così, le sole cose che vi posso dire sono:
- le righe perse non sono la prima o l'ultima di un nuovo log dopo aver ruotato, ma al centro di log da cui ha letto la riga prima e quella dopo
- i thread non cadono, ho messo un controllo periodico (isAlive)
- il processo non sfora mai la memoria impostata dalla virtual machine come mi avete detto di fare. A parte che se non ho capito male dovrebbe lanciare un'eccezione qualora ciò avvenga, ad ogni modo non si è mai avvicinato manco lontanamente al max heap size memory impostato
- ovviamente il programma non genera nessuna eccezione, nè tantomeno cade mai

Ho deciso quindi di fare una prova di "stress" sulla mia macchina locale (windows, java 1.6 - mentre la macchina di lavoro è unix, java 1.5, sto compilando sulla mia con l'opzione -target 1.5). Ho pensato potesse essere un problema di troppe entry nello stesso istante nel log su cui sono in tail, così ho scritto un'applicazioncina che mi spara sui due log 2 righe, il tutto in un ciclo for i=0 i<15.000, in 3-4 secondi spara 15.000 righe per log, eppure non ne ha persa manco una.

Non so più che pensare, nè che prove fare. L'unica cosa che non ho provato ancora tra le 1000 che ho provato è sostituire
if ((line = input.readLine()) != null)
con
if (bufferedReader.ready()==true) {
line = input.readLine();

Grazie 1000 a tutti per l'aiuto,
TD
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2008, 17:13   #14
tylerdurden83
Senior Member
 
Iscritto dal: Nov 2004
Messaggi: 691
Boh, ho fatto altre prove...

Ho messo il jar in ascolto su un log mio usato per i test, vuoto.

Ho provato, sul server unix, a sparare con un altro jar 15000 righe una alla volta, e non ha dato problemi.
Ho provato a spararle 500 alla volta, cioè creando una stringa che concat("\n") e concat(riga successiva), quindi in una sola write sul log di test ho scritto 500 righe, anche in questo caso nessun problema....

Non ho proprio più idea di dove andare a parare....fin'ora in ogni test non ha mai perso una sola riga, anche se i test sono stati molto più "stressanti" rispetto ai log su cui sta in tail normalmente, eppure pare perdere dati solo da quelli....
tylerdurden83 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader Tascabile e con Android: BOOX Go 6 Gen II &egrav...
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro Recensione Lenovo Idea Tab Plus: il tablet da 12...
Oltre il contante e le crypto: tutto sull'Euro Digitale e la nuova sovranità monetaria europea Oltre il contante e le crypto: tutto sull'Euro D...
Recensione HONOR Magic V6: spessore record e super batteria. È lui il fold da battere? Recensione HONOR Magic V6: spessore record e sup...
Redmi Pad 2 9.7: ampio display, economico e peso contenuto, ma qualche limite nelle prestazioni Redmi Pad 2 9.7: ampio display, economico e peso...
Piccolo è bello: Cisco presenta A...
Z.AI avvia un data center da 1 gigawatt....
Microsoft e Mistral annunciano un accord...
Grazie al Very Large Telescope potrebbe ...
Sony FX5: RAW interno X-OCN e Open Gate ...
AMD e Anthropic, affare fatto: 5 miliard...
Cyber Arena Tour 2026, WINDTRE BUSINESS ...
Wistron ha aperto il primo stabilimento ...
"Così è facile perder...
Peak Design ripensa la staffa a L: il tr...
Samsung: ufficiale la serie Galaxy Z Fol...
Galaxy Watch Ultra2 e Watch9 ufficiali: ...
Un razzo spaziale Falcon 9 ha lanciato l...
Microlino: dal rischio di fallimento all...
SpaceX, uno stadio di Falcon 9 si schian...
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:02.


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