08. File & Network I/O

来源:互联网 发布:恶搞锁屏软件 编辑:程序博客网 时间:2024/05/19 02:19

Java Interfaces

A Java Interface allows you to specify methods that must be implemented by a class

- Simply speaking, it is just a list of methods, but no implementations (up to Java 7)

- Several interfaces:

List<E>

Map<K, V>

Set<E>

Comparable<T>  (- compareTo() method defines natural ordering of Type)

Comparator<T> (- compare() method defines alternative ordering of Type)


Abstraction

"The essence of abstractions is preserving information that is relevant in a given context, and forgetting information that is irrelevant in that context."

Use whenever suitable in order to avoid duplication in code

In a class hierarchy, higher classes are more general/abstract

- Think of it as a basis for other classes than as a class with specific instances you want to use


A class in the middle of class hierarchy (declared abstract)

public abstract class Person { ... }

Incomplete

- Has methods & variables common to its subclasses

- Can have concrete methods

- Put common fields and methods in superclass

- Some methods can be abstract (specification only)

public abstract String getDescription();

Must be subclassed (to be instantiated)

- You cannot say "new" on an abstract class


Abstract Class vs. Interface

 Abstract ClassInterfaceConcrete Class
"extends"

Single inheritance
"implements"

Can implement multiple interfaces
Variables
No restrictions

Can have both instance and static fields
All variables must be public static finalConstructors
Abstract class cannot be instantiated using the new operatorNo constructors

An interface cannot be instantiated using the new operator
Methods
No restrictions

Can have public protected, private concrete methods
All methods must be public

File I/O

Files can be classified as Text or Binary

- file that can be (meant to be) processed using a text editor is text file

- All the other files called binary files (Designed to be read by a program)

Java source code files (*.java) are text files

Java class files (*.class) are binary files


Abstract Classes for I/O

In the java.io package

The Reader & Writer classes

- Abstract Classes

- Let you read & write characters (text)

The InputStream & OutputStream classes

- Abstract Classes

- Let you read & write bytes (binary)


Binary I/O

InputStream

- Abstract read() method - Read one byte and return it or -1 if it encounters the end of the input source

OutputStream

- Abstract write() method - Write one byte to an output location

Concrete methods to read & write an array of bytes


Character I/O

Reader class to read

- Abstract class

- Concrete read() method

Return a single character's unicode code unit (between 0 and 65535) or -1 when reached the end of the file

Writer class to write

- Abstract class

- Concrete write(int c) method

Argument c is the unicode code unit just like the read method


Text I/O

Mainly focus on using two concrete classes (FileReader and BufferedReader)

FileReader class

- New constructors

- No additional methods

BufferedReader class

- New constructors

- Override Reader class's read() method

- readLine() method which lets you read a line of text or "null" when no more line is available


Typical way to read a file:

import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class ReadLineTest {    /**     * Simple test program to print lines of a file using BufferedReader.     * @param args arguments     */    public static void main(String[] args) {        if (args.length != 1) {            System.out.println("Program to print out lines of a file, in typical fashion:");            System.out.println("using BufferedReader");            System.out.println("doing it one line at a time (with readLine())");            System.out.println("not worrying about unprintable characters");            System.out.println("put line numbers in front of each printed line");            System.out.println("  Usage: java ReadLineTest filename");            return;        }        try {            BufferedReader br = new BufferedReader(new FileReader(args[0]));            int lineNumber = 0;            boolean eof = false;            while (!eof) {                String line = br.readLine();                if (line == null) {                    eof = true;                } else {                    lineNumber = lineNumber + 1;                    System.out.println("line " + lineNumber + ": " + line);                }            }            br.close();        } catch (FileNotFoundException e) {            System.out.println("File " + args[0] + " was not found");            return;        } catch (IOException e) {            System.out.println();            System.out.println(e);            return;        }    }}

The Beauty of Buffers

Not using buffers would be like shopping without a cart

- Buffers are like shopping car to put items till it is full

- Then, you make fewer trips (if not one trip) to your car

Use Buffered I/O!


What Exceptions Must You Catch?

Subclasses of RuntimeException and Error need not be caught or declared as thrown from a method

- NumberFormatException

- ArrayIndexOutOfBounds

- StackOverflowError

Other exceptions must be caught or your method declaration must state that you might throw them

- FileNotFoundException

- IOException

- InterruptedException


Subclass to Handle Parsing

Can subclass BufferedReader to handle the parsing of the input stream


CSV Parsing Example

Class to read CSV file and return the values separated in an array of Strings

