Diferență între revizuiri ale paginii „Input/Output Streams”

De la WikiLabs
Jump to navigationJump to search
 
(Nu s-au afișat 2 versiuni intermediare efectuate de același utilizator)
Linia 82: Linia 82:
 
By using class '''ByteArrayInputStream''', you can read data from an array using stream reading methods, without having to manually manage the current read index in the array. The connection is easily done by giving the existing array as an argument to the stream constructor. The example above creates a 10 bytes array, filling it with value from 0 to 9 and then creating a ByteArrayInputStream and using it to sequentially read the data, byte by byte and displaying it on the screen. You can also see that the reading is only done until the ''read()'' method returns -1, signaling the end of the stream, thus the end of the array.
 
By using class '''ByteArrayInputStream''', you can read data from an array using stream reading methods, without having to manually manage the current read index in the array. The connection is easily done by giving the existing array as an argument to the stream constructor. The example above creates a 10 bytes array, filling it with value from 0 to 9 and then creating a ByteArrayInputStream and using it to sequentially read the data, byte by byte and displaying it on the screen. You can also see that the reading is only done until the ''read()'' method returns -1, signaling the end of the stream, thus the end of the array.
  
=== Fluxuri de ieșire orientate pe octet ===
+
=== Byte Output Streams ===
  
[[Fișier:outputstream.png|Reprezentare grafică a unui OutputStream generic și a unui FileOutputStream]]
+
[[Fișier:outputstream.png|Graphical representation of a generic OutputStream and a FileOutputStream]]
 +
 
 +
For writing data using streams, a class hierarchy is used, derived from class [http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html java.io.OutputStream]]. Just like '''InputStream''', class '''OutputStream''' is abstract, offering an interface for declaring generic write methods. The class has the following definition:
  
Pentru scrierea datelor folosind conceptul de flux orientat pe octet, se folosește o ierarhie de clase derivată din clasa '''OutputStream'''. Ca și clasa '''InputStream''', clasa [http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html OutputStream] este o clasa abstractă, oferind o interfață de declarare a unor metode de scriere general valabile. Clasa are următoarea definiție:
 
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
 
