Input and Output in Java Byte- and Character-based I/O File Objects – 2015

advertisement
Input and Output in Java
Byte- and Character-based I/O
File Objects
jonas.kvarnstrom@liu.se – 2015

Two forms of file access:
2
jonkv@ida
Introduction

A stream:
 A sequence of elements
 Made available one at a time
  Sequential access
Used in most of Java's I/O classes
3
jonkv@ida
Streams 1: The Concept
4
Reading “raw” bytes
 abstract class InputStream
 Read a single byte or an array of bytes
 InputStream is;
 Reading from a file
 is = new FileInputStream("java.dat");
 Reading from an array in memory
 is = new ByteArrayInputStream(…);
 Reading from a network socket
 is = socket.getInputStream();
 …
Interfaces would have
been better – why?
Writing “raw” bytes
 abstract class OutputStream
 Write a single byte or an array of bytes
 OutputStream is;
 Writing to a file
 is = new FileOutputStream("java.dat");
 This is how you create an empty file!
 Writing to an array in memory
 is = new ByteArrayOutputStream(…);
 Writing to a network socket
 is = socket.getOutputStream();
 …
One class for each source / destination
jonkv@ida
Streams 2: Binary I/O

A simple OutputStream example:
5
Declare an AutoCloseable
resource in try()… (Java 7+)
▪ public static void main(String[] args) {
try (OutputStream os = new FileOutputStream("java.dat")) {
This is
os.write(3);
Use it inside the block…
basically all os.write(new byte[] { 6, 7, 8 });
you can do! …
… and when you exit the block,
} catch (IOException e) {
the resource (file) will
… handle I/O errors that may arise
automatically be closed, even if
there is an exception!
when opening or using the stream…
}
▪
try ( InputStream is = new FileInputStream("foo.dat");
OutputStream os = new FileOutputStream("java.dat"))
{
Using two resources…
…
} catch (IOException e) {
Error handling is important!
… handle it …
Always make sure that every
}
file is closed!
}
jonkv@ida
Streams 3: Example
6
– Very little basic functionality… for a reason!

Division of responsibilities
 ”Basic” streams handle sources and destinations
 Filter streams provide additional functionality
▪ Add buffering
▪ Support other types of data
▪ …
Your code
Filter Stream
Filter Stream
Basic Stream
jonkv@ida
Stream Filters 1: Introduction

7
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); }
…
FileOutputStream
▪
public void writeShort(short s) {
out.write((s & 0xFF00) >> 8);
…or any other
out.write(s & 0xFF);
”destination
}
stream”
…
}
▪ try (MyOutputStream out = new MyOutputStream(
new FileOutputStream("foo.dat"))) {
…
}
jonkv@ida
Stream Filters 2: How do they Work?
8
Useful output filters
 BufferedOutputStream
 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
try (DataOutputStream os =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("java.dat"))))
{
os.write(new byte[] { 6, 7, 8 });
os.writeLong(1234567890123L);
os.writeFloat(2.7f);
} catch (final IOException e) {
… handle it …
}
jonkv@ida
Stream Filters 3: Output
Useful input filters
 BufferedInputStream
 Buffers I/O:
Don't read a single byte at a time…
 DataInputStream
 readLong(), readFloat(), …
 readUTF() – reads UTF-8 format
 readLine() – deprecated!
 Ignores character encodings
 Use Readers instead!
9
jonkv@ida
Stream Filters 4: Input

11
Distinct subsystem for text-based I/O: Reader, Writer
 Sends full 16-bit Unicode text, not 8-bit bytes
Your code
Unicode
Unicode text
Filter Writer
Filter Reader
Unicode
Unicode
Filter Writer
Filter Reader
Unicode
Unicode
OutputStreamWriter
8-bit bytes
Your code
UTF-8:
“ä”  c3 a4
ISO Latin-1: “ä”  e4
OutputStream
InputStreamReader
8-bit bytes UTF-8:
c3 a4  “ä”
ISO Latin-1: c3 a4  “ä”
InputStream
jonkv@ida
Readers and Writers 2
12
Reading text
Writing text
 abstract class Reader
 abstract class Writer
 Read a single char or an array of chars
 Reader re;
 Reading from a file
 re = new FileReader("java.dat");
 Reading from an array in memory
 Read a single byte or an array of bytes
 Writer wr;
 Writing to a file
 wr = new FileWriter("java.dat");
 Writing to an array in memory
 re = new CharArrayReader(…);
 wr = new CharArrayWriter(…);
 re = new StringReader(…);
 wr = new StringWriter(…);
