You are on page 1of 48

Java 语言程序设计

1
第九章 文件输入输出
 概念
 Java I/O 类
 Java I/O 操作
 标准输入 / 输出
 文件读写操作
 目录管理
 随机访问文件
 文件属性

2
概念
 I/O 来源
 控制台 (console, 如 DOS 窗口 ) 打印 / 读

 文件 (file) 读 / 写
 网络接口 (TCP/UDP 端口 ) 读 / 写
 针对数据的读写
 以流 (stream) 的方式对数据进行操作
流 读出
数据源 数据 程序 流的重要特性
顺序读 / 写
写入 流 sequentially
程序 数据 目的

3
概念
 读 / 写流的一般流程
 读 (Reading)
 open a stream // 打开读出流
 while more information // 判断
 read information // 读
 close the stream // 关闭流
 写 (Writing)
 open a stream // 打开写入流
 while more information // 判断
 write information // 写
 close the stream // 关闭流
4
概念
 两种流的定义 ( 读取信息的基本数据单位 )
 字节流 (byte stream): 一个字节 (8-bit) 一
个字节读 / 写
 字符流 (character stream): 一个字符一个字
符读 / 写 ( 具有特定字符编码的数据 )

j a v a 语 言
6A 61 76 61 D3 EF D1 D4

以字节流的方式读 : 读 8 次, 8 个字节
以字符流的方式读 : 读 6 次, 6 个字符
5
第九章 文件输入输出
 概念
 Java I/O 类
 Java I/O 操作
 标准输入 / 输出
 文件读写操作
 目录管理
 随机访问文件
 文件属性

6
Java I/O 类
 字节流的读 / 写操作 ( 来自 JDK1.0)
 java.io.InputStream ( 抽象类 )
1. public abstract int read()
2. public int read(byte b[])
3. public int read(byte b[], int offset, int length)
4. 到达流的终点,无数据读出则返回 -1
 java.io.OutputStream ( 抽象类 )
 public abstract void write(int b)
 public void write(byte b[])
 public void write(byte b[], int offset, int
length)
 所有的读 / 写函数都抛出 7
Java I/O 类
 字符流的读 / 写操作 ( 来自 JDK1.1)
 java.io.Reader ( 抽象类 )
 public int read()
 public int read(char cbuf[])
 publc abstract int read(char cbuf[], int offset,
int length)
 到达流的终点,无数据读出则返回 -1
 java.io.Writer ( 抽象类 )
1. public void write(int c)
2. public void write(char cbuf[])
3. public void write(char cbuf[], int offset, int
length)
 所有的读 / 写函数都抛出
java.io.IOException 8
Java I/O 类
 I/O 流的层次关系
 class java.io.InputStream 的子类
 class java.io.ByteArrayInputStream
 class java.io.FileInputStream
 class java.io.FilterInputStream
 class java.io.BufferedInputStream
 class java.io.DataInputStream
 class java.io.LineNumberInputStream
 class java.io.PushbackInputStream
 class java.io.ObjectInputStream
 class java.io.PipedInputStream
 class java.io.SequenceInputStream
 class java.io.StringBufferInputStream
 ……… 9
Java I/O 类
 I/O 流的层次关系
 class java.io.OutputStream 的子类
 class java.io.ByteArrayOutputStream
 class java.io.FileOutputStream
 class java.io.FilterOutputStream
 class java.io.BufferedOutputStream
 class java.io.DataOutputStream
 class java.io.PrintStream
 class java.io.ObjectOutputStream
 class java.io.PipedOutputStream
 ………

10
Java I/O 类
 I/O 流的层次关系
 class java.io.Reader 的子类
 class java.io.BufferedReader
 class java.io.LineNumberReader
 class java.io.CharArrayReader
 class java.io.FilterReader
 class java.io.PushbackReader
 class java.io.InputStreamReader
 class java.io.FileReader
 class java.io.PipedReader
 class java.io.StringReader
 ………
11
Java I/O 类
 I/O 流的层次关系
 class java.io.Writer 的子类
 class java.io.BufferedWriter
 class java.io.CharArrayWriter
 class java.io.FilterWriter
 class java.io.OutputStreamWriter
 class java.io.FileWriter
 class java.io.PipedWriter
 class java.io.PrintWriter
 class java.io.StringWriter
 ………

