input / output - · pdf filebyte streams • performs input/output using 8bit bytes •...
TRANSCRIPT
Outline• Input / Output
• Aim: “Understand how Java can receive input from streams and files and generate equivalent outputs”
• Handling Streams
• Handling Files
• Java NIO
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
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