(writes to a StringBuffer)
 …
 …
No encoding specified: Use the platform’s
default to convert bytes  chars
So don’t use this for files that should be
machine-readable on multiple systems!
jonkv@ida
Readers and Writers 3
13
Useful filters
Text output
 BufferedWriter
 Buffers I/O:
Don't write a single char at a time…
 PrintWriter
 print(), println() methods
for primitive datatypes and Strings
Text input
 BufferedReader
 Buffers I/O:
Don't read a single char at a time…
 Method for reading a line
jonkv@ida
Readers and Writers 4: Filters
14
Specify a character encoding using OSW and ISR
OutputStreamWriter
OutputStream os =
new FileOutputStream("file.txt");
Writer wr =
new OutputStreamWriter(os, “Big5");
Your code
Unicode chars
OutputStreamWriter
Bytes in Big5 encoding
(Traditional Chinese)
FileOutputStream
InputStreamReader
Socket sock = …;
InputStream is = sock.getInputStream();
Reader re =
new InputStreamReader(is, “Cp1046”);
Your code
Unicode chars
InputStreamReader
Bytes in Cp1046
encoding (IBM arabic)
”SocketInputStream”
UTF-8  all characters supported, readable on most systems!
jonkv@ida
R/W 5: Specifying Encodings

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!");
try (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(), …
16
jonkv@ida
File[name] Objects: The File Class
Object-based I/O:
Serialization
jonas.kvarnstrom@liu.se – 2015
18
Serialization: Convert objects to/from sequences of bytes
ObjectOutputStream
ObjectInputStream
OutputStream os =
new FileOutputStream("file.dat");
ObjectOutputStream out =
new ObjectOutputStream(os);
Writes an
out.writeObject(gameBoard);
out.writeObject(highscoreList); object and
everything it
out.close();
refers to!
Your code
Objects
ObjectOutputStream
Bytes: All you need to
reconstruct the objects
FileOutputStream
Socket sock = …;
InputStream is = sock.getInputStream();
ObjectInputStream in =
new ObjectInputStream(is);
List<Score> highscoreList =
(List<Score>) in.readObject();
in.close();
Your code
Objects
ObjectInputStream
Bytes
”SocketInputStream”
jonkv@ida
Serialization 1: Intro

19
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
Serialization 2: Serializable Interface

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();
20
jonkv@ida
Serialization 3: Writing An Object Twice

Can old saved objects be read after changing the class?
 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
▪ …
 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!
21
jonkv@ida
Serialization 4: Class Versions

22
Error handling was omitted
▪
▪
▪
▪
▪
▪
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
jonkv@ida
Serialization 5: Exceptions

24
How does your program find its image files, audio files, etc?
 Your software may be installed in different locations
 Path syntax depends on the OS
 Your program, including images, can be packed inside a single JAR file
▪ Java ARchive, essentially a ZIP file

Resources reuse the Java class loading mechanism
 Place files together with your code
 Use resources to find and load them
Everything in a single JAR file:
mypackage/Main.class
mypackage/ShowImage.class
…
data/bin.dat
img/test.png
jonkv@ida
Resources 1: Data in the ClassPath

25
Since the class loading mechanism is used:
 Must first have a ClassLoader or a java.lang.Class object
▪ Simplest way: SomeClassInYourProgram.class
Not a file name:
”.class” is magic syntax
 Then, getResource() returns a java.net.URL
▪ URL url = Main.class.getResource("img/test.png");
 Finally:
▪ Use the URL's getContent() method to return:
▪ an ImageProducer, for images
mypackage/Main.class
▪ an AudioClip,
for audio
mypackage/ShowImage.class
…
▪ an InputStream,
otherwise
data/bin.dat
▪ Or construct an ImageIcon from the URL!
img/test.png
▪ It calls getContent() for you
▪ ImageIcon icon = new ImageIcon(url);
jonkv@ida
Resources 2: Example

Most IDEs have a setting determining which files are resources
 You place them in the source folders
 Compilation copies them to output folders or JAR files
26
jonkv@ida
Resources 3: IDEs
Download