Anteprima
Vedrai una selezione di 3 pagine su 9
Appunti sull'input/output in Java Pag. 1 Appunti sull'input/output in Java Pag. 2
Anteprima di 3 pagg. su 9.
Scarica il documento per vederlo tutto.
Appunti sull'input/output in Java Pag. 6
1 su 9
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

FileOutputStream outputStream = new

FileOutputStream(“output.dat”);

In entrambi i casi si utilizza il metodo int read() che legge un

carattere / byte per volta e restituisce un valore di tipo int. Tale

valore corrisponde al codice del carattere / byte letto oppure –1

se non ci sono più dati da leggere.

C'è questa distinzione tra percorso relativo e assoluto perchè

· dobbiamo sepre pensare che il software quando va in esecuzione

ha un contesto, il contesto sostanzialmente sarebbe un'area di

lavoro in cui il software sta già operando, quindi se vado a scrive

un'applicativo Java che legge da un file e salvo il mio file.java in

una cartella X, allora compilo il sorgent e se non cambiamo nulla

la compilazione fa si che dentro la cartella stesssa trovo anche

il .class, se quindi faccio tutto nel main abbiamo solo il sorgente

e il .class corrispettivo. Se invece voglio dire al software di

anadare a leggere il file, il percorso assoluto funziona sempre

poichè infatti va nel file system che p una componente del

sistema operativo, il sistema operativo gestisce infatti il file

systema che è un suo compoente, il file systema ha delle

primitive del tipo "apri una certa cartella", "crea questo file" etc...

e quindi può accedere al percordo assoluto indicato, il file system

traduce il percordo dato e ci conduce alla cartella esatta.

Potrei quindi pensare di dare sempre il percorso completo così da

non avere problemi, questo è però sbagliato perchè se nel codice

vado a scrivere il percorso assoluto, ad esempio posso dichiarare

una costante che pongo uguale al percorso, passo quindi il nome

del file come se fosse una costante e dò il percorso assoluto,

però così quando distribuisco il mio file, nel momento in cui

passo un programma a un'altra persona il file non verrebbe

trovato, potrei anche pensare di creare lo stesso percorso,

rimane il fatto che la parte C:\users\nomeutente\ è gestita dal

sistema operativo, in realtà potrebbe anche chi riceve il file

creare la cartella \nomeutente\ ma ha poco senso ma

soprattutto, almeno per windows, la prima parte è differente,

quindi in generale l'idea è che il percorso assoluto ha senso

soloper la macchina per cui è stato scritto.

ciò che è da fare in questo caso è ragionare con i percorsi relativi

o pattern relativi. Un percorso relativo è un percorso che esprime

la posizione di una risorsa, quindi di un file, rispetto alla

posizione da cui stiamo osservando, quindi se sto scrivendo un

software e lo posiziono nella cartella X, quando il mio software

andrà in esecuzione il suo contesto è la cartella X, che è la

cartella in cui il software vive e che vede direttamente, quindi in

questa cartella se creo un file di nome writer.java, per lui la sua

posizione relativa è la cartella X, quindi se all'interno del file .java

vado a specificare il nome del file prova.txt lui lo vede perchè è

nella sua stessa posizione relativa, qiundi il percorso relativo del

file prova.txt rispetto al chiamante che sarà il writer.java è

identico, quindi basta solo il nome del file.

Immaginiamo ora che nella cartella X ci sia una cartella che si

chiama media e all'interno di media ci sia il nuovo file nuovo.txt,

immaginiamo ora che il writer voglia leggere il file nuovo.txt, a

questo punto il nuovo nome diventerà ./media/nuovo.txt, questo

è il percorso relativo da writer.java alla risorsa che è nuovo.txt,

possiao inoltre dire che nell'ultimo percorso indicato il punto

iniziale è un simbolo che indica di partire dalla cartella attuale a

cui si trova, in realtà lo si può scrivere anche media/nuovo.txt,

funziona comunque.

Immaginiamo ora che il file nuovo.txt si trovi in una cartella

esterna a X, ad esempio immaginiamo che ci sia una cartella Y

che contiene la cartella X e il file nuovo.txt, in questo caso

abbiamo lo stesso ragionamento solo che invece di andare in

avanti verso media devo tornare indietro, per tornare indietro

scrivo ../nuovo.txt

Torniamo ora alla situazione in cui nuovo.txt è interno alla

cartella media, ora se viene condiviso il progetto e viene

condivisa la cartella X, ora senza modificare nulla il software

funziona anche sul dispositivi con cui è stata condivisa la cartella

perchè non è stato indicato il percorso assoluto. Questo è il

vantaggio dei percorsi relativi.

Se la risorsa a cui accediamo non sta all'interno del file syste

quindi è qualcosa di remoto allora non c'è altre possibilità oltre a

mettere il percorso assoluto, lì c'è il concetto di resource

identifier che è il percorso assoluto ma è assoluto rispetto a un

over the top.

quando puntiamo a una risorsa web esterna, quindi passiamo un

percorso esterno, c'è sempre un entità, nel caso di internet è un

DNS, che risolvono quel percorso assoluto e lo rendono

interpretabile a livello più universale.

I file di configurazione servono se voglio mantenere un percorso

assoluto, questo non verrà scritto hard coded sul mio software

perchè so che poi perderei la portabilità ma vado ad aggiungere

dettagli sul file, quindi magari mi segno un percorso relativo e

