Files,

IO,

& Stuff

IO =

Input / Output

java.io.*

There's useful stuff here

java.nio.*

There's advanced stuff here

new "io" (super creative)

Streams

  • You've got a data source/destination.

  • You have no idea when the data will be available.

  • There's lots of data (?).

Application

Bunch of Data

Stream

Unidirectional

  • Readable / Input (read)

  • Writeable / Output (write)

Bidirectional

  • Duplex (direct)

Sample input

File

Application

Stream

Reading a file

Sample output

Console

Application

Stream

Writing to the console

Sample duplex

Filter to double numbers

Input: Numbers

Output: Input * 2

Bonus: Pipelines

Stream

Stream

Stream

pipe

pipe

Famous Streams

stdin

stdout

stderr

System.in

System.out

System.err

Sidebar: Type Casting

  • Some types can be converted to other types (when there is enough data to do so).
  • For example:
    • int can be converted to double
    • double can be converted to int (lossy conversion)
// value is 65.1234
double justADouble = 65.1234;

// should equal 65
int anIntTryingToBeADouble = (int) justADouble; // lossy conversion

// should be 'A'
char aCharFromAnIntFromADouble = (char) anIntTryingToBeADouble;

Bytes & Java

  • Bytes are really just unsigned 8-bit integers stored in memory.
  • The smallest 8-bit integer is 0.
  • The largest 8-bit integer is 255. (2^8 = 256)
  • But Java uses signed 8-bit integers. I'm sorry.
// value is 65.1234
double justADouble = 65.1234;

// should equal 65
int anIntTryingToBeADouble = (int) justADouble; // lossy conversion

// should be 'A'
char aCharFromAnIntFromADouble = (char) anIntTryingToBeADouble;

// should be a byte (stored in memory, typically only used for IO)
byte aByteFromACharFromAnIntFromADouble = (byte) aCharFromAnIntFromADouble;

// should be a byte (stored in memory, typically only used for IO)
byte aByteFromAnIntFromADouble = (byte) anIntTryingToBeADouble;

Casting vs. Coersion

  • Casting is done by explicitly telling Java to do a conversion (by placing the type in brackets before the value).
  • Coercion is an implicit cast where Java is forced to convert without being asked to do so.
  • Don't coerce. If Java does not want tea, you shouldn't force it to drink it.
// value is 65.1234
double justADouble = 65.1234;

// should equal 65
int anIntTryingToBeADoubleButBeingBadAtIt = justADouble; // lossy coersion

java.io.InputStream

int read();
  • Reads a single byte as an integer.
  • Bytes are really just integers (between 0 and 255).
  • It'll return -1 if there's no data.
int read( byte[] data );
  • Reads many bytes.
  • Pass it a fixed size array, where the size is the maximum number of bytes to be read.
  • Returns the number of bytes actually read.
void close();
  • Opens the stream.
  • Just kidding.

java.io.OutputStream

void write( byte[] data );
  • Writes all the bytes from data.
  • That's all.
void flush();
  • Forces all buffered data to be written.
void close();
  • Opens the stream.
  • Jokes. Still doesn't open the stream.

Streams are efficient

... usually.

Streams use chunking for efficiency.

Chunking is when you split up data into smaller data (called chunks).

InputStream does not implement any type of chunking by default. It is up to the implementation.

OutputStream must have chunking built-in - that is why flush exists.

Java is terribly inconsistent.

Streams in java are sequential.

They don't have to be. They can be parallel - which maximizes laziness.

Sequential is when the processing of chunk n must end before chunk (n+1) can be read.

How to use Files

  1. Open the file.

  2. Read / write.

  3. Close the file.

  4. Please, close the file.

Why you should close files

The Thing that Handles Files

// open a file
File fd = new File( "/relative-or-absolute/path/to/the/file" );

// do stuff with it
fd.delete();  
fd.exists();  
fd.getName();  
fd.getPath();  
fd.length();

fd = file descriptor (i.e. some kind of abstract pointer pointing to a file)

just the variable name that is typically used

Reading Files

// creates a byte stream
InputStream in = new FileInputStream( fd );

// creates a character stream
InputStreamReader inReader = new InputStreamReader( in );

// creates a buffered reader
BufferedReader reader = new BufferedReader( inReader );

Writing Files

// creates a byte stream
OutputStream out = new FileOutputStream( fd );

// creates a character stream
OutputStreamWriter inWriter = new OutputStreamWriter( out );

// creates a buffered writer
BufferedWritter writer = new BufferedWriter( inWriter );

ITI1121: Files, IO, & Stuff

By Karim Alibhai

ITI1121: Files, IO, & Stuff

  • 523