IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

I/0 Streams

Un I/O Stream o fluxe d'entrada/sortida representa un origen de dades i una destinació de dades qualsevol. Un Stream pot representar diferents tipus d'origens i/o destinacions:

Fitxers o disk files
Dispositius de hardware devices i/o perifèrics
Altres programes
Memory arrays
network sockets
...

Els streams de java suporten diferents tipus de dades des de bytes, a tipus de daes primitius (enters, booleans, etc), caracters localitzats, objectes...

Els streams simplement mouen les dades, la manipulació de les mateixes la fan tercers, no els propis streams.

No importa com funcionin els streams internament, tots representen el mateix model:

Un stream és una seqüència ordenada de dades, Els programes utilitzen streams d'entrada per llegir dades d'una font o streams de sortida per enviar dades a una destinació.

Recursos:

InputStream i OutputStream

Són les classes abstractes en la que es basen tots els tipus d'Streams en Java.

Byte Streams

Els Byte Streams o fluxos de bytes són el tipus d'streams o fluxes més basics. Cal tenir en compte que el byte (més que el bit) és la unitat típica mínima d'opetacions d'entrada/sortida (I/O).

Els programes Java utilitzen byte streams per realitzar operacions d'entrada sortida en unitats de 8 bits = 1 byte. Totes les clases d'aquest tipus són filles de les clases InputStream i OutputStream.

Hi ha múliples tipus de classes byte stream, algunes s'expliquen als següents apartats. Cal tenir en compte que totes funcionaran de forma similar, l'únic que canviarà serà la creació del Stream.

FileInputStream i FileOutputStream

Els fitxers es poden llegir i escriure utilitzant les clases FileInputStream i FileOutputStream

Vegem un exemple:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyBytes {
    public static void main(String[] args) throws IOException {

        FileInputStream in = null;
        FileOutputStream out = null;

        try {
            in = new FileInputStream("in.txt");
            out = new FileOutputStream("out.txt");
            int c;

            while ((c = in.read()) != -1) {
                out.write(c);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

Aquest exemple el que fa és agafar un fitxer d'entrada (in.txt) i copia tot el seu contingut a out.txt.

El més important és el tros de codi:

while ((c = in.read()) != -1) {
               out.write(c);
           }

On anem llegint byte a byte el fitxer original, segons es pot veure a la gràfica següent:

TODO: http://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html

http://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html

NOTA: El fitxer ha d'estar a la mateixa carpeta on s'executa el programa i s'ha de dir exactament igual. podeu indicar un path complet, però OCO! la forma en que s'especifiquen paths depèn del sistema operatiu i pot fer que la vostra aplicació deixi de ser multiplataforma

Observeu el tros de codi:

IMPORTANT: Sempre cal tancar els streams per alliberar recursos. Fixeu-vos l'ús del bloc finally per assegurar-se que el stream es tanqui inclús en cas d'errors. Aquesta tècnica permet eviar els resource leaks o especificament els memory leaks

Cal tenir en compte que els Byte Streams no són la forma més eficient de treballar amb dades I/O, ja que estem treballant a un nivell molt baix de sistema, és a dir de la forma més primitiva possible. Per exemple per a un fitxer podria ser més interesant treballar amb streams de caràcters.

NOTA: Que no sigui la forma més eficient no vol dir que no valgui la penda entendre com funciona, ja que tota la resta d'Streams es basen en Streams de bytes

Android

Vegeu Android i fitxers de l'article Android Storage.

Character Streams. Reader i Writer

Reader i Writer, les classes pare de qualsevol stream basat en caràcters.

FileReader i FileWriter

Java utilitza Unicode per emmagatzemar caràcters. Els streams de caràcters automàticament tradueixen el fotmat intern d'un strema al format local (depenent del joc de caràcters local). Els Western locales (prvis a unicode) acosutem a ser variants de ASCII de 8 bits

La majoria d'aplicacions no són més complexes si utilitzen Caràcters en comtpes de bytes, però això depèn del nivell d'importància de la Internacionalització i Localització de l'aplicació.

NOTA: Si la internacionalització no és una prioritat, simplement es poden utilitzar els streams de caràcters sense parar massar atenció en els tipus de caràcters

Les classes bàsiques són FileReader i FileWriter, filles de Reader i Writer, les classes pare de qualsevol stream basat en caràcters.

IMPORTANT: Tots els streams de caràcters són fills de les classes Reader i Writer. Igual que amb els byte streams hi ha unes classes especialitzades en fitxers: FileReader i FileWriter

java.io.FileReader
java.io.FileWriter

Els streams de caràcters són sovint "wrappers" d'streams de bytes. El stream de caràcters utilitza un stream de bytes per a realitzar operacions físiques de I/O, mentres que els streams de caràcters controlen les traduccions entre caràcters y bytes.

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyCharacters {
    public static void main(String[] args) throws IOException {

        FileReader inputStream = null;
        FileWriter outputStream = null;

        try {
            inputStream = new FileReader("xanadu.txt");
            outputStream = new FileWriter("characteroutput.txt");

            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

L'exemple CopyCharacters és molt similar a CopyBytes. L'única diferencia és en els objectes:

FileInputStream -> FileReader
FileOutputStream -> FileWriter

Cal tenir en compte que tots treballen amb ints, però de diferent mida!

CopyCharacters -> 16 bits
CopyBytes -> 8 bits

TODO:

There are two general-purpose byte-to-character "bridge" streams: InputStreamReader and OutputStreamWriter. Use them to create character streams when there 
are no prepackaged character stream classes that meet your needs. The sockets lesson in the networking trail shows how to create character streams from the byte 
streams provided by socket classes.
Line-Oriented I/O

El procesament de caràcters sovint es fa en unitats de dades més grans que simples caràcters. un cas típic és operar a nivell de línies. La definició de línia és:

Un string de caràcters amb un terminador de línia al final.

IMPORTANT: Compte que el terminador de línia no és igua len totes les plataformes: ("\r\n"),("\r"), ("\n"). Java suporta tots els tipus

Vegem ara un exemple de copia per línies utilitzant:

BufferedReader i PrintWriter
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;

public class CopyLines {
    public static void main(String[] args) throws IOException {

        BufferedReader inputStream = null;
        PrintWriter outputStream = null;

        try {
            inputStream = new BufferedReader(new FileReader("xanadu.txt"));
            outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));

            String l;
            while ((l = inputStream.readLine()) != null) {
                outputStream.println(l);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

L'ús del mètode readLine retorna una línia de text. Per a mostrar les línies per sortida utlitzen println que s'encarrega d'afegir el terminador de línia al final.

Recursos:

Scanning and Formatting

TODO
Clase Scanner


Object streams

Vegeu també Serialització.

ObjectInputstream

ObjectOutputstream

Exemples

Exemples amb Android:

Android_sockets#Com_utilitzar_un_objecte_per_controlar_les_acciones_que_es_duen_a_terme

Vegeu també

Enllaços externs