OOP with Java Yuanbin Wu cs@ecnu
OOP with Java 通知 Project 6: 5 月 30 日晚 9 点
复习 异常处理 语法 抛出异常 : throw 处理异常 : try, catch 异常对象 : Exception 类的子类 从方法中抛出异常 方法的异常说明 :throws 中断当前方法的执行, 返回抛出的异常对象, 在该方法的调用路径上寻找合适的 catch.
class SimpleException extends Exception { public class InheritingExceptions { public static void main(string[] args) { try { System.out.println("Throw SimpleException from f()"); throw new SimpleException(); catch(exception e) { System.out.println("Caught it!"); System.out.println(e); System.out.println(e.printStackTrace(System.out));
bar() throws Type1Exception, Type2Exception{ // throw (Type1Exception e); // throw (Type2Exception e); foo() { try{ bar(); catch (Type1Exception e){... catch (Type2Exception e){...
I/O Introduction Path Object InputStream/OutputStream Reader/Writer Typical usage of I/O streams Object Serialization
Introduction I/O Input/output 哪些行为有 I/O 操作? I/O 操作是复杂的 多种交互的设备
Introduction I/O 过程的抽象 流 (Stream) Input Output
Introduction I/O 流 抽象 : 数据的来源 (In), 数据的目的地 (Out) 字节 (01 串 ): ByteArrayStream 文件 : FileStream 字符串 : StringStream 对象 : ObjectStream
Introduction 最重要的 I/O Stream 操作 InputStream: read() OutputStream: write() close() 为生活带来便利的 I/O Stream 操作 从文件读取一行 : readline() 读取一个基本类型 : readint(), readdouble() 读取对象
public static void fileoutput() throws IOException{ String str = "hello world!"; File file = new File("d:\\test2.txt"); // 创建文件 if(!file.exists()){ file.createnewfile(); // 如果文件不存在, 则进行创建 FileOutputStream foutput = new FileOutputStream(file); BufferedOutputStream boutput = new BufferedOutputStream(fOutput); byte[] buffer = str.getbytes(); // 将字符串文本转换成字节数组 boutput.write(buffer); boutput.close(); foutput.close(); public static void fileinput() throws IOException{ File file = new File("d:\\test2.txt"); // 创建文件 FileInputStream fiutput = new FileInputStream(file); BufferedInputStream biutput = new BufferedInputStream(fIutput); int temp = 0; while((temp = biutput.read())!= -1){ // 当 temp 为 -1 时, 数据读取完毕 System.out.print((char)temp); biutput.close(); fiutput.close();
Path 接口 File 类 Java 7 之前 Path 接口 Java 7 引入, 用于替代 File 类 File 类对象可通过 topath() 得到对应的 Path 对象
Path 接口 文件路径 绝对路径 C:/Documents/tmp/Hello.java 相对路径../../tmp/Hello.java
Path 接口 Path 接口 java.nio.file 提供对文件路径字符串的操作
Path 接口 创建 Path 类型的对象 Path p1 = Paths.get("C:/Document/tmp/Hello.java"); Path p2 = FileSystems.getDefault().getPath("C:/Document/tmp/Hello.java");
Path 接口 // Microsoft Windows syntax Path path = Paths.get("C:\\home\\joe\\foo"); // Solaris syntax // Path 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()); // C:\home\joe\foo // foo // home // 3 // home\joe // home\joe\ // C:\
Files 类 包含文件操作的静态方法 文件是否存在 创建文件? 删除文件 拷贝 / 移动 重命名 列出目录下所有文件...
Files 类 判断文件是否存在 Path p = Paths.get("C:/Document/tmp/Hello.java"); System.out.println(Files.exists(p)); 判断文件是否可读 / 可写 / 可执行 Path p = Paths.get("C:/Document/tmp/Hello.java"); System.out.println(Files.isReadable(p)); System.out.println(Files.isWritable(p)); System.out.println(Files.isExecutable(p));
Files 类 删除文件 try { Files.delete(path); catch (NoSuchFileException x) { System.out.format("%s: no such" + " file or directory%n", path); catch (DirectoryNotEmptyException x) { System.out.format("%s not empty%n", path); catch (IOException x) { // File permission problems are caught here. System.out.println(x);
Files 类 获得文件相关的信息 size(path) isdirectory(path, LinkOption) isregularfile(path, LinkOption...) issymboliclink(path) getlastmodifiedtime(path, LinkOption...) setlastmodifiedtime(path, FileTime) getowner(path, LinkOption...) setowner(path, UserPrincipal)
Stream I/O 流 InputStream 类 read(), close() OutputStream 类 write(), close() 每次读入 / 写出一个字节
从不同的源头产生输入 Byte arrays String objects files InputStream 对应于不同的 InputStream 子类
InputStream ByteArrayInputStream StringBufferInputStream FileInputStream...
OutputStream 输出到不同的目的地 Byte arrays String objects files 对应于不同的 OutputStream 子类
OutputStream ByteArrayOutputStream FileOutputStream...
Stream InputStream ByteArrayInputStream StringBufferInputStream FileInputStream... OutputStream ByteArrayOutputStream FileOutputStream...
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("xanadu.txt"); out = new FileOutputStream("outagain.txt"); int c; while ((c = in.read())!= -1) out.write(c); finally { if (in!= null) in.close(); if (out!= null) out.close();
Stream 是否有效 InputStream/OutputStream 每次读 / 写一个字节 缓冲区 (buffer) 可以帮助提高效率 是否易用 有时需要读入 / 写出一个基本类型, 而不是字节 readint(), readdouble() 是否易读 需要格式化的输出 println(), print(), printf(),..
Stream 希望 : 对每一种输入输出流都可以 选择是否带缓冲 选择读入字节还是基本类型 提供格式化的输出 How?
Stream 如何实现带缓冲的输入 / 输出流? 方案 1: read() 方法增加参数 read(byte[ ], int off, int len) 缺点 buffer 长度需要用户指定 用户需要知道更多实现细节
Stream 如何实现带缓冲的输入 / 输出流? 方案 2 继承 BufferedByteArrayInputStream, BufferedByteArrayOutputStream BufferedStringBufferInputStream, BufferedStringBufferOutputStream BufferedFileInputStream, BufferedFileOutputStream 缺点 类过多 无法动态加载
Stream 如何实现带缓冲的输入 / 输出流? 方案 3 组合 定义 BufferedInputStream 类 包含一个 InputStream 对象作为成员 调用该 InputStream 对象的 read(byte[], int off, int len) 实现缓冲 该调用在不同系统上有不同的优化, 并且被封装
FileInputStream fin = new FileInputStream("xanadu.txt"); BufferedInputStream bf = new BufferedInputStream(fin); bf.read(); // buffered read FileOutputStream fout = new FileOutputStream("xanadu.txt"); BufferedOutputStream bf = new BufferedOutputStream(fout); bf.write(1); // buffered write ByteArrayInputStream bin = new ByteArrayInputStream("xanadu.txt".getBytes()); BufferedInputStream bf = new BufferedInputStream(bin); bf.read(); // buffered read ByteArrayOutputStream bout = new ByteArrayOutputStream("xanadu.txt".getBytes()); BufferedOutputStream bf = new BufferedOutputStream(bout); bf.write(1); // buffered read
Stream 添加缓冲功能 BufferedInputStream 添加读取基本类型功能 DataInputStream readint(), readdouble(), readfloat(),...
FileInputStream fin = new FileInputStream("xanadu.txt"); DataInputStream din = new DataInputStream(fin); din.read(); din.readint(); din.readdouble(); FileOutputStream fout = new FileOutputStream("xanadu.txt"); DataOutputStream dout = new DataOutputStream(fout); dout.write(1); dout.writeint(10), dout.writedouble(3.14); ByteArrayInputStream bin = new ByteArrayInputStream("xanadu.txt".getBytes()); DataInputStream din = new DataInputStream(bin); din.read(); din.readint(); din.readdouble(); ByteArrayOutputStream bout = new ByteArrayOutputStream("xanadu.txt".getBytes()); DataOutputStream bout = new DataOutputStream(bout); bout.write(1); bout.writeint(10), bout.writedouble(3.14);
Stream 添加缓冲功能 BufferedInputStream 添加读取基本类型功能 DataInputStream readint(), readdouble(), readfloat(),... 添加格式化输出功能 PrintStream println(), print(),
FileOutputStream fout = new FileOutputStream("xanadu.txt"); PrintStream ps = new PrintStream(fout); ps.write(1); ps.println( hello ); ps.print( world ); ByteArrayOutputStream bout = new ByteArrayOutputStream("xanadu.txt".getBytes()); PrintStream ps = new PrintStream(bout); ps.write(1); ps.println( hello ); ps.print( world );
FilterInputStream 特点 BufferedInputStream, DataInputStream 为 InputStream 的子类 具有 InputStream 所有的类的子类接口
FilterInputStream InputStream FilterInputStream BufferdInputStream DataInputStream
FilterOutputStream OutputStream FilterOutputStream BufferdOutputStream DataOutputStream PrintStream
FilterInputStream 特点 BufferedInputStream, DataInputStream 为 InputStream 的子类 具有 InputStream 所有的类的子类接口 FilterInputStream 的对象可以作为 FilterInputStream 的参数!
FileInputStream fin = new FileInputStream("xanadu.txt"); BufferedInputStream bf = new BufferedInputStream(fin); DataInputStream din = new DataInputStream(bf); din.read(); din.readint(); din.readdouble(); FileOutputStream fout = new FileOutputStream("xanadu.txt"); BufferedOutputStream bf = new BufferedOutputStream(fout); DataOutputStream dout = new DataOutputStream(bf); dout.write(1); dout.writeint(10); dout.writedouble(3.14);
Decorator pattern InputStream ByteArrayInputStream FileInputStream StringBufferInputStream FilterInputStream BufferdInputStream DataInputStream 装饰器
总结 Stream InputStream, OutputStream 根据数据源的不同, 分为 FileInputStream, ByteArrayInputStream FileOutputStream, ByteArrayOutputStream 可以有不同的装饰器 BufferedInputStream, DataInputStream PrintStream
public static void fileoutput() throws IOException{ String str = "hello world!"; File file = new File("d:\\test2.txt"); // 创建文件 if(!file.exists()){ file.createnewfile(); // 如果文件不存在, 则进行创建 FileOutputStream foutput = new FileOutputStream(file); BufferedOutputStream boutput = new BufferedOutputStream(fOutput); byte[] buffer = str.getbytes(); // 将字符串文本转换成字节数组 boutput.write(buffer); boutput.close(); foutput.close(); public static void fileinput() throws IOException{ File file = new File("d:\\test2.txt"); // 创建文件 FileInputStream fiutput = new FileInputStream(file); BufferedInputStream biutput = new BufferedInputStream(fIutput); int temp = 0; while((temp = biutput.read())!= -1){ // 当 temp 为 -1 时, 数据读取完毕 System.out.print((char)temp); biutput.close(); fiutput.close();
Reader / Writer InputStream, OutputStream 每次读入 / 写出一个字节 Reader, Writer 每次读入 / 写出一个字符 Utf-16 每次读入 / 写出 16bit, 或者 32bit
Reader / Writer 读写字节 InputStream OutputStream FileInputStream FileOutputStream StringBufferInputStrea m (no corresponding class) ByteArrayInputStream ByteArrayOutputStrea m 读写字符 Reader Writer FileReader FileWriter StringReader StringWriter CharArrayReader CharArrayWriter
Reader / Writer decorators 读写字节 FilterInputStream FilterOutputStream BufferedInputStream BufferedOutputStream DataInputStream 读写字符 FilterReader FilterWriter BufferedReader BufferedWriter DataInputStream DataOutputStream PrintStream DataOutputStream PrintWriter PrintWriter 可以用 OutputStream 作为参数
例子 Typical uses of I/O streams
import java.io.*; public class BufferedInputFile { // Throw exceptions to console: public static String read(string filename) throws IOException { // Reading input by lines: BufferedReader in = new BufferedReader(new FileReader(filename)); String s; StringBuilder sb = new StringBuilder(); while((s = in.readline())!= null) sb.append(s + "\n"); in.close(); return sb.tostring(); public static void main(string[] args) throws IOException { System.out.print(read("BufferedInputFile.java"));
import java.io.*; public class MemoryInput { public static void main(string[] args) throws IOException { StringReader in = new StringReader( BufferedInputFile.read("MemoryInput.java")); int c; while((c = in.read())!= -1) System.out.print((char)c);
import java.io.*; public class FormattedMemoryInput { public static void main(string[] args) throws IOException { try { DataInputStream in = new DataInputStream( new ByteArrayInputStream( BufferedInputFile.read( "FormattedMemoryInput.java").getBytes())); while(true) System.out.print((char)in.readByte()); catch(eofexception e) { System.err.println("End of stream");
import java.io.*; public class TestEOF { public static void main(string[] args) throws IOException { DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("TestEOF.java"))); while(in.available()!= 0) System.out.print((char)in.readByte());
import java.io.*; public class BasicFileOutput { static String file = "BasicFileOutput.out"; public static void main(string[] args) throws IOException { BufferedReader in = new BufferedReader( new StringReader( BufferedInputFile.read("BasicFileOutput.java"))); PrintWriter out = new PrintWriter( new BufferedWriter(new FileWriter(file))); int linecount = 1; Short cut: String s; PrintWriter out = new PrinterWriter(file); while((s = in.readline())!= null ) out.println(linecount++ + ": " + s); out.close(); // Show the stored file: System.out.println(BufferedInputFile.read(file));
import java.io.*; public class StoringAndRecoveringData { public static void main(string[] args) throws IOException { DataOutputStream out = new DataOutputStream( new BufferedOutputStream(new FileOutputStream("Data.txt"))); out.writedouble(3.14159); out.writeutf("that was pi"); out.writedouble(1.41413); out.writeutf("square root of 2"); out.close(); DataInputStream in = new DataInputStream( new BufferedInputStream(new FileInputStream("Data.txt"))); System.out.println(in.readDouble()); // Only readutf() will recover the // Java-UTF String properly: System.out.println(in.readUTF()); System.out.println(in.readDouble()); System.out.println(in.readUTF());
Standard I/O System.out PrintStream System.err PrintStream System.in 需要一些预处理
import java.io.*; public class Echo { public static void main(string[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); String s; while((s = stdin.readline())!= null && s.length()!= 0) System.out.println(s);