第六章 i/o 流和系统类

Post on 20-Jan-2016

76 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

第六章 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 - PowerPoint PPT Presentation

TRANSCRIPT

Chapter 6 I/O Stream 1

第六章 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 2

6.1 Java 的输入 / 输出 stream • I/O stream 的基本概念

Chapter 6 I/O Stream 3

• 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 4

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 5

Chapter 6 I/O Stream 6

• 字节 stream 提供 8 bit 字节的 I/O• InputSteam / OutputStream 是字节 stream I/O 的抽

象类 , 提供字节 stream I/O 的公共 API

Chapter 6 I/O Stream 7

Chapter 6 I/O Stream 8

• 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 9

• 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 10

• 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 11

– 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 12

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 13

例 :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 14

例 : 利用 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 15

2. 管道流 , pipe streams• pipe streams 可将一个线程 (Thread) 的输出送到另一个线程的输入 ,

不需要另外的中间文件或缓冲区

Chapter 6 I/O Stream 16

Chapter 6 I/O Stream 17

例 (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 18

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 19

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 20

3. 存储器读写• Java 提供了 ByteArrayInputStream, 和

ByteArrayOutputStream 用来将数据写入一个在 ByteArrayOutputStream 内部的存储器区域 , 或将数据从一个 ByteArrayInputStream 内部的存储器区域读出

• 访问 ByteArrayInputStream, 和 ByteArrayOutputStream 的方法和访问其它 stream 的方法一样

• StringReader 和 StringWriter 提供类似的功能 , 只不过数据是写入一个字符串 , 或从一个字符串中读出

4. 用 Stream 来连接文件• SequenceInputStream 支持用一个 Stream 从多个输入源连续

读取数据

Chapter 6 I/O Stream 21

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 22

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 23

例 :BufferedReader d =

new BufferedReader(new DataInputStream(System.in));String input; while ((input = d.readLine()) != null) { ... //do something interesting here}

Chapter 6 I/O Stream 24

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 25

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 26

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 27

2. 用户自己建立新的过滤流• 用户自己建立过滤流的步骤

– 创建一个 FilterInputStream 和 FilterOutputStream 的子类– 置换 read() 和 write() 方法– 置换所需的其它方法– 确保输入流和输出流一起工作

Chapter 6 I/O Stream 28

• 用户自己建立过滤流的例子– 例子中用到了四个类和一个接口 ( 除了主类 , 都已在 JAVA

类库中 )• CheckedOutputStream / CheckedInputStream

• Checksum interface

• Adler32 class (calculate CRC-32)

• CheckedIODemo ()

(1) CheckedOutputStream• 构造函数public CheckedOutputStream(OutputStream out, Checksum cksum) {

super(out);

this.cksum = cksum;

}

Chapter 6 I/O Stream 29

• 在 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 30

(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 31

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 demoimport java.util.zip.*;public class CheckedIODemo {

Chapter 6 I/O Stream 32

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 33

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 34

• 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 35

• RandomAccessFile 支持的典型读操作– read(int i)

– read(byte b[ ])

– read(byte b[ ], int offset, int length)

• RandomAccessFile 支持的其余读写操作请见 JDK 文档资料6.2 系统类• Java 用系统类提供独立于系统具体实现的统一系统服务接口

Chapter 6 I/O Stream 36

• 系统类 (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 37

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 38

例 (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 39

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 40

Chapter 6 I/O Stream 41

1. 系统属性的获取– 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

2. 系统属性的设置• 可通过 System.setProperties() 修改当前的系统属性

Chapter 6 I/O Stream 42

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 43

-- 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 44

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 45

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 46

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 47

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 48

6.2.3 集成原始方法 (native method)• 原始方法 : 由其它程序语言实现的 Java 方法

Chapter 6 I/O Stream 49

• 从 C 语言中调用 JAVA 语言编写的代码

Chapter 6 I/O Stream 50

Chapter 6 I/O Stream 51

Chapter 6 I/O Stream 52

The Circumstance to Use JNI1. The standard Java class library may not support the

platform-dependent features needed by your application2. You may already have a library or application written in

another programming language and you wish to make it accessible to Java applications

3. You may want to implement a small portion of time-critical code in a lower-level programming language, such as assembly, and then have your Java application call these functions.

“The JNI is for programmers who must take advantage of platform-specific functionality outside of the Java Virtual Machine. Because of this, it is recommended that only experienced programmers should attempt to write native methods or use the Invocation API! “

Chapter 6 I/O Stream 53

6.2.4 其它系统方法1. 获取系统时间• System.currentTimeMIlis(); // return long (64 bits)

– Returns the current time in milliseconds (the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC)

2. 数组拷贝• public static void arraycopy(Object src, int src_position, Object dst,

int dst_position, int length)

Chapter 6 I/O Stream 54

public class ArrayCopyDemo { // JB demo

public static void main(String[] args) {

char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'a', 't', 'e', 'd' };

char[] copyTo = new char[7];

System.arraycopy(copyFrom, 2, copyTo, 0, 7);

System.out.println(new String(copyTo));

}

}

Chapter 6 I/O Stream 55

3. 退出运行系统• void exit(int status)• 退出 Java 解释器 , • 用户可传递一个整型的退出代码给 exit() 方法 , 用以说明退出

原因• System.exit(n); // n for the reason to exit, non zero means

error

第六章作业 :1. What class would you use to read a few pieces of data that

are at known positions near the end of a large file?

2. Implement a pair of classes, one Reader and one Writer, that count the number of times a particular character, such as e, is read or written. The character can be specified when the stream is created. Write a program to test your classes. You can use the text of this question as the content of the input file

top related