550 likes | 749 Views
第å…ç« I/O æµå’Œç³»ç»Ÿç±». I/O 是应用程åºçš„一个基本功能 ä»Žç»ˆç«¯è®¾å¤‡è¯»å†™æ•°æ® ä»Žæ–‡ä»¶ä¸è¯»å†™æ•°æ® 从网络连接ä¸è¯»å†™æ•°æ® æ•°æ®è¯»å†™æ—¶çš„æ ¼å¼åŒ–å¤„ç† ä¸åŒçš„è¯è¨€å¯¹ I/O çš„æ”¯æŒ C:  以库的形å¼æ供,功能强大çµæ´» , 但安全性差 C++: 建立在 stream( æµ ) 概念之上 , 类型安全 , 扩展性好 Java: 类似 C++, 建立在 stream 的概念上 Java I/O 通过系统类 ( System) console I/O 通过 java.io 包. 6.1 Java 的输入 / 输出 stream
E N D
第六章 I/O 流和系统类 • I/O是应用程序的一个基本功能 • 从终端设备读写数据 • 从文件中读写数据 • 从网络连接中读写数据 • 数据读写时的格式化处理 • 不同的语言对I/O的支持 • C: 以库的形式提供,功能强大灵活, 但安全性差 • C++: 建立在 stream(流) 概念之上, 类型安全, 扩展性好 • Java: 类似C++, 建立在 stream 的概念上 • Java I/O • 通过系统类 (System) console I/O • 通过 java.io 包 Chapter 6 I/O Stream
6.1 Java 的输入/输出 stream • I/O stream 的基本概念 Chapter 6 I/O Stream
I/O stream 的使用方法 • java.io 包提供了一组类支持上述方法的 I/O stream 的使用 (browse the java.io doc.) • 需要在程序中 import java.io.* 去使用 I/O stream • I/O stream 分为字符 stream 和字节 stream Chapter 6 I/O Stream
6.1.1 Java I/O stream 的类层次结构 • 字符 stream 提供 unicode (16 bit) 字符的 I/O • Reader/Writer 是字符 stream I/O 的抽象类, 提供字符 stream I/O 的公共 API • 字符 stream 的类层次结构 Chapter 6 I/O Stream
字节 stream 提供 8 bit 字节的 I/O • InputSteam / OutputStream 是字节 stream I/O 的抽象类, 提供字节 stream I/O 的公共 API Chapter 6 I/O Stream
Reader / InputStream 定义了类似的 API • Reader’s API • int read() • int read(char cbuf[]) • int read(char cbuf[], int offset, int length) • InputStream’s API • int read() • int read(byte cbuf[]) • int read(byte cbuf[], int offset, int length) Chapter 6 I/O Stream
Writer / OutputStream 定义了类似的 API • Writer’s API • int write(int c) • int write(char cbuf[]) • int write(char cbuf[], int offset, int length) • OutputStream’s API • int write(int c) • int write(byte cbuf[]) • int write(byte cbuf[], int offset, int length) Chapter 6 I/O Stream
Decorator Pattern used in the Java file system • The use of layered objects to dynamically and transparently add responsibilities to individual objects is referred to as the Decorator pattern • The decorator pattern specifies that all objects that wrap around your initial object have the same interface. This makes the basic use of the decorators transparent—you send the same message to an object whether it has been decorated or not • Decorators are often used when simple subclassing results in a large number of classes in order to satisfy every possible combination that is needed—so many classes that it becomes impractical Chapter 6 I/O Stream
The Java I/O library requires many different combinations of features, and this is the justification for using the decorator pattern • The classes that provide the decorator interface to control a particular InputStream or OutputStream are the FilterInputStream and FilterOutputStream • Ex. Common used decorators • DataInputStream • BufferedInputStream Chapter 6 I/O Stream
6.1.2 简单的字节 I/O stream • 简单的字节 I/O stream 是 InputStream 和 OutputStream 的直接子类 • FileInputSteam / FileOutputStream • PipedInputStream / PipedOutputStream • ByteArrayInputStream / ByteArrayOutputStream • SequenceInputStream • StringBufferInputStream 1. 读写文件(JB demo) Chapter 6 I/O Stream
例: import java.io.*; public class FileStreamsTest { public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream("test_in.txt"); FileOutputStream out = new FileOutputStream("test_out.txt"); int b; while ((b = in.read()) != -1) out.write(b); in.close(); out.close(); } } Chapter 6 I/O Stream
例: 利用 FileReader / FileWriter 类实现前面例子同样的功能(JB demo) import java.io.*; public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File(" test_in.txt "); File outputFile = new File(" test_out.txt "); FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } } Chapter 6 I/O Stream
2. 管道流, pipe streams • pipe streams 可将一个线程 (Thread) 的输出送到另一个线程的输入, 不需要另外的中间文件或缓冲区 Chapter 6 I/O Stream
例(JB demo, partial): import java.io.*; public class RhymingWords { public static void main(String[] args) throws IOException { FileReader words = new FileReader("words.txt"); // do the reversing and sorting Reader rhymedWords = reverse( sort( reverse(words) ) ); // write new list to standard out BufferedReader in = new BufferedReader(rhymedWords); String input; while ((input = in.readLine()) != null) System.out.println(input); in.close(); } Chapter 6 I/O Stream
public static Reader reverse(Reader source) throws IOException { BufferedReader in = new BufferedReader(source); PipedWriter pipeOut = new PipedWriter(); PipedReader pipeIn = new PipedReader(pipeOut); PrintWriter out = new PrintWriter(pipeOut); new ReverseThread(out, in).start(); return pipeIn; } Chapter 6 I/O Stream
public static Reader sort(Reader source) throws IOException { BufferedReader in = new BufferedReader(source); PipedWriter pipeOut = new PipedWriter(); PipedReader pipeIn = new PipedReader(pipeOut); PrintWriter out = new PrintWriter(pipeOut); new SortThread(out, in).start(); return pipeIn; } } Chapter 6 I/O Stream
3. 存储器读写 • Java 提供了 ByteArrayInputStream, 和 ByteArrayOutputStream 用来将数据写入一个在 ByteArrayOutputStream 内部的存储器区域, 或将数据从一个 ByteArrayInputStream 内部的存储器区域读出 • 访问 ByteArrayInputStream, 和 ByteArrayOutputStream 的方法和访问其它 stream 的方法一样 • StringReader 和 StringWriter 提供类似的功能, 只不过数据是写入一个字符串, 或从一个字符串中读出 4. 用 Stream 来连接文件 • SequenceInputStream 支持用一个 Stream 从多个输入源连续读取数据 Chapter 6 I/O Stream
import java.io.*; public class Concatenate { public static void main(String[] args) throws IOException { ListOfFiles mylist = new ListOfFiles(args); SequenceInputStream s = new SequenceInputStream(mylist); int c; while ((c = s.read()) != -1) System.out.write(c); s.close(); } } Chapter 6 I/O Stream
6.1.3 过滤流 (filter stream) • Filter stream 一般总是和另一个 stream 结合起来使用. Filter stream 从那个 stream 读或向那个 stream 写数据, 并对读出的或要写入的数据进行处理 (过滤) • 常见的过滤有 • 对数据进行缓冲 • 对数据进行计数 • 转换数据格式 例: • DataInputStream and DataOutputStream • BufferedInputStream and BufferedOutputStream • PushbackInputStream • PrintStream (This is an output stream.) Chapter 6 I/O Stream
例: BufferedReader d = new BufferedReader(new DataInputStream(System.in)); String input; while ((input = d.readLine()) != null) { ... //do something interesting here } Chapter 6 I/O Stream
1. DataInputStrem 和 DataOutputStream import java.io.*; // JB demo public class DataIODemo { public static void main(String[] args) throws IOException { // write the data out DataOutputStream out = new DataOutputStream(new FileOutputStream("invoice1.txt")); double[ ] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; int[ ] units = { 12, 8, 13, 29, 50 }; String[ ] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain" }; Chapter 6 I/O Stream
for(int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeChar('\t'); out.writeInt(units[i]); out.writeChar('\t'); out.writeChars(descs[i]); out.writeChar('\n'); } out.close(); // flush the data in buffer into the file // read it in again DataInputStream in = new DataInputStream(new FileInputStream("invoice1.txt")); double price; int unit; StringBuffer desc; double total = 0.0; Chapter 6 I/O Stream
try{ while (true){ price = in.readDouble(); in.readChar(); // throws out the tab unit = in.readInt(); in.readChar(); // throws out the tab char chr; desc = new StringBuffer(20); char lineSep = System.getProperty("line.separator").charAt(0); while ((chr = in.readChar()) != lineSep) desc.append(chr) ; System.out.println("You've ordered " + unit + " units of " + desc + " at $" + price); total = total + unit * price; } // while loop } catch (EOFException e) { } System.out.println("For a TOTAL of: $" + total); in.close(); } } Chapter 6 I/O Stream
2. 用户自己建立新的过滤流 • 用户自己建立过滤流的步骤 • 创建一个 FilterInputStream 和 FilterOutputStream 的子类 • 置换 read() 和 write() 方法 • 置换所需的其它方法 • 确保输入流和输出流一起工作 Chapter 6 I/O Stream
用户自己建立过滤流的例子 • 例子中用到了四个类和一个接口 (除了主类, 都已在JAVA类库中) • CheckedOutputStream / CheckedInputStream • Checksum interface • Adler32 class (calculate CRC-32) • CheckedIODemo () • CheckedOutputStream • 构造函数 public CheckedOutputStream(OutputStream out, Checksum cksum) { super(out); this.cksum = cksum; } Chapter 6 I/O Stream
在 CheckedOutputStream 中被置换的函数 • write(int i) • write(byte b[ ]) • write(byte b[ ], int offset, int length) public void write(int b) throws IOException { out.write(b); cksum.update(b); } public void write(byte[] b) throws IOException { out.write(b, 0, b.length); cksum.update(b, 0, b.length); } public void write(byte[] b, int offset, int length) throws IOException { out.write(b, offset, length); cksum.update(b, offset, length); } Chapter 6 I/O Stream
(2) CheckedInputStream • 构造函数 public CheckedInputStream(InputStream in, Checksum cksum) { super(in); this.cksum = cksum; } • 在 CheckedInputStream 中被置换的函数 • int read() • int read(byte[ ] b) • int read(byte[ ] b, offset, length) public int read() throws IOException { int b = in.read(); if(b != -1) cksum.update(b); return b; } Chapter 6 I/O Stream
public int read(byte[] b) throws IOException { int len; len = in.read(b, 0, b.length); if (len != -1) { cksum.update(b, 0, b.length); } return len; } public int read(byte[] b, int off, int len) throws IOException { len = in.read(b, off, len); if (len != -1) { cksum.update(b, off, len); } return len; } • 演示 CheckedOutputStream / CheckedOutputStream 的程序 import java.io.*; // JB demo import java.util.zip.*; public class CheckedIODemo { Chapter 6 I/O Stream
public static void main(String[] args) throws IOException { Adler32 inChecker = new Adler32(); Adler32 outChecker = new Adler32(); CheckedInputStream in = null; CheckedOutputStream out = null; try { in = new CheckedInputStream( new FileInputStream("farrago.txt"), inChecker); out = new CheckedOutputStream( new FileOutputStream("outagain.txt"), outChecker); } catch (FileNotFoundException e){ System.err.println("CheckedIODemo: " + e); System.exit(-1); } catch (IOException e) { System.err.println("CheckedIODemo: " + e); System.exit(-1); } Chapter 6 I/O Stream
int c; while ((c = in.read()) != -1) out.write(c); System.out.println("Input stream check sum: " + inChecker.getValue()); System.out.println("Output stream check sum: " + outChecker.getValue()); in.close(); out.close(); } } • CheckedIODemo 运行后的输出结果 Input stream check sum: 736868089 Output stream check sum: 736868089 6.1.4 随机访问文件 • 前面所述字符/字节都是顺序访问的流 Chapter 6 I/O Stream
java.io 中提供了 RandomAccessFile 类 • RandomAccessFile 类支持(同时)读和写的操作 • RandomAccessFile 提供用于随机访问的方法(文件指针操作) • skipBytes() - 相对移位 • seek() - 绝对移位 • getFilePointer() - 得到当前文件指针位置 • 使用 RandomAccessFile • new RandomAccessFile(“farrago.txt”, “r”); // 只读 • new RandomAccessFile(“farrago.txt”, “rw”); // 同时读写写 • RandomAccessFile 支持的典型写操作 • write(int i) • write(byte b[ ]) • write(byte b[ ], int offset, int length) Chapter 6 I/O Stream
RandomAccessFile 支持的典型读操作 • read(int i) • read(byte b[ ]) • read(byte b[ ], int offset, int length) • RandomAccessFile 支持的其余读写操作请见 JDK 文档资料 6.2 系统类 • Java 用系统类提供独立于系统具体实现的统一系统服务接口 Chapter 6 I/O Stream
系统类 (System) 主要包含 • 标准输入, 输出, 和错误流 • 系统属性 • 垃圾收集 • 动态库的装载 • 系统类的特点 • 是一个最终类 • 所有的成员变量都是私有的 • 所有的变量和方法都是类变量和类方法 (可通过类名直接使用) 例(JB demo): class UserNameTest { public static void main(String[] args) { String name; name = System.getProperty("user.name"); System.out.println(name); } } Chapter 6 I/O Stream
6.2.1 标准输入/输出 • 标准输入: System.in - 数据来自键盘 • read() • 标准输出: System.out - 数据送往显示器 • println(x) // print x and a newline • print(x) // print x only • 错误输出: System.err -数据送往显示器 • print/println 只接受一个参数, 但参数可以是下述之一 • Object // means the parameter can be any class • String • char[] • int • long • float • double • boolean Chapter 6 I/O Stream
例(JB demo): public class DataTypePrintTest { public static void main(String[ ] args) { Thread objectData = new Thread(); String stringData = "Java Mania"; char[] charArrayData = { 'a', 'b', 'c' }; int integerData = 4; long longData = Long.MIN_VALUE; float floatData = Float.MAX_VALUE; double doubleData = Math.PI; boolean booleanData = true; System.out.println(objectData); System.out.println(stringData); System.out.println(charArrayData); System.out.println(integerData); System.out.println(longData); Chapter 6 I/O Stream
System.out.println(floatData); System.out.println(doubleData); System.out.println(booleanData); } } • 程序运行输出 Thread[Thread-4,5,main] Java Mania abc 4 -9223372036854775808 3.40282e+38 3.14159 true 6.2.2 系统属性 • 系统类维护一个由 <关键字, 值> 对描述的系统属性的集合 Chapter 6 I/O Stream
系统属性的获取 • System.getProperty(“path.separator”); // may return null • // getProperty with default return value System.getProperty("subliminal.message", "Buy Java Now!"); • System.getProperties(); // return a Properties object • 系统属性的设置 • 可通过 System.setProperties() 修改当前的系统属性 Chapter 6 I/O Stream
import java.io.*; // JB demo import java.util.Properties; public class PropertiesTest { public static void main(String[] args) throws Exception { // set up new properties object from file "myProperties.txt" FileInputStream propFile = new FileInputStream( "myProperties.txt"); Properties p = new Properties(System.getProperties()); p.load(propFile); // set the system properties System.setProperties(p); // display new properties System.getProperties().list(System.out); } } • myProperties.txt: subliminal.message=Buy Java Now! Chapter 6 I/O Stream
-- listing properties -- java.runtime.name=Java(TM) 2 Runtime Environment, Stand... sun.boot.library.path=C:\JBuilder6\jdk1.3.1\jre\bin java.vm.version=1.3.1-b24 java.vm.vendor=Sun Microsystems Inc. java.vendor.url=http://java.sun.com/ Chapter 6 I/O Stream
path.separator=; java.vm.name=Java HotSpot(TM) Client VM file.encoding.pkg=sun.io java.vm.specification.name=Java Virtual Machine Specification user.dir=D:\MSE_JBuilder\PropertiesTest java.runtime.version=1.3.1-b24 Chapter 6 I/O Stream
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment os.arch=x86 java.io.tmpdir=C:\DOCUME~1\WINDOW~1\LOCALS~1\Temp\ line.separator= java.vm.specification.vendor=Sun Microsystems Inc. java.awt.fonts= os.name=Windows 2000 subliminal.message=Buy Java Now! java.library.path=C:\JBuilder6\jdk1.3.1\bin;.;C:\WINDOW... java.specification.name=Java Platform API Specification java.class.version=47.0 os.version=5.1 Chapter 6 I/O Stream
user.home=C:\Documents and Settings\Windows XP user.timezone= java.awt.printerjob=sun.awt.windows.WPrinterJob file.encoding=GBK java.specification.version=1.3 user.name=Windows XP java.class.path=D:\MSE_JBuilder\PropertiesTest\classe... java.vm.specification.version=1.0 java.home=C:\JBuilder6\jdk1.3.1\jre user.language=zh java.specification.vendor=Sun Microsystems Inc. awt.toolkit=sun.awt.windows.WToolkit Chapter 6 I/O Stream
java.version=1.3.1 java.ext.dirs=C:\JBuilder6\jdk1.3.1\jre\lib\ext sun.boot.class.path=C:\JBuilder6\jdk1.3.1\jre\lib\rt.jar;... java.vendor=Sun Microsystems Inc. file.separator=\ java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport... sun.cpu.endian=little sun.io.unicode.encoding=UnicodeLittle user.region=CN sun.cpu.isalist=pentium i486 i386 Chapter 6 I/O Stream
6.2.3 集成原始方法 (native method) • 原始方法: 由其它程序语言实现的 Java 方法 Chapter 6 I/O Stream
从 C 语言中调用 JAVA 语言编写的代码 Chapter 6 I/O Stream