12
Java I/O 类
 I/O 流的分类 (12 个功能类 )
I/O 类 所用到的类 描述

文件 FileReader/FileWriter 文件流 ( 读 / 写文件 )
FileInputStream/FileOutputStream
缓冲 BufferedReader/BufferedWriter 提高读 / 写效率
BufferedInputStream
BufferedOutputStream
打印 PrintWriter PrintStream
(System.out.println())
内存 CharArrayReader/CharArrayWriter 读 / 写内存
ByteArrayInputStream
ByteArrayOutputStream
StringReader/StringWriter
StringBufferInputStream
13
Java I/O 类
 I/O 流的分类 (12 个功能类 )
I/O 类型 所用到的类 描述
字 流和字符 InputStreamReader 将 InputStream 中读入
流的 OutputStreamWriter 的字 为字符 / 将字
符 为字 写入
OutputStream
管道 PipedReader/PipedWriter 文件流 ( 读 / 写文件 )
pipe PipedInputStream/PipedOutputStream
连接 SequenceInputStream 多个输入流连接为一个
Concatenation 输入流
对象串行化 ObjectInputStream Object Serialization
ObjectOutputStream

14
Java I/O 类
 I/O 流的分类 (12 个功能类 )
I/O 类型 所用到的类 描述
基本数据转化 DataInputStream JAVA 基本数据类型的
DataOutputStream 读/写
计数 LineNumberReader 读操作时记录行数
LineNumberInputStream
Peeking PushbackReader 可回退缓存
Ahead PushbackInputStream (pushback buffer)
过滤 FilterReader/FilterWriter 在读 / 写操作时对数据
FilterInputStream/FilterOutputStream 进行过滤

15
第九章 文件输入输出
 概念
 Java I/O 类
 Java I/O 操作
 标准输入 / 输出
 文件读写操作
 目录管理
 随机访问文件
 文件属性

16
Java I/O 操作
 主要内容
1. 标准输入 / 输出
 控制台屏幕打印和键盘读入
2. 文件 I/O 操作
 文件读写
 如何提高文件读写效率
 流的包装 (Wrap)
 基本数据转换流
 目录管理
 随机访问文件 (Random Access File)
 文件属性
3. 网络流操作 ( 见第十三讲 )
17
标准输入 / 输出
 输出 : 控制台屏幕打印

class Test {
public static void main(String args[]) {
System.out.println(“Hello World!”);
}
}

18
C:\>java Test
标准输入 / 输出 A
Received number=3
 输入 : 键盘读入
C:\>
import java.io.IOException;
class Test {
public static void main(String args[]) throws
IOException {
byte[] b = new byte[10];
System.out.println("Received number="
+
System.in.read(b));
}
} 19
文件读写操作
 文件读 / 写流程
1. 打开文件流
2. 条件判断
3. 读出 / 写入
4. 关闭文件流
 两种类型文件
 FileInputStream/FileOutputStream ( 字节流 )
 FileReader/FileWriter ( 字符流 )

20
文件读写操作
1. 字节流构造方法
 public FileInputStream(File file) throws
FileNotFoundException
 public FileInputStream(String name) throws
FileNotFoundException

 public File(String pathname)

 public FileOutputStream(File file) throws


FileNotFoundException
 public FileOutputStream(File file, boolean append) throws
FileNotFoundException // 是否向已存在的文件后添加
 public FileOutputStream(String name) throws
FileNotFoundException
 public FileOutputStream(String name, boolean append)
throws FileNotFoundException
21
public int read
public
()throws
voidIOException
write (int b) throws IOException
文件读写操作
public int read
public
(byte[]
void
b) write
throws(byte[]
IOException
b) throws IOException
public int read
public
(byte[]
void
b, write
int off,
(byte[]
int len)
b, throws
int off, IOException
int len) throws IOExceptio
文件读写 - 实例
 FileInputStream in =1
