Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
2
jonkv@ida
Streams and Readers/Writers
File I/O: Two distinct but similar subsystems Binary I/O
Input and Output in Java
“Raw” byte‐based I/O
c3 a4 c3 a4 – no change
Two abstract base classes
InputStream
Byte‐, Character‐ and Object‐based I/O
File Objects
Resources
Text I/O
Character‐based I/O
Some classes connect to byte streams
with character encoding conversions
UTF-8:
ISO Latin-1:
c3 a4 ä
c3 a4 ä
Two abstract base classes
Reader
Reading a byte / array of bytes
OutputStream
Reading a char / array of chars
Writer
Writing a byte / array of bytes
Writing a char / array of chars
3
One concrete class for each source
Binary I/O
FileInputStream: From a file
InputStream is;
is = new FileInputStream("java.dat");
Text I/O
FileReader: From a file
Reader re;
re = new FileReader("java.txt");
Which one on your system? System.getProperty("file.encoding")
ByteArrayInputStream: From an array
byte[] buffer = new byte[1024];
… fill the buffer …
InputStream is;
is = new ByteArrayInputStream(buffer);
… read from the stream …
No encoding specified:
Use the platform’s default
to convert bytes chars
CharArrayReader: From an array
char[] buffer = new char[1024];
… fill the buffer …
Reader re;
re = new CharArrayReader(buffer);
… read from the stream …
StringReader: From a String
Streams and Readers/Writers
4
One concrete class for each destination
Binary I/O
FileOutputStream: To a file
OutputStream os;
os = new FileOutputStream("java.txt");
ByteArrayOutputStream: To an array
byte[] buffer = new byte[1024];
OutputStream os;
os=new ByteArrayInputStream(buffer);
… Write to the stream …
… Use the buffer …
Text I/O
FileWriter: To a file
Writer wr;
wr = new FileWriter("java.txt");
CharArrayWriter: To an array
char[] buffer = new char[1024];
Writer wr;
wr = new CharArrayWriter(buffer);
… Read from the stream …
… Use the buffer …
StringWriter: To a StringBuffer
jonkv@ida
Streams and Readers/Writers
jonkv@ida
– Streams: Can't jump / “seek” back and forth
– Very little basic functionality… for a reason!
6
jonkv@ida
A simple OutputStream example:
▪ public static void main(String[] args) {
OutputStream os = null;
try {
os = new FileOutputStream("java.txt");
os.write(3);
os.write(new byte[] { 6, 7, 8 });
…
} catch (IOException e) {
… handle it …
} finally {
try {
if (os != null) os.close();
} catch (IOException e) {…}
}
}
Streams 5: Close everything!
8
jonkv@ida
5
jonkv@ida
Streams 4: An OutputStream Example
Opening and closing multiple streams:
▪ public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream("foo.txt");
os = new FileOutputStream("java.txt");
…
} catch (IOException e) {
… handle it …
} finally {
try { if (os != null) os.close(); } catch (IOException e) {…}
try { if (is != null) is.close(); } catch (IOException e) {…}
}
One try/catch per file!
}
Declare it outside try {}…
Use it inside…
… and close it in finally {}!
Filters 1: Introduction
7
Java I/O uses the decorator design pattern
introduce additional functionality
▪ Add buffering
▪ Support other types of data
▪ …
”Basic” streams and readers/writers:
▪ Responsible for dealing with
sources and destinations
▪ Only support raw bytes/chars
Filters 2: How do Filters Work?
Your code
Filter streams and readers/writers
jonkv@ida
Error handling is important!
Always make sure that every
file is closed!
Filter Stream
Filter Stream
Basic Stream
A simple filter stream example:
▪ public class MyOutputStream {
private OutputStream out;
Your code
public MyOutputStream(final OutputStream out) {
this.out = out;
}
MyOutputStream
public void write(byte b)
{ out.write(b); }
public void write(byte[] b)
{ out.write(b); }
…
public void writeShort(short s) {
FileOutputStream
out.write((s & 0xFF00) >> 8);
…or any other
out.write(s & 0xFF);
”destination }
…
stream”
}
▪ final FileOutputStream fos = new FileOutputStream("foo.txt");
final MyOutputStream mos = new MyOutputStream(fos);
Useful output filters
10
jonkv@ida
Filters 4: Output
12
jonkv@ida
9
jonkv@ida
Filters 3: Output
Useful output filters
Binary I/O
Text I/O
Buffers I/O:
Don't write a single byte at a time…
PrintStream (System.out / err)
print(), println() methods
for primitive datatypes and Strings
Uses platform character encoding
to convert chars bytes
DataOutputStream
writeLong(), writeFloat(), …
writeUTF() – writes UTF‐8 format
writeBytes(String str) – deprecated!
Ignores character encodings
11
Useful input filters
Binary I/O
Buffers I/O:
Don't read a single byte at a time…
Buffers I/O:
Don't write a single char at a time…
PrintWriter
print(), println() methods
for primitive datatypes and Strings
Sufficient to close the "outer" stream:
This closes all its inner streams too
Filters 5: Input
BufferedInputStream
BufferedWriter
DataOutputStream os = null;
try {
os = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("java.txt")));
os.write(new byte[] { 6, 7, 8 });
os.writeLong(1234567890123L);
os.writeFloat(2.7f);
} catch (final IOException e) {
… handle it …
} finally {
try { if (os != null) os.close(); }
catch (IOException e) {…}
}
jonkv@ida
BufferedOutputStream
Filters 6: Specifying Encodings
Specify a character encoding using OSW and ISR
Text I/O
BufferedReader
Buffers I/O:
Don't read a single char at a time…
Method for reading a line
OutputStreamWriter
OutputStream os =
new FileOutputStream("file.txt");
Writer wr =
new OutputStreamWriter(os, “Big5");
InputStreamReader
Socket sock = …;
InputStream is = sock.getInputStream();
Reader re =
new InputStreamReader(is, “Cp1046”);
DataInputStream
readLong(), readFloat(), …
readUTF() – reads UTF‐8 format
readLine() – deprecated!
Ignores character encodings
Use Readers instead!
Your code
Unicode chars
OutputStreamWriter
Bytes in Big5 encoding
(Traditional Chinese)
FileOutputStream
Your code
Unicode chars
InputStreamReader
Bytes in Cp1046
encoding (IBM arabic)
”SocketInputStream”
14
jonkv@ida
Serialization 1: Intro
Serialization: Convert objects to/from sequences of bytes
OutputStream os =
new FileOutputStream("file.txt");
ObjectOutputStream out =
new ObjectOutputStream(os);
Writes an out.writeObject(gameBoard);
object and out.writeObject(highscoreList);
everything out.close();
it refers to!
Your code
ObjectInputStream
Socket sock = …;
InputStream is = sock.getInputStream();
ObjectInputStream in =
new ObjectInputStream(is);
List<Score> highscoreList =
(List<Score>) in.readObject();
in.close();
Your code
Objects
Objects
ObjectOutputStream
ObjectInputStream
Bytes: All you need to
reconstruct the objects
Serialization 2: Serializable Interface
15
The objects must implement java.io.Serializable
An interface without methods, indicating that serialization is allowed
▪ By accessing the byte stream you can read private fields!
▪ public class Pair implements Serializable {
private Object
first;
All fields must also be Serializable!
private Object
second;
private transient int hashCodeCache;
…except transient fields, which
Pair(Object first, Object second) {
this.first = first;
this.second = second;
}
we assume can be reconstructed
or are unnecessary for other reasons
}
The superclass must:
▪ Be Serializable, so we can save its data to the stream, or
▪ Have a no‐args constructor, so we can reconstruct it from scratch
Many Java classes already implement Serializable
▪ Strings, Collections subclasses, …
jonkv@ida
FileOutputStream
Bytes
”SocketInputStream”
Serialization 3: Writing An Object Twice
ObjectOutputStream must handle circular references
Node structure example:
▪ Node parent
= new Node(null);
Node child
= new Node(parent); // child points to parent
parent.addChild(node);
// parent points to child
Remembers which objects were written
▪ First time:
Write object ID + entire object representation
▪ Second time: Write object ID
Does not care whether the object was updated!
▪ List list = new ArrayList();
oos.write(list);
// Writes object ID + entire list
list.add("Another element");
oos.write(list);
// Writes the object ID…
To write a new copy of the object: Use reset()
▪ oos.reset();
16
jonkv@ida
ObjectOutputStream
Can old saved objects be read after changing the class?
Error handling was omitted
▪
▪
▪
▪
▪
▪
Some changes are allowed
▪ Adding fields – if you read an old object, the field will be set to 0/null
▪ Changing public/protected/private
▪ A few more types of changes
Others are forbidden
▪ Changing the class hierarchy in certain ways
▪ Removing Serializable
▪ …
18
jonkv@ida
Serialization 5: Exceptions
ClassNotFoundException
InvalidClassException
StreamCorruptedException
OptionalDataException
NotSerializableException
IOException
– received an object of a non‐existing class
– bad control information in the stream
– primitive data found instead of objects
– an object was not Serializable
– the usual Input/Output related exceptions
Many more serialization features…
▪ http://docs.oracle.com/javase/7/docs/technotes/guides/serialization/index.html
You must have the same serial version ID
▪ By default this is a hash of certain features in the class — too strict!
▪ To allow adding new fields, declare your own version ID:
private final static long serialVersionUID = 1; // for example
▪ IMPORTANT! Change this if you make incompatible changes to your class!
File[name] Objects: The File Class
20
File Objects (java.io.File) represent file and path names
They do not represent open files!
Also file system operations:
▪ File f = new File("/");
Find available space, total space,
File f2 = new File(f, "etc");
file system roots (C:\, D:\), File f3 = new File(f, "passwd");
System.out.print(f3.getAbsolutePath());
if (f3.exists()) {
System.out.println("You have a password file");
System.out.println("It's in the directory " + f3.getParent());
System.out.println("Its length is " + f3.length());
if (f3.canRead()) System.out.println("I can read it");
if (f3.canWrite()) System.out.println("I can write to it");
if (f3.isHidden()) System.out.println("It is hidden");
if (f3.delete()) System.out.println("I have deleted it!");
OutputStream os = new FileOutputStream(f3);
} File.createNewFile() is used for atomic locking – just use a FileOutputStream in most cases!
Also directory operations:
listFiles(), mkdir(),
renameTo(), …
jonkv@ida
17
jonkv@ida
Serialization 4: Class Versions
Support for compression
Package java.util.zip — zip, gzip, checksums
Package java.util.jar — JAR archives
Advanced high‐performance I/O operations
Package java.nio
JavaBeans Activation Framework (JAF)
Given some data (a binary file),
identify its type (for example, "JPEG image")
Identify operations available for that type
21
jonkv@ida
See Also