Input / Output - · PDF fileByte Streams • Performs input/output using 8bit bytes •...

31
Input / Output Ric Glassey [email protected]

Transcript of Input / Output - · PDF fileByte Streams • Performs input/output using 8bit bytes •...

Input / OutputRic Glassey

[email protected]

Outline• Input / Output

• Aim: “Understand how Java can receive input from streams and files and generate equivalent outputs”

• Handling Streams

• Handling Files

• Java NIO

Stream I/O

Streams• Represent an input source and output destination

• Layer of abstraction for many data managers

• File, memory, device, network socket

• Bytes, primitives, localised characters, objects

DataSource

Program01101001 10010011

DataDestination

Program 11110011 11001100

File,Memory, Network,

etc

Input Stream

Output StreamFile,

Memory, Network,

etc

Byte Streams• Performs input/output using 8bit bytes

• Other streams extend from this class, so it is normally not used directly (e.g. FileInputStream)

• Streams should always be closed immediately after use - avoids resource leakage

• via finally block

• or try-with-resource statement

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("input-text.txt"); out = new FileOutputStream("output-text.txt"); int c;

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

Character Streams

• Java stores character values internally as Unicode

• Local encodings (e.g. ASCII) are converted automatically

• Character streams operate the same as Byte streams, reusing the pattern of code

• Create Input/Output Stream

• Try to read and write by byte/character

• Catch any IOExceptions

• Finally release the resources once complete (on success or fail)

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("input-text.txt"); outputStream = new FileWriter("output-text.txt");

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

Buffered Streams

• Byte and Characters streams have been unbuffered - we take each unit as it comes

• This is quite inefficient, as the OS is performing a lot of read/write requests on demand

• Memory, disk, network operations are slow

• A buffer (area of memory) is used as a staging area to store data before the native OS is invoked

DataSource

Program

01101001 10010011

Input Stream + Buffer

10101000 10111011

11001101 11110001

11001111

Buffer is not yet full

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("input-text.txt")); outputStream = new PrintWriter(new FileWriter("output-text.txt"));

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

Instead of characters, wait until a complete line

has been read

Tokenisation

• While working at character and line level is useful, most data manipulation tasks work on a token level

• A token depends on how a block of data should be separated using a delimiter

• Whitespace

• Other character (e.g. comma in CSV files)

import java.io.*;import java.util.Scanner;

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

Scanner s = null;