tutti i percorsi assoluti li scarico su un file di testo che uso come

file di configurazione.

In ambito web le cosw diventano più complesse perchè quando

eseguiamo un'applicazione stand lone, cioè sulla nostra

macchina, in qualche modo siamo all'interno di un'ambiente ben

definito

Il vantaggio dei buffer è che faccio meno letture

· Un BufferedReader permette di gestire un flusso tramite un

· buffer:

I dati vengono letti a blocchi dal flusso e memorizzati in un

· buffer (area di memoria).

Quando viene richiesto un nuovo dato prima si verifica la

· suadisponibilità nel buffer e, se non disponibile in memoria,

si legge un nuovo blocco.

Mette a disposizione il metodo readLine()il quale legge una riga e

la restituisce sotto forma di stringa

Per associare un file ad un BufferedReader:

· FileReader file = new FileReader(“nome-file”);

BufferedReader in = new BufferedReader(file);

BufferedReader in = new BufferedReader(new FileReader(“nome-

· file”));

Per leggere da un BufferedReader: in.readLine();

· La chiusura del bufferedReader automaticamente chiude il

· FileReader da cui sta leggendo

La classe PrintWriter mette a disposizione i metodi void print() e

· void println() utilizzabili con qualunque tipo di parametro

(stringa, intero, reale, ecc.).

Si può creare un nuovo oggetto PrintWriter a partire da un Writer,

· in particolare da un FileWriter. PrintWriter f = new PrintWriter

(new FileWriter(“nome-file”) );

CSV:

· In un generico testo non c'è alcuna corrispondenza tra quello che

c'è scritto nelle righe nemmeno a livello strutturale, infatti

possono esserci lettere, numeri etc..., l'informazione ha senso se

viene strutturata, infatti nel mondo dei basi di dati si creano le

tabelle. Il prelievo dei dati è difficile se l'informazione è inserita in

maniera no strutturata. Qaundo abbiamo a che fare con file di

testo la struttura o semistruttura la si può stabilire usando dei

caratteri di separazione. Il CSV è un file in cui abbiamo qualcosa

di questo tipo:

matricola, nome, cognome, data

1010, Antonio, Blue, 1-2-1

2015, Michi, Verdi, 1-1-1

la prima riga si chiama header e può essere omessa purchè

abbia lo stesso numero di virgole di quello che ci sta sotto.

La struttura viene fuori dal fatto che quando lo salvo con

estensione CSV, se vado a leggerlo ome se fosse un CSV, la

prima cosa che il mio porgramma fa è chiedermi se il file ha un

header, se così fosse allora della prima riga conta solo le virgole

e la scarta, poi comincia a leggere i file, capisce che il primo dato

è un intero, poi c'è una virgola, poi una stringa, poi una virgola e

così via, vede se in ogni riga il numero di virgole coincide con

quelle del header e se così fosse allora è conforme, se c'è

un'anomalia il file diventa non leggibile..

Comma-separated è uno standard così definito, tuttavia il fatto

della comma non è una regola fissa, infatti possiamo usare ad

esempio il punto-e-virgola per dividere i caratteri, oppure gli

spazi o i tab, l'importante è che il separatore, una volta scelto,

sia asottato su tutte le righe.

Ora, se immaginassi di voler prendere la matricola in tutte le

righe, vado a prendere il primo elemento della riga prima che ci

sia il primo separatore, devo quindi prendere la riga e scomporla

sulla base del separatore, si parla di tokenization

La classe StringTokenizer e’ definita nel package java.util. Un

· oggetto StringTokenizer separa una stringa in sottostringhe dette

token. Per default, il tokenizer separa la stringa ad ogni spazio. Il

costruttore StringTokenizer richiede come parametro la stringa

da separare. Ciascuna chiamata al metodo nextToken()restituisce

il token successivo.

String.split Serve per dividere una stringa sulla base di un regex

· e non un separatore. Un regex è una regular expression che i

rappresenta una stringa tipica, un modello di stringa che ci

permette di identificare una particolare caratteristica di una

stringa

StringBuilder Esso è pensato come una sequenza mutabile di

· caratteri, quindi una sequenza in cui possiamo fare qualsiasi

modifica e senza avere il problema di ricreare l'oggetto. Quando

si legge dal file avremo sempre la situazione in cui leggiamo da

file e creiamo una stringa con quello che abbiamo letto, quindi

faremo tante operazioni di append sulla stringa, se usiamo la

concatenazione di stringhe normale ha un costo, se usiamo lo

stiringBuilder che ha il metodo appenda risparmiamo molto

tempo a livello di costo computazionale, risparmiamo quindi

risorse

StringBuilder e StringBuffer sono identici con gli stessi metodi,

· c'è però la solita differenza nel caso in cui la risorsa, quindi la

stringa fosse condivisa tra più processi, se quella stringa può

essere manipolata da due sottoprocessi del programma che

scrivono su stringBuilder, allora usare StrigBuilder è pericoloso

perchè esso non è sincronizzato, cioè non e pronto a gestire

conflitti tra tread diversi che accedono contemporaneamente. Il

funzionamento è duale a ciò che fa il sistema operativo

Dettagli
Publisher
A.A. 2023-2024
9 pagine
SSD Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher ab502 di informazioni apprese con la frequenza delle lezioni di Programmazione a oggetti e ingegneria del software e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Pavia o del prof Antonino Nocera.