new
FileInputStream(“original.txt");
FileOutputStream out = new
import java.io.*;
FileOutputStream(“result.txt");
public class CopyBytes {
public static void main(String[] args) throws
IOException {
File inputFile = new File(“original.txt");
File outputFile = new File(“result.txt");
FileInputStream in = new
FileInputStream(inputFile);
FileOutputStream out = new
FileOutputStream(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
22
out.close();
文件读写操作
1. 字符流构造方法
 public FileReader(File file) throws
FileNotFoundException
 public FileReader(String fileName) throws
FileNotFoundException

 public File(String pathname)

 public FileWriter(File file) throws IOException


 public FileWriter(File file, boolean append) throws
IOException
 public FileWriter(String fileName) throws
IOException
 public FileWriter(String fileName, boolean append)
throws IOException
23
blic int read
public
() throws
void IOException
write (int b) throws IOException
文件读写操作
blic int read
public
(char[]
void
cbuf)
write
throws
(char[]IOException
cbuf) throws IOException
blic int read
public
(char[]
void
cbuf,
write
int(char[]
off, intcbuf,
len) throws
int off, IOException
int len) throws IOExcept
文件读写in -=实例
 FileReader 2
new FileReader(“original.txt");
FileWriter out = new FileWriter(“result.txt");
import java.io.*;
public class Copy {
public static void main(String[] args) throws
IOException {
File inputFile = new File(“original.txt");
File outputFile = new File(“result.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();
} 24
如何提高文件读写效率
 两类缓冲流
 针对字节流
 java.io.BufferedInputStream 类
 java.io.BufferedOutputStream 类
 针对字符流
 java.io.BufferedReader 类
 java.io.BufferedWriter 类

25
如何提高文件读写效率
 构造方法
 public BufferedInputStream(InputStream in)
2048 bytes
 public BufferedInputStream(InputStream in, int
size)
 public BufferedOutputStream(OutputStream out)
512 bytes
 public BufferedOutputStream(OutputStream out,
int size)

 public BufferedReader(Reader in) 8192 bytes


 public BufferedReader(Reader in, int sz)
 public BufferedWriter(Writer out) 8192 byte
 public BufferedWriter(Writer out, int sz)
26
如何提高文件读写效率
 如何提高文件读写效率 - 实例 1
String
StringFileInputStream
filename
filename fis ==new
= “test.txt”;
“test.txt”;
FileInputStream(“test.txt”);
FileInputStream
FileInputStream fisfis == new
new
FileInputStream(filename);
FileInputStream(filename);
int count = 0;
intBufferedInputStream
countint=BUFSIZE
final 0; = 1024;
bis = new
int BufferedInputStream(fis);
c;
byte buf[] = new byte[BUFSIZE];
intintcount
while ((c
len; = 0;
= fis.read()) != -1) {
int c; ==((len
ifwhile
(c 'A') =
{ fis.read(buf)) != -1) {
while ((c(int
count++;
for = bis.read())
i = 0; i < len;!= -1)
i++){{
} if (c if == 'A') {== 'A') {
(buf[i]
} count++;
count++;
fis.close();
} }
System.out.println(count);
} }
fis.close();
}
System.out.println(count);
fis.close();
27
如何提高文件读写效率
 如何提高文件读写效率 - 实例 2

String filename = “test.txt”;


FileReader fr = new
FileReader(filename);
BufferedReader br = new
BufferedReader(fr);
int count = 0;
while (br.readLine() != null) {
count++;
}
br.close();
System.out.println(count);
28
流的包装 (wrap)
 概述
FileReader fr = new FileReader (filename);
BufferedReader br = new BufferedReader (fr);
BufferedReader br = new BufferedReader (
new
FileReader(filename));
PrintWriter out = new PrintWriter (
new BufferedWriter(new
FileWriter(filename)));
public String readLine() in
java.io.BufferedReader
public void println(String x) in java.io.PrintWriter
 利用不同流的特点 ( 方法 )
 寻找合适的方法完成特定的需求
 对已有的流进行再处理
29
流的包装 (wrap)
 流的种类
 节点流
 直接对数据源进行读 / 写操作的流
 处理流
 对一个已有的流进行某种操作的流

30
流的包装 (wrap)
 节点流
 FileInputStream, PipedInputStream,
ByteArrayInputStream,
StringBufferInputStream
 FileOutputStream, PipedOutputStream,
ByteArrayOutputStream
 CharArrayReader, FileReader, PipedReader,
StringReader
 CharArrayWriter, FileWriter, PipedWriter,
StringWriter

31
流的包装 (wrap)
 处理流
 FilterOutputStream, DataOutputStream,
BufferedOutputStream, PrintStream
 FilterInputStream,
LineNumberInputStream,
DataInputStream, BufferedInputStream,
PushbackInputStream
 BufferedReader, LineNumberReader,
InputStreamReader, FilterReader,
PushBackReader
 BufferedWriter, OutputStreamReader,
FilterWriter, PrintWriter
32
流的包装 (wrap)
 一个实例
 java.io.FileReader
 public FileReader(File file) throws
FileNotFoundException
 public FileReader(String fileName) throws
FileNotFoundException
 java.io.BufferedReader
 public BufferedReader(Reader in) 8192 bytes
 public BufferedReader(Reader in, int sz)
 流的包装 改变了流的行为

33
流的包装 (wrap)
流的包装 ((wrap)-
 程序如何结束 实例
跳出 while 循环 1
)?
public static final InputStream in
(java.lang.System)
public InputStreamReader(InputStream in)
public BufferedReader(Reader in)
import java.io.*;
public class Echo {
public static void main(String[] args) throws
IOException {
BufferedReader in = new BufferedReader(
new
InputStreamReader(System.in));
String s;
while((s = in.readLine()).length() != 0)
System.out.println(s);
} 34
基本数据转换流
 概述
 java.io.DataInputStream 类
 public DataInputStream(InputStream in)
 public final boolean readBoolean()
 public final byte readByte()
 public final char readChar()
 public final int readInt()
 java.io.DataOutputStream 类
 public DataOutputStream(OutputStream out)
 public final void writeBoolean(boolean v)
 public final void writeByte(int v)
 public final void writeChar(int v)
 public final void writeInt(int v)
35
19.99 12 Java T-
DataInputStream in = new DataInputStream( shirt
基本数据转换流 new
FileInputStream("invoice1.txt"));
9.99 8 Java Mug

基本数据转换流 - 实例
 double total;
try {
while (true) {
double price
DataOutputStream out =
= in.readDouble();
new DataOutputStream(new
in.readChar();
FileOutputStream("invoice1.txt"));
int unit = in.readInt();
double prices[] = {19.99, 9.99};
in.readChar();
int units[]=char
{12,chr;
8};
String descs[] = {"Java desc
StringBuffer T-shirt", "Java
= new Mug"};
StringBuffer(20);
for (int i =while
0; i <((chr
prices.length; i ++) { ‘\n’)
= in.readChar())!=
out.writeDouble(prices[i]);
desc.append(chr);
out.writeChar('\t');
System.out.println("You've ordered " + unit + "
out.writeInt(units[i]);
units
out.writeChar('\t');
of " + desc + " at $" + price);
out.writeChars(descs[i]);
total = total + unit * price;
out.writeChar('\n');
}
} } catch (EOFException e) { } 36
目录管理
 概述
 java.io.File 类 : 文件和目录的路径名
 构造方法
 public File(String pathname)
 public File(String parent, String child)
 public File(File parent, String child)
 parent 通常表示一个目录, child 则表示一个目录或文件
 路径名 (pathname)
 UNIX 平台上绝对路径的前缀“ /” ,相对路径无前缀,
例“ /etc/inetd.conf” 、“ inetd.conf”
 Windows 平台,绝对路径名的前缀由“盘符 :\” 组成; UNC
路径名前缀为“ \\” ,然后是主机名和共享名,相对路径名无
盘符,例“ c:\windows\notepad.exe” 、“ notepad.exe”

37
目录管理
 方法
 public boolean canWrite()/canRead()
 public boolean exists()
 public boolean delete() 删除文件或目录,若删除目录
,要求该目录必须为空
 public boolean createNewFile() 创建一个空文件,当
且仅当该文件不存在
 public boolean isDirectory()/isFile()/isHidden()
 public long lastModified()/public boolean
setLastModified(long time)
 public String[] list() 得到当前目录下的所有文件名和
目录名,若该 File 对象不是表示目录,则返回 null
 public boolean mkdir()/mkdirs() 创建一个目录
 public boolean renameTo(File dest)
 public boolean setReadOnly()
38
目录管理
 目录管理—方法举例

import java.io.File;
public class DirList {
public static void main(String[] args) {
File path = new File(".");
String[] list = path.list();
for(int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
}

39
class DirFilter implements FilenameFilter {
String key;
目录管理
DirFilter(String key) { this.key = key; }
public boolean accept(File dir, String
name)
 { 目录管理—方法举例
String f = new
File(name).getName();
java.util.FilenameFilter 接口
return f.indexOf(key) != -1;
public boolean accept(File dir, String
}
import java.io.File; name);
} // public
是否指定的文件 应包含在文件列表中
import java.io.FilenameFilter; String getName() in
public class DirList { java.io.File
// 获得文件或目录名,仅仅是最后的部分
public static void main(String[] args) {
File path = new File(".");
String[] list = path.list(new
DirFilter(args[0]));
for (int i = 0; i < list.length; i++)
System.out.println(list[i]);
} 40
随机访问文件
 随机访问文件 (Random Access File)
 java.io.RandomAccessFile 类
 读写操作在同一个类中完成,须在构造对象时指定
参数
 通过移动文件指针 (file pointer) 在文件的指定位置
进行读写操作
 构造方法
 public RandomAccessFile(String name, String
mode) throws FileNotFoundException
 public RandomAccessFile(File file, String mode)
throws FileNotFoundException
 mode: “r”, “rw”
41
随机访问文件
 方法
 public void seek(long pos)
 public int read()
 public int read(byte[] b)
 public int read(byte[] b, int off, int len)
 public final boolean
readBoolean()/readByte()/readChar()/readShort()/
readInt()/readDouble()/readFloat()
 public final String readLine()
 public void write(int b)
 public void write(byte[] b)
 public void write(byte[] b, int off, int len)
 public final void
writeBoolean()/writeByte()/writeChar()/writeShor
t()/writeInt()/writeDouble()/writeFloat()
42
运行结果 :
随机访问文件 Value 0: 0.0
Value 1: 1.414
 随机访问文件 (Random Value 2: 2.828
Access
Value 3: 4.242
File)- 实例
Value 4: 5.656
RandomAccessFile rf = new Value 5: 47.0001
RandomAccessFile("rtest.dat", "rw");
Value 6: 8.484
for(int i = 0; i < 10; i++)
Value 7: 9.898
rf.writeDouble(i*1.414);
Value 8: 11.312
rf.close();
Value 9: 12.72599999999999
rf = new RandomAccessFile("rtest.dat", "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();
rf = new RandomAccessFile("rtest.dat", "r");
for(int i = 0; i < 10; i++)
System.out.println("Value " + i + ": " +
rf.readDouble());
43
rf.close();
文件属性
 文件的特性
 读和写的权限
 文件长度
 修改时间
 是否是目录
 java.io.File 类
 设定文件属性
 查询文件属性

44
文件属性
 获取文件路径
import java.io.*;
class AttrDemo1 {
public static void main(String[] args) throws IOException {
File testfile = new File("." + File.separatorChar +
"testfile1");
testfile.createNewFile();
System.out.println("name = " + testfile.getName());
System.out.println("path = " + testfile.getPath());
System.out.println("absolute path = " +
testfile.getAbsolutePath());
System.out.println("canonical path = " +
testfile.getCanonicalPath());
}
} 45
文件属性
 获取文件修改时间
import java.io.*; import java.util.*;
public class AttrDemo2 {
public static void main(String[] args) throws IOException {
File testfile = new File("testfile2");
testfile.delete();
testfile.createNewFile();
long modtime = testfile.lastModified();
System.out.println("last modification time #1 = " + new
Date(modtime));
testfile.setLastModified(0);
modtime = testfile.lastModified();
System.out.println("last modification time #2 = " + new
Date(modtime));
46
}
文件属性
 获取和设定文件长度
import java.io.*;
public class AttrDemo3 {
public static void main(String[] args) throws IOException {
File testfile = new File("testfile3");
testfile.delete();
testfile.createNewFile();
System.out.println("length #1 = " +testfile.length());
RandomAccessFile raf = new
RandomAccessFile("testfile3", "rw");
raf.setLength(100);
raf.close();
System.out.println("length #2 = " + testfile.length());
}
47
文件属性
 设置读写权限
import java.io.*;
public class AttrDemo4 {
public static void main(String[] args) throws IOException {
File testfile = new File("testfile4");
testfile.delete();
testfile.createNewFile();
if (testfile.canRead()) System.out.println("file can be read
#1");
if (testfile.canWrite()) System.out.println("file can be
written #1");
testfile.setReadOnly();
if (testfile.canRead()) System.out.println("file can be read
#2");
if (testfile.canWrite()) System.out.println( "file can be 48