try { s = new Scanner(new BufferedReader(new FileReader(“input.txt")));

while (s.hasNext()) { System.out.println(s.next()); } } finally { if (s != null) { s.close(); } } }}

default delimiter is ‘whitespace’, Scanner.useDelimiter(“…”) to change

Further streams

• More streams are available depending on the program needs

• DataStreams (for primitive types)

• boolean,char,byte,short,int,long,float,double

• ObjectStreams

• Class must implement Serializable interface

File I/O (+NIO)

General File I/O

• As of Java 7, file manipulation has been changed

• java.nio.file package is now preferred

• jave.io.file will become legacy, but will be around for a while

• Main entry points are Path and Files

• Practice with both legacy and new!

File Paths

• Any manipulation of files will involve locating a file by its filename and filepath

• Most filesystems are hierarchical / tree-based

• root/then/path/to/some/file.txt

• consisting of directories, separators, files

File Path Issues

• Different operating systems use different separators

• /home/ric/lecture

• C:\home\ric\lecture

• Relative and Absolute paths

• ric/lecture (relative to current context)

• /home/ric/lecture (relative to root of filesystem)

File Path Issues

• Symbolic Links (symlinks)

• Files may actually be pointers to other locations on the file system (aka alias)

root

home

alice bob carol

report work

morework

stuff

my_report

symlink

java.nio.file.Path

• Programmatic representation of a path in a file system

• Models the name and location of a file*

• Used to locate, examine and manipulate files

// None of these methods needs the file to exist

// Microsoft Windows syntaxPath path = Paths.get("C:\\home\\joe\\foo");

// Solaris syntaxPath path = Paths.get("/home/joe/foo");

System.out.format("toString: %s%n", path.toString());System.out.format("getFileName: %s%n", path.getFileName());System.out.format("getName(0): %s%n", path.getName(0));System.out.format("getNameCount: %d%n", path.getNameCount());System.out.format("subpath(0,2): %s%n", path.subpath(0,2));System.out.format("getParent: %s%n", path.getParent());System.out.format("getRoot: %s%n", path.getRoot());

Joining Paths• Combine paths using resolve method

• e.g. common use case when processing multiple files and the absolute path needs to be created

• path/to/ + file1.txt, file2.txt, file3.txt, etc

// SolarisPath p1 = Paths.get("/path/to");// Result is /home/joe/foo/barSystem.out.format("%s%n", p1.resolve(“file1.txt"));

// Microsoft WindowsPath p1 = Paths.get("C:\\path\\to");// Result is C:\home\joe\foo\barSystem.out.format("%s%n", p1.resolve(“file1.txt"));

Finding the Path between Paths

• Using the relativize method

Path p1 = Paths.get("joe");Path p2 = Paths.get("sally");

// Result is ../sallyPath p1_to_p2 = p1.relativize(p2);// Result is ../joePath p2_to_p1 = p2.relativize(p1);

// with some more distancePath p1 = Paths.get("home");Path p3 = Paths.get("home/sally/bar");

// Result is sally/barPath p1_to_p3 = p1.relativize(p3);// Result is ../..Path p3_to_p1 = p3.relativize(p1);

java.nio.file.Files

• Operations on files (reading, writing, manipulation)

• Class consists entirely of static methods

• Compare with java.io.File

• Acts on Paths

Files Operations

Path path = Paths.get("home/sally/bar");Files.exists(path);Files.notExists(path);// The file is verified to exist// The file is verified to not exist// The file's status is unknown...// this result can occur when file cannot be accessed

boolean isRegularExecutableFile = Files.isRegularFile(path) & Files.isReadable(path) & Files.isExecutable(path);

Path p1 = "path/to/file";Path p2 = "path/to/a/symlink/to/file/above";

if (Files.isSameFile(p1, p2)) { // Logic when the paths locate the same file}

Files Operations

try { Files.delete(path);

// n.b. deleteIfExists(path) can be used to pass // silently and not throw exceptions

} catch (NoSuchFileException x) { System.err.format("%s: no such" + " file or directory%n", path);} catch (DirectoryNotEmptyException x) { System.err.format("%s not empty%n", path);} catch (IOException x) { // File permission problems are caught here. System.err.println(x);}

copying and moving methods also available

Reading from small files

• Whilst the java.io Streams earlier are sufficient, java.nio alternatives should also be tested

• A common use case of reading all bytes or lines into a suitable collection is provided

Path file = "/path/to/file";byte[] allBytes = Files.readAllBytes(file);List<String> allLines = Files.readAllLines(file, Charset.defaultCharset());

Buffered read/write for text files

Charset charset = Charset.forName("US-ASCII");try (BufferedReader reader = Files.newBufferedReader(file, charset)) { String line = null; while ((line = reader.readLine()) != null) { System.out.println(line); }} catch (IOException x) { System.err.format("IOException: %s%n", x);}

String s = “...";// opens or creates file at specified pathtry (BufferedWriter writer = Files.newBufferedWriter(file, charset)) { writer.write(s, 0, s.length());} catch (IOException x) { System.err.format("IOException: %s%n", x);}

Review• Exception handling and File I/O are independent, but

closely related topics in Java

• Going outside of our program invites more exceptional events, and we must design accordingly

• There is a balance to be struck between too defensive (API is unwieldy to us) and trusting the client to do the correct action.

• Be observant of legacy and new File handling operations

• Subtle detail that illustrates your understanding

Readings• Objects First with Java, 5th Ed. **required**

• Chapter 12: Handling Errors

• http://kth-primo.hosted.exlibrisgroup.com/KTH:one_search:KTH_LMSMILL13432475

• The Java Tutorial: Basic I/O

• https://docs.oracle.com/javase/tutorial/essential/io/index.html

Survey

• Final Survey!

• A chance to reflect on your own experiences and preferences for the complete course

• And to give a hint of your project ideas :-)

• https://www.surveymonkey.com/s/DBJHDWB