- Extends BufferedReader

- Calls super() in its constructor

- A new readCSVLine() method which calls super.readLine() method

import java.io.BufferedReader;import java.io.IOException;import java.io.Reader;/** * A simplified version of CSV Reader. * * Subclass of a BufferedReader to handle a character stream that consists of * comma separated values (CSVs) * * Provides an additional instance method, readCSVLine(), that parses lines into * substrings. The substrings are separated by comma in the original input * stream. The readCSVLine() method returns an array of references to Strings. * The Strings are the values from the line that were separated by commas. If a * value was surrounded by quotes, the quotes are removed. * * Limitations: Spaces before or after the commas are not removed. In the first * and last quote are removed from a value. Embedding commas in a quoted value * is not handled properly. (In this case, the commas will separate the values * and the quotes will not be removed from the ends of those values. */public class CSVReader extends BufferedReader {    /**     * Initializes the class.     * @param in the reader from which to read CSV lines     */    public CSVReader(Reader in) {        super(in);    }    /**     * This is the only additional method. It uses readLine from the superclass     * to get a line but returns the comma separated values as in an array of     * strings.     * @return an array of Strings containing the values At the end of the file,     *         readCSVLine returns null (just as readLine does).     * @throws IOException throws IOException     */    public String[] readCSVLine() throws IOException {        // Get a line by calling the superclass's readLine method        String line = super.readLine();        // If we're at the end of the file, readLine returns null        // so we return null.        if (line == null) {            return null;        }        // Count up the number of commas        int commaCount = 0;        for (int i = 0; i < line.length(); i++) {            if (line.charAt(i) == ',') {                commaCount = commaCount + 1;            }        }        // Allocate an array of the necessary size to return the strings        String[] values = new String[commaCount + 1];        // In a loop, set beginIndex and endIndex to the start and end        // positions of each argment and then use the substring method        // to create strings for each of the comma separate values        // Start beginIndex at the beginning of the String, position 0        int beginIndex = 0;        for (int i = 0; i < commaCount; i++) {            // set endIndex to the position of the (next) comma            int endIndex = line.indexOf(',', beginIndex);            // if the argument begins and ends with quotes, remove them            if (line.charAt(beginIndex) == '"' && line.charAt(endIndex - 1) == '"') {                // If we made it here, we have quotes around our string.                // Add/substract one from the start/end of the args                // to substring to get the value. (See else comment                // below for details on how this works.)                values[i] = line.substring(beginIndex + 1, endIndex - 1);            } else {                // If we name it here, we don't have quotes around                // our string. Take the substring of this line                // from the beginIndex to the endIndex. The substring                // method called on a String will return the portion                // of the String starting with the beginIndex and up                // to but not including the endIndex.                values[i] = line.substring(beginIndex, endIndex);            }            // Set beginIndex to the position character after the            // comma. (Remember, endIndex was set to the position            // of the comma.)            beginIndex = endIndex + 1;        }        // handle the value that's after the last comma        if (line.charAt(beginIndex) == '"' && line.charAt(line.length() - 1) == '"') {            values[commaCount] = line.substring(beginIndex + 1, line.length() - 1);        } else {            values[commaCount] = line.substring(beginIndex, line.length());        }        return values;    }}

And a Test Program to test CSVReader

import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class CSVReaderTest {    /**     * Simple test program to read CSV files.     * @param args arguments     */    public static void main(String[] args) throws FileNotFoundException, IOException {        if (args.length != 1) {            System.out.println("Usage: java CSVReaderTest <filename>");            System.exit(0);        }        FileReader fr = new FileReader(args[0]);        CSVReader c = new CSVReader(fr);        int lineNum = 0;        boolean eof = false;        while (!eof) {            String[] values = c.readCSVLine();            if (values == null) {                eof = true;            } else {                lineNum = lineNum + 1;                System.out.print("Line " + lineNum + "  " + values.length + " components:");                for (int i = 0; i < values.length; i++) {                    System.out.print(" \"" + values[i] + "\"");                }                System.out.println();            }        }        c.close();    }}

Binary I/O and Dealing with Files (before Java 7)

java.io.File class

- Represents a file on a disk but does not represent the contents

- Thus, does NOT have methods to read and write

- Provide useful methods to manipulate files and directories such as getName(), getPath(), delete(), exists(), etc

- Useful to verify a valid path and file

Just like BufferedReader

- Use BufferedInputStream to read

- Use BufferedOutputStream to write


(After Java 7)

java.nio.file package

- Path Interface: Locate a file on a file system

- Paths Class: Two static methods to return Path from string and URI

- Files Class: All static methods that operate on files and directories such as create, copy, move, delete, etc


IP Addresses

A unique number of each network address on the Internet

IPv4

- The 2nd generation of IP addresses

- A four byte IP address, ~ a billion addresses, not all available

- Running out of them

IPv6

- The 3rd generation of IP addresses

- A sixteen byte IP address, literally zillions of addresses


Ports

Computer has a small number of IP address (typically: wired, wireless, localhost)

Each application on computer can use one or more port numbers to cause network traffic to be routed to it

IP Address is like a mall, and Port number is like a store in the mall


How to read from the network (Client)

Use the java.net.Socket class with host and port

Socket client = new Socket(host, port);

Clients bind, connect and then get the InputStream and OutputStream

client.getInputStream();

client.getOutputStream();

Use DataInputStream and DataOutputStream

DataOutputStream dos = new DataOutputStream(os);

dos.writeUTF( ... )

DataInputStream class is to read bytes from a binary stream and reconstructing from the data in any of the Java primitive types and String

DataOutputStream class is to convert data from any of the Java primitive types and String to a series of bytes and writing these bytes to a binary stream

import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;public class SimpleClient {    /**     * Simple test program to read and write as a client over the network.     * @param args arguments     */    public static void main(String[] args) throws IOException, ClassNotFoundException {        Socket client = new Socket(args[0], 9898);                OutputStream os = client.getOutputStream();        DataOutputStream dos = new DataOutputStream(os);        dos.writeUTF(args[1]);        dos.flush();        InputStream is = client.getInputStream();        DataInputStream dis = new DataInputStream(is);        String str = new String(dis.readUTF());        System.out.println("Received from " + client.getInetAddress() + ": " + str);        client.close();    }}

How to read from the network (server)

Use java.net.ServerSocket with port and java.net.Socket classes

ServerSocket server = new ServerSocket(port);

Socket client = server.accept();

Servers bind and accept, then get the InputStream and OutputStream

client.getInputStream();

client.getOutputStream();

Use DataInputStream and DataOutputStream

DataInputStream dis = new DataInputStream(is);

String str = dis.readUTF();

DataOutputStream dos = new DataOutputStream(os);

dos.writeUTF("Thank you: " + client.getInetAddress());

import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class SimpleServer {    /**     * Simple test program to read and write as a server over the network.     * @param args arguments     */    public static void main(String[] args) throws IOException, ClassNotFoundException {        ServerSocket ss = new ServerSocket(9898);        System.out.println("Server is up and listening...");        System.out.println();        Socket client = ss.accept();        System.out.println("Connection from " + client.getInetAddress());        // InputStream to read bytes        InputStream is = client.getInputStream();        DataInputStream dis = new DataInputStream(is);        String str = new String(dis.readUTF());        System.out.println("   Received: " + str);        // OutputStream to write bytes        OutputStream os = client.getOutputStream();        DataOutputStream dos = new DataOutputStream(os);        dos.writeUTF("Thank you: " + client.getInetAddress());        System.out.println();        System.out.println("Good bye!!! Server is down.");        // don't forget to close resources        dos.close();        dis.close();        client.close();        ss.close();    }}

HTTP

This is just a socket protocol

- Runs on port 80 by default

- Send HTTP requests (GET, POST, etc)

- Receive HTTP reply (Header, Data)


How to read from the web in Java?

Use java.net.URL

- Get an InputStream, 

- Get an InputStreamReader

- Get a BufferedReader

- Read it like a file

Don't forget to close everything when done

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;public class URLToStringTest {    /**     * Maximum size constant.     */    private static final int MAX_SIZE = 4 * 1024 * 1024;    /**     * Reads the response from a url and returns its string representation.     * @param urlString url to parse     * @return String representation of the response from a url     */    private static String urlToString(String urlString) {        try {            URL url = new URL(urlString);            InputStream is = url.openStream();            InputStreamReader isr = new InputStreamReader(is);            BufferedReader br = new BufferedReader(isr);            StringBuilder b = new StringBuilder();            boolean eof = false;            while (!eof && b.length() < MAX_SIZE) {                String line = br.readLine();                if (line == null) {                    eof = true;                } else {                    b.append(line);                    b.append('\n');                }            }            br.close();            return b.toString();        } catch (IOException e) {            throw new AssertionError(e);        }    }    /**     * Simple test program to read and print from a url.     * @param args arguments     */    public static void main(String[] args) {        System.out.println(urlToString(args[0]));    }}

0 0