public abstract class OutputStream{
 
public abstract class OutputStream{
Linia 97: Linia 98:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Funcţia ''write()'' scrie în flux octetul cel mai puțin semnficativ al argumentului, care este de tip '''int'''. Celelalte funcții permit scrierea în flux a unui tablou de octeți sau a unei secțiuni din tabloul de octeți ''b'' începând de la poziția ''off'' și având lungimea ''len''.  
+
Method ''write()'' writes the lest significant bytes of the argument, which is of type '''int''' to the stream. The other methods write the contents of a byte array ''b'' or a section of it, starting from position ''off'' and having a length of ''len''.
  
Funcția ''flush()'' forțează scriea datelor în stream și este utilă în cazul în care se folosește un buffer de scriere (golește buffer-ul).  
+
Method ''flush()'' forces writing data to the stream, and it is useful when a write buffer is used.
  
Funcția ''close()'' închide fluxul deschis prin operația de creare a fluxului, eliberând astfel orice resursă de sistem ocupată de fluxul respectiv.
+
Method ''close()'' closes the stream and frees and resource associated with it.
  
Ca și în cazul clasei ''InputStream'', clasele derivate din ''OutputStream'' pot fi separate în două categorii: fluxuri propriu-zise ([http://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html ByteArrayOutputStream], [http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html FileOutputStream], etc) care se conectează la o destinație, și fluxuri de tip filtru (derivate din [http://docs.oracle.com/javase/7/docs/api/java/io/FilterOutputStream.html FilterOutputStream]). Ultimele tipuri de fluxuri se conectează la primele, îmbogățind funcționarea acestora.
+
Just like ''InputStream'', classes derived from ''OutputStream'' can be split in two categories: data streams ([http://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html ByteArrayOutputStream], [http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html FileOutputStream], etc.) which connect to a destination, and filter streams (derived from [http://docs.oracle.com/javase/7/docs/api/java/io/FilterOutputStream.html FilterOutputStream]) which are wrappers over the first ones, enhancing their functionality.
  
Fluxurile standard de ieșire ('''System.out''') și de eroare ('''System.err''') sunt membri statici ai clasei '''System''' de tipul [http://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html PrintStream], care extinde clasa '''FilterOutputStream'''. Acestea sunt conectate cu display-ul și se folosesc prin convenție în două situații distincte: primul pentru afișarea mesajelor către utilizatorul programului, şi al doilea pentru afișarea mesajelor de eroare (de cele mai multe ori în scop de depanare).
+
Standard output stream ('''System.out''') and standard error streams ('''System.err''') are static fields of class '''System''', of type [http://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html PrintStream], which extends class '''FilterOutputStream'''. These are connected to the display and by conventions are used in two distinct situations: first to display messages for the program user, and the second, to display error messages (usually for debugging purposes).
  
În continuare este prezentat un exemplu de utilizare a clasei '''ByteArrayOutputStream''', prin care se afișează toate valorile pe 8 biţi:
+
Next, let's see an example of using a '''ByteArrayOutputStream''', used to display all 8-bits values:
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
 
ByteArrayOutputStream _buffer = new ByteArrayOutputStream(256);
 
ByteArrayOutputStream _buffer = new ByteArrayOutputStream(256);
Linia 121: Linia 122:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Clasa '''ByteArrayOutputStream''' este clasa corespondentă clasei '''ByteArrayInputStream''' și permite conectarea unui flux la un buffer (un tablou de octeți). Buffer-ul se crează în momentul în care un obiect de tipul '''ByteArrayOutputStream''' se instanțiază folosind unul dintre cei doi constructori. Această clasă oferă o metodă de stocare a datelor în memorie înainte de a le trimite mai departe. Pentru transmiterea datelor se folosește metoda ''writeTo()''. Această funcție scrie conținutul buffer-ului în fluxul ''out'' transmis ca parametru. Spre deosebire de clasa '''ByteArrayInputStream''' unde tabloul (buffer-ul) era transmis prin constructorul clasei, în cazul clasei '''ByteArrayOutputStream''', pentru a avea o referintă la acest buffer, este nevoie să se apeleze funcția ''toByteArray()''. Această funcție creează un tablou de dimensiune egală cu numărul de octeți înscriși în flux și care conține acești octeți.
+
Class '''ByteArrayOutputStream''' corresponds to '''ByteArrayInputStream''' and allows the connection of a stream to a buffer (a byte array). The buffer is created when an object of type '''ByteArrayOutputStream''' is instantiated by using one of the two constructors. This class offers a method of storing data in memory before processing or sending them somewhere else. In order to transmit data, method ''writeTo()'' is used.
 +
In the example above, the buffer is written to the ''out'' stream, passed as a parameter. Opposite to class '''ByteArrayInputStream''', where the buffer was passed as an argument to the constructor, in the case of
 +
'''ByteArrayOutputStream''', in order to obtain a reference to the buffer, a call to ''toByteArray()'' is required. This method returns a copy of the buffer.
 +
 
 +
== Character Input/Output Streams ==
  
== Fluxuri de intrare-ieșire la nivel de caracter ==
+
Classes for character streams are extended from class [http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html java.io.Reader] for reading data and http://docs.oracle.com/javase/7/docs/api/java/io/Writer.html java.io.Writer] for writing data. Most of these classes overlap with byte stream classes, having the same functionality. The difference between them is that '''InputStream/OutputStream''' classes work (read/ write) with bytes (8 bits), as '''Reader/Writer''' work with characters represented in the [http://en.wikipedia.org/wiki/Unicode Unicode] standard, on 16 bits.
  
Clasele pentru fluxurile la nivel de caracter au la bază clasa '''Reader''' pentru citirea datelor și clasa '''Writer''' pentru scrierea datelor. Majoritatea acestor clase se suprapun peste clasele pentru fluxurile la nivel de octet, oferind în principal aceleași funcționalități. Deosebirea între clasele de tip '''InputStream/OutputStream''' și cele de tip '''Reader/Writer''' este aceea că primele clase lucrează cu fluxuri de octeți (8 biți), în timp ce ultimele lucrează cu fluxuri de caractere reprezentate pe 16 biți în format [http://en.wikipedia.org/wiki/Unicode Unicode] (standard internațional de codare a caracterelor care este capabil să reprezinte caracterele tuturor limbilor scrie).
+
The corespondence between bytes streams and character streams are as follow:
  
Cu toate că noile clase '''Reader/Writer''' dublează clasele '''InputStream/OutputStream''', acestea din urmă nu au fost abandonate, datorită în principal cerinței de compatibilitate cu aplicațiile dezvoltate într-o versiune mai veche de Java. Totuși, există unele metode din vechile clase care se recomandă a nu a mai fi folosite, fiind caracterizare ca depășite (''deprecated''). Funcțiile oferite de clasele '''InputStream/OutputStream''' se regăsesc în clasele '''Reader/Writer''' cu mici deosebiri, acest lucru reflectându-se și în denumirile asemănătoare ale celor două tipuri de clase de tip flux, prefixele fiind aceleași.
+
In case of input streams:
În cazul claselor de citire a datelor se pot observa următoarele corespondențe:
 
 
* '''InputStream''' - [http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html Reader]
 
* '''InputStream''' - [http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html Reader]
 
* '''ByteArrayInputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/CharArrayReader.html CharArrayReader]
 
* '''ByteArrayInputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/CharArrayReader.html CharArrayReader]
 
* '''StringBufferInputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/StringReader.html StringReader]
 
* '''StringBufferInputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/StringReader.html StringReader]
 
* '''FileInputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html FileReader]
 
* '''FileInputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html FileReader]
* Există unele clase, '''SequenceInputStream''', și '''DataInputStream''' care nu au o versiune de tip '''Reader'''.
+
* There are classes, like '''SequenceInputStream''' and '''DataInputStream''' that don't have a '''Reader''' version.
  
În cazul claselor pentru scriere, se pot observa următoarele corespondențe:
+
In case of output streams:
 
* '''OutputStream''' - [http://docs.oracle.com/javase/7/docs/api/java/io/Writer.html Writer]
 
* '''OutputStream''' - [http://docs.oracle.com/javase/7/docs/api/java/io/Writer.html Writer]
 
* '''ByteArrayOutputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/CharArrayWriter.html CharArrayWriter]
 
* '''ByteArrayOutputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/CharArrayWriter.html CharArrayWriter]
 
* '''FileOutputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html FileWriter]
 
* '''FileOutputStream''' – [http://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html FileWriter]

Versiunea curentă din 15 decembrie 2013 11:59

A computer communicates with the exterior world through one or more communication interfaces, also called input-output (IO) ports. E.g.: serial port, parallel port, video port, audio port, etc. By using these interfaces, the computer is able to transmit and receive information to and from the outside world through different peripheral devices (monitor, printer, keyboard, mouse, modem, Ethernet card, etc.).

Input/Output Streams

Considering the large number of peripheral types, the constant development of new ones and also the fact that existing peripherals are being constantly upgraded, direct communication between them and the software programs would be difficult to achieve if it were to only use the processor instructions (in/out). Furthermore, the complexity of the communication with the peripheral devices gets even higher with different types of communication: sequential/ random, binary/ character/ line by line, etc. In order to help with these problems, device drivers were developed, which are software modules used to control the peripherals and provide a simpler communication interface, however, they don't completely solve the compatibility issues of the IO operations. As a result, the operating system also introduces a layer of abstraction, offering a more uniform way of transferring data to and from the peripheral devices. However, programming languages, like Java, are created so that can be used in several operating systems and so additional standard functions are required, defined in the programming language libraries, to communicate with devices, independently of the operating system.

In order to treat communication uniformly, Java uses the concept of stream. The notion has been invented by Dennis Ritchie, who implemented the first IO system based on streams, in the Unix operating system, in year 1984. A stream implies the creation of a communication channel, generally valid, between two entities, either software or hardware, with the condition that one entity is a source, and the other is a destination. So, the source will transmit (write) information in the stream, and the destination will receive (read) from the stream. This way, the stream allows treating any communication channel between any entities in the system in the same way. Defining a stream is done by defining its two ends (source and destination). Because there are two communication directions, we can separate streams into two categories: input streams and output streams. Input streams are streams that connect to devices that provides data (like keyboards) and output streams connect to devices that receive data (like the monitor). Both source and destination can be either a peripheral device or software component.

Console Streams

The Java language provides three types of standard streams for communicating with the console:

  • standard input stream - type InputStream, used to read data;
  • standard output stream - type PrintStream, used to display data;
  • standard error stream - type PrintStream, used to display errors.

In Java, all standard streams are accessible through class java.lang.System. So, for standard input, there is System.in, for standard output there is System.out and for standard error, there is System.err. The three members in, out and err of class System are static.

Classes that implement IO operations are placed in package java.io. This package contains two categories of streams: bytes streams and character streams. Byte streams have been introduced from JDK version 1.0.2 and character streams are available since JDK 1.1. The latter ones do not replace, but complete stream functionality by being able to directly read and write characters (which in Java have 2 bytes each).

Byte Input/Output Streams

Bytes streams (as character streams) are split in two categories: input streams and output streams.

=== Bytes Input Streams

Graphical representation of a generic InputStream and a FileInputStream

Classes implementing byte input streams are extended from java.io.InputStream, an abstract class which offers generic read methods. The definition of the class is:

public abstract class InputStream{
    public abstract int read() throws IOException;
    public int read(byte b[]) throws IOException;
    public int read(byte b[], int off, int len) throws IOException;
    public long skip(long n) throws IOException;
    public int available() throws IOException;
    public void close() throws IOException;
    public synchronized void mark(int readlimit);
    public synchronized void reset() throws IOException;
    public boolean markSupported();
}

Method read(), with no arguments, reads the next byte from the stream and return it as an int with values between 0 and 255. If the end of stream has been reached, it returns -1.

Methods read(), having as arguments an array of bytes, read a number of len or the length of the array b (whichever is smaller) of bytes from the stream and write them in array b at index off, if this is specified. They return the number of bytes read from the stream (and subsequently written in b) or -1 if the end of stream has been reached.

Method skip() is used to discard a number of bytes from the input stream, specified in argument n.

Methods mark() and reset() are used together, so that portions of the stream that have been already read can be read again. Through method mark(), the current position in the stream is memorized, specifying the maximum size of the buffer that will store the following data through the argument readLimit that can be written before calling reset(). The reset() method re-position the read index to the position where it was when the mark() method was called. These two methods are only valid if the stream supports marking. Checking for this is done by calling method markSupported().

Method available() returns the number of bytes available to be read from the stream without blocking execution. Be aware that some classes (like file streams) only return an estimate value when calling available(). Check the documentation.

Method close() is used to close a stream. Once work with a stream is done, it needs to be closed in order to free the associated resources. Normally, JVM will automatically close all streams then the program ends, but a programmer should not count on this feature and clean up after him/herself.

In order to use class InputStream in applications, it needs to be extended by classes that are connected to real data sources, existing in the system. Some of these classes, defined in Java, are:

Another category of classes derived from InputStream, this time though not directly, are filter classes, derived from FilterInputStream which is, in its turn, derived from InputStream. These types of classes do not offer support for any additional data sources but instead they work as a wrapper over exiting input streams, providing additional functionality. Examples of such classes are:

  • DataInputStream is one of the most used filter classes. In contains several methods that can read primitive data types (int, float, etc.), in a system independent way.
  • PushbackInputStream offers the possibility of rewind and read data that has already been read.

Next, an example of using class ByteArrayInputStream:

byte _buffer[] = new byte[10];
for(byte i = 0; i < _buffer.length; i++){
    _buffer[i] = i;
}

ByteArrayInputStream _bufferStream = new ByteArrayInputStream(_buffer);
int _byteRead;
while((_byteRead = _bufferStream.read()) != -1){
    System.out.print(  + _byteRead);
}
System.out.println();

By using class ByteArrayInputStream, you can read data from an array using stream reading methods, without having to manually manage the current read index in the array. The connection is easily done by giving the existing array as an argument to the stream constructor. The example above creates a 10 bytes array, filling it with value from 0 to 9 and then creating a ByteArrayInputStream and using it to sequentially read the data, byte by byte and displaying it on the screen. You can also see that the reading is only done until the read() method returns -1, signaling the end of the stream, thus the end of the array.

Byte Output Streams

Graphical representation of a generic OutputStream and a FileOutputStream

For writing data using streams, a class hierarchy is used, derived from class java.io.OutputStream]. Just like InputStream, class OutputStream is abstract, offering an interface for declaring generic write methods. The class has the following definition:

public abstract class OutputStream{
    public abstract void write(int i) throws IOException;
    public void write (byte b[]) throws IOException;
    public void write (byte b[], int off, int len) throws IOException;
    public long flush() throws IOException;
    public void close() throws IOException;
}

Method write() writes the lest significant bytes of the argument, which is of type int to the stream. The other methods write the contents of a byte array b or a section of it, starting from position off and having a length of len.

Method flush() forces writing data to the stream, and it is useful when a write buffer is used.

Method close() closes the stream and frees and resource associated with it.

Just like InputStream, classes derived from OutputStream can be split in two categories: data streams (ByteArrayOutputStream, FileOutputStream, etc.) which connect to a destination, and filter streams (derived from FilterOutputStream) which are wrappers over the first ones, enhancing their functionality.

Standard output stream (System.out) and standard error streams (System.err) are static fields of class System, of type PrintStream, which extends class FilterOutputStream. These are connected to the display and by conventions are used in two distinct situations: first to display messages for the program user, and the second, to display error messages (usually for debugging purposes).

Next, let's see an example of using a ByteArrayOutputStream, used to display all 8-bits values:

ByteArrayOutputStream _buffer = new ByteArrayOutputStream(256);
try{
    for(int i=0;i<256;i++) {
        _buffer.write(i);
    }
    _buffer.writeTo(System.out);
    byte[] _tablou = _buffer.toByteArray();
}catch(IOException _e){
    System.out.println("Eroare "+ _e.getMessage());
}

Class ByteArrayOutputStream corresponds to ByteArrayInputStream and allows the connection of a stream to a buffer (a byte array). The buffer is created when an object of type ByteArrayOutputStream is instantiated by using one of the two constructors. This class offers a method of storing data in memory before processing or sending them somewhere else. In order to transmit data, method writeTo() is used. In the example above, the buffer is written to the out stream, passed as a parameter. Opposite to class ByteArrayInputStream, where the buffer was passed as an argument to the constructor, in the case of ByteArrayOutputStream, in order to obtain a reference to the buffer, a call to toByteArray() is required. This method returns a copy of the buffer.

Character Input/Output Streams

Classes for character streams are extended from class java.io.Reader for reading data and http://docs.oracle.com/javase/7/docs/api/java/io/Writer.html java.io.Writer] for writing data. Most of these classes overlap with byte stream classes, having the same functionality. The difference between them is that InputStream/OutputStream classes work (read/ write) with bytes (8 bits), as Reader/Writer work with characters represented in the Unicode standard, on 16 bits.

The corespondence between bytes streams and character streams are as follow:

In case of input streams:

  • InputStream - Reader
  • ByteArrayInputStreamCharArrayReader
  • StringBufferInputStreamStringReader
  • FileInputStreamFileReader
  • There are classes, like SequenceInputStream and DataInputStream that don't have a Reader version.

In case of output streams: