1、IO流 1,流的分类 按照流的流向划分: 输入流:只能从中读取数据,而不能向其写数据。输入流基类,InputStream和Reader。 输出流:只能向其写入数据,而不能从中读取数据。输出流基类,OutputStream和Writer。 按照操作数据单元划分: 字节流:操作最小数据单元是8位的字节。字节流基类,InputStream和OutputStream。 字符流:操作最小数据单元是16位字节。字符流基类,Reader和Writer。 2,Java IO体系 2.1 IO体系图 2.2 IO体系分类图 3,IO流抽象基类 3.1,输入流的抽象
2、基类:InputStream和Reader InputStream和Reader是所有输入流的基类,它们都是抽象类,本身不能创建实例来执行输入,但它们是所有输入流的模板,所有输入流都使用它们提供的方法。 在InputStream里包含如下三个方法: 》》int read():从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转换为int类型)。 》》int read(byte[] b):从输入流中读取最多b.length个字节的数据,并将其存储在字节数组b中,赶回实际读取的字节数。 》》int read(byte[] b,int off,int len):从输入流中
3、读取最多len字节的数据,并将其从off位置开始存储在数组b中,返回实际读取的字节数。 在Reader里包含如下三个方法: 》》int read():从输入流中读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)。 》》int read(char[] cbuf):从输入流中读取最多cbuf.length个字符的数据,并将其存储在字符数组cbuf中,赶回实际读取的字符数。 》》int read(char[] cbuf,int off,int len):从输入流中读取最多len字符的数据,并将其从off位置开始存储在数组cbuf中,返回实际读取的字符数。 3.2,输出
4、流的抽象基类:OutputStream和Writer OutputStream和Writer和前面的输入流相似,两个流都提供了如下三个方法: 》》void write(int c):将指定的字节/字符输出到输出流中,其中c代表字节或者字符。 》》void write(byte[]/char[] buf):将字节数组/字符数组中的数据输出到指定的输出流中。 》》void write(byte[]/char[] buf,int off,int len):将字节数组/字符数组中从off位置开始,长度为len的字节/字符输出到指定的输出流中。 因为字符流直接以字符作为操作单位
5、所以Writer可以用字符串来代替字符数组,即以String对象作为参数。Writer里还包含如下两个方法: 》》void write(String str):将字符串str里包含的字符输出到指定的输出流中。 》》void write(String str,int off,int len):将字符串str从off位置开始,长度为len的字符输出到指定输出流中。 4,IO流程序异常处理的标准方式 import java.io.*; class FileWriterDemo2 { public static void main(String[] args) {
6、FileWriter fw = null; try { fw = new FileWriter("c:\\demo.txt"); fw.write("abcde"); } catch (IOException e) { //异常处理方式 System.out.println(e.toString()); } finally { try { if(fw!=null) fw.close(); } catch (IOException e) { //异
7、常处理方式 System.out.println(e.toString()); } } } } 5,流与流之间相对应的关系 图5.1 字节输入流与输出流的对应关系 图5.2,字符输入流与输出流的对应关系 6,实现IO的子类 6.1,字符流 1,FileWriter 构造方法: FileWriter(String fileName):根据给定的文件名构造一个FileWriter对象。 FileWriter(String fileName, boolean append):根据给定的文件名以及指示是否附加写入数据的boolean值来构造
8、FileWriter对象。 常用方法: void close():关闭此流,但要先刷新它。 void flush():刷新该流的缓冲。 void write(char[] cbuf) :写入字符数组。 void write(char[] cbuf, int off, int len) :写入字符数组的某一部分。 void write(int c) :写入单个字符。 void write(String str) :写入字符串。 void write(String str, int off, int len) :写入字符串的某一部分。 2,FileReader
9、 构造方法: FileReader(String fileName):在给定从中读取数据的文件名的情况下创建一个新 FileReader。 常用方法: void close() :关闭该流并释放与之关联的所有资源。 int read() :读取单个字符。 int read(char[] cbuf) :将字符读入数组。 int read(char[] cbuf, int off, int len) :将字符读入数组的某一部分。 3,BufferedWriter 构造方法: BufferedWriter(Writer out):创建一个使用默认大小输出缓冲区的缓冲
10、字符输出流。 常用方法: void close():关闭此流,但要先刷新它。 void flush():刷新该流的缓冲。 void newLine():写入一个行分隔符,该方法具有跨平台性。 void write(char[] cbuf) :写入字符数组。 void write(char[] cbuf, int off, int len):写入字符数组的某一部分。 void write(int c):写入单个字符。 void write(String str) :写入字符串。 void write(String s, int off, int len):写入字符
11、串的某一部分。 4,BufferedReader 构造方法: BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流。 常用方法: void close():关闭该流并释放与之关联的所有资源。 int read():读取单个字符。 int read(char[] cbuf):将字符读入数组。 int read(char[] cbuf, int off, int len):将字符读入数组的某一部分。 String readLine():读取一个文本行。当读取到文件末尾时,返回null。 5,LineNumberR
12、eader:是BufferedReader的子类,带行号操作的类 构造方法: LineNumberReader(Reader in):使用默认输入缓冲区的大小创建新的行编号 reader。 常用方法: int getLineNumber():获得当前行号。 void mark(int readAheadLimit):标记该流中的当前位置。 int read():读取单个字符。 int read(char[] cbuf, int off, int len):将字符读入数组中的某一部分。 String readLine():读取文本行。 void setLineNum
13、ber(int lineNumber):设置当前行号。 void close():关闭流。 6,代码演示:复制纯文本文件 import java.io.*; public class CopyTextDemo { public static void main(String[] args) throws IOException { // copy_one(); // copy_two(); copy_three(); } // 使用字符缓冲流,提高效率 public static void copy_three() throws IOExcept
14、ion { BufferedReader bfr = new BufferedReader(new FileReader("c:\\demo.java")); BufferedWriter bfw = new BufferedWriter(new FileWriter("c:\\demo.txt")); String line = null; while ((line = bfr.readLine()) != null) { bfw.write(line); // 换行,因为readLine方法写入时,不包含换行符 bfw.newLine();
15、 bfw.flush(); } bfr.close(); bfw.close(); } // 使用字符数组进行缓冲,一次读取,一次写入,效率高 public static void copy_two() throws IOException { FileReader fr = new FileReader("c:\\demo.java"); FileWriter fw = new FileWriter("c:\\demo_copy.txt"); char[] buf = new char[1024]; int len = 0;
16、while ((len = fr.read(buf)) != -1) { fw.write(buf, 0, len); } fr.close(); fw.close(); } // 读一个字符,写一个字符,这种方法效率很低下 public static void copy_one() throws IOException { FileReader fr = new FileReader("c:\\demo.java"); FileWriter fw = new FileWriter("c:\\demo_copy.txt"); int
17、len = 0; while ((len = fr.read()) != -1) { fw.write((char) len); } fr.close(); fw.close(); } } ====================================================================== 6.2,字节流 1,FileOutputStream: 构造方法: FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。 FileOutputStream(
18、String name, boolean append):创建一个向具有指定 name 的文件中写入数据的输出文件流 常用方法: void close():关闭此文件输出流并释放与此流有关的所有系统资源。 void write(byte[] b):将 b.length 个字节从指定 byte 数组写入此文件输出流中。 void write(byte[] b, int off, int len):将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 void write(int b):将指定字节写入此文件输出流。 2,FileInputSt
19、ream: 构造方法: FileInputStream(String name):通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。 常用方法: int available():返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。 void close():关闭此文件输入流并释放与此流有关的所有系统资源。 int read():从此输入流中读取一个数据字节。 int read(byte[] b):从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
20、 int read(byte[] b, int off, int len):从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。 3,BufferedOutputStream: 构造方法: BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 常用方法: void close():关闭此输出流并释放与此流有关的所有系统资源。 void flush():刷新此缓冲的输出流。 void write(byte[] b, int off, int len):将指定 byte 数组
21、中从偏移量 off 开始的 len 个字节写入此缓冲的输出流。 void write(int b):将指定的字节写入此缓冲的输出流。 void write(byte[] b):将 b.length 个字节写入此输出流。 4,BufferedInputStream: 构造方法: BufferedInputStream(InputStream in):创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 常用方法: int available():返回可以从此输入流读取(或跳过)、且不受此输入流接下来的方法调用阻塞的估计字节数。
22、 void close():关闭此输入流并释放与该流关联的所有系统资源。 int read():从此输入流中读取下一个数据字节。 int read(byte[] b):从此输入流中将 byte.length 个字节的数据读入一个 byte 数组中。 int read(byte[] b, int off, int len):从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。 ====================================================================== 6.3,转换流 1,InputStreamR
23、eader:读取转换流。字节流通往字符流的桥梁。 常用方法:InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。 沿用java.io.Reader类中的方法,但是基本上只起桥梁作用,实际上该流最终会被缓冲区操作。BufferedReader。 2,OutputStreamWriter:写入转换流。字符流通往字节流的桥梁。 常用方法:OutputStreamWriter(OutputStream out):创建使用默认字符编码的 OutputStreamWriter。 沿用java.io.Wr
24、iter类中的方法,但是基本上只起桥梁作用,实际上最终被缓冲区操作。 3,演示代码 /* 需求1 在控制台录入信息,将录入的文字存入到文件 源:键盘 目的:文件 需求2 在控制台打印文件的内容 源:文件 目的:控制台 */ import java.io.*; class TransStreamDemo{ public static void main(String[] args) throws IOException { // readKeywordToFile(); readFileToConsole(); }
25、public static void readKeywordToFile() throws IOException { // 创建数据源 InputStream in = System.in; InputStreamReader isr = new InputStreamReader(in); BufferedReader bfr = new BufferedReader(isr); // 创建数据目的 FileOutputStream fos = new FileOutputStream("c:\\out.txt"); OutputStreamWri
26、ter osr = new OutputStreamWriter(fos); BufferedWriter bfw = new BufferedWriter(osr); // 操作 String line = null; while ((line = bfr.readLine()) != null) { if ("over".equals(line)) break; bfw.write(line.toUpperCase()); bfw.newLine(); bfw.flush(); } bfr.close();
27、 bfw.close(); } public static void readFileToConsole() throws IOException { // 数据源 FileInputStream fis = new FileInputStream("c:\\demo.java"); InputStreamReader isr = new InputStreamReader(fis); BufferedReader bfr = new BufferedReader(isr); // 数据目的 OutputStream out = System.out
28、 OutputStreamWriter osw = new OutputStreamWriter(out); BufferedWriter bfw = new BufferedWriter(osw); // 操作 String line = null; while ((line = bfr.readLine()) != null) { bfw.write(line); bfw.flush(); bfw.newLine(); } bfr.close(); bfw.close(); } } =============
29、 6.4,File类 属性: static String separator:与系统有关的默认名称分隔符 构造方法: File(File parent, String child):根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 File(String parent, String child):根据 pare
30、nt 路径名字符串和 child 路径名字符串创建一个新 File 实例。 一般方法: 1)创建 boolean createNewFile():在指定位置创建文件,如果文件已经存在,则不创建,返回false。 和输出流不一样,输出流对象一定创建文件,如果文件已存在,会覆盖旧文件。 boolean mkdir():创建单级目录。 boolean mkdirs():创建多级目录。 2)删除 boolean delete():删除此抽象路径名表示的文件或目录,若文件或目录不存在,返回false。 注意:当删除某个目录时,若目录里有文件存在,则不可删
31、除,返回false。 void deleteOnExit():在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。 3)判断 boolean exists():测试此抽象路径名表示的文件或目录是否存在。 boolean isDirectory():判断是否是目录。 boolean isFile():判断是否是文件。 注意:判断文件对象是否是文件或者目录时,必须先通过exists()方法判断该文件对象是否存在。 boolean isAbsolute():测试此抽象路径名是否为绝对路径名。 boolean isHidden():测试
32、此抽象路径名指定的文件是否是一个隐藏文件。 boolean canRead():判断File对象所对应的文件或者目录是否可读。 boolean canWrite():判断File对象所对应的文件或者目录是否可写。 4)获取信息 File getAbsoluteFile():返回此抽象路径名的绝对路径名形式。 String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。 File getCanonicalFile():返回此抽象路径名的规范形式。 String getCanonicalPath():返回此抽象路径名的规范路径名字符串。 l
33、ong getFreeSpace():返回此抽象路径名指定的分区中未分配的字节数。 String getName():返回由此抽象路径名表示的文件或目录的名称。 String getParent():返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。 File getParentFile():返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。 String getPath():将此抽象路径名转换为一个路径名字符串。 long getTotalSpace():返回此抽象路径名指定的分区大小。 long ge
34、tUsableSpace():返回此抽象路径名指定的分区上可用于此虚拟机的字节数。 long length():返回由此抽象路径名表示的文件的长度。 static File[] listRoots():列出可用的文件系统根。 String[] list():列出File对象所有的子文件和路径名,返回String数组。 String[] list(FilenameFilter filter):返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。 File[] listFiles():列出File对象所有的子文件和路径,返回File数组。
35、演示代码:
/*
将指定目录下的所有Java文件的绝对路径全部输出到文本文件中保存
方法:递归
用集合存储
*/
import java.util.*;
import java.io.*;
class JavaFileList {
public static void main(String[] args) throws IOException {
File file = new File("e:\\JavaStudy");
List
36、st);
File files = new File(file, "java.txt");
writeToFile(list, files.toString());
}
public static void fileToList(File file, List
37、dir[x], list);
else {
if (dir[x].getName().endsWith(".java"))
;
list.add(dir[x]);
}
}
}
public static void writeToFile(List
38、f : list) { String path = f.getAbsolutePath(); bfw.write(path); bfw.newLine(); bfw.flush(); } bfw.close(); } } ====================================================================== 6.5,Properties类 Properties是hashtable的子类。 它具备Map集合的特点,而且它里面存储的键值对都是字符串,是集合中和IO流技术相结合的集合容器。
39、 特点:可以用于键值对形式的配置文件。 常用方法: String getProperty(String key):用指定的键在此属性列表中搜索属性。 String getProperty(String key, String defaultValue):用指定的键在属性列表中搜索属性。 void list(PrintStream out):将属性列表输出到指定的输出流。 void list(PrintWriter out):将属性列表输出到指定的输出流。 void load(InputStream inStream):从输入流中读取属性列表(键和元素对)。 void
40、load(Reader reader):按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 Object setProperty(String key, String value):调用 Hashtable 的方法 put,设置键值对。 void store(OutputStream out, String comments)以适合使用 load(InputStream):方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 void store(Writer writer, String comments)
41、以适合使用 load(Reader):方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。
Set
42、intStream 构造方法: PrintStream(File file):创建具有指定文件且不带自动行刷新的新打印流。 PrintStream(File file, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新打印流。 PrintStream(OutputStream out):创建新的打印流。 PrintStream(OutputStream out, boolean autoFlush):创建新的打印流。 PrintStream(OutputStream out, boolean autoFlush, String encoding):创
43、建新的打印流。 PrintStream(String fileName):创建具有指定文件名称且不带自动行刷新的新打印流。 PrintStream(String fileName, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新打印流。 一般方法: void close():关闭流。 void flush():刷新该流的缓冲。 print方法:各种数据类型的打印方法。详情见jdk1.6 api println方法:各种数据类型的带换行的打印方法。详情见jdk1.6 api 注意: 由于PrintStream类的输出功能非常强大,通常
44、如果我们需要输出文本内容,都应该讲输出流包装成PrintStream后进行输出。 当使用处理流来包装底层节点流之后,关闭输入/输出流资源时,只要关闭最上层的处理流即可。关闭最上层的处理流,系统会自动 关闭被该处理流包装的节点流。对于下面介绍的PrintWrite类,同样适用。 2,PrintWriter 构造方法: PrintWriter(File file):使用指定文件创建不具有自动行刷新的新 PrintWriter。 PrintWriter(File file, String csn):创建具有指定文件和字符集且不带自动刷行新的新 PrintWriter。 Prin
45、tWriter(OutputStream out):根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。 PrintWriter(OutputStream out, boolean autoFlush):通过现有的 OutputStream 创建新的 PrintWriter。 PrintWriter(String fileName):创建具有指定文件名称且不带自动行刷新的新 PrintWriter。 PrintWriter(String fileName, String csn):创建具有指定文件名称和字符集且不带自动行刷新的新 PrintWrit
46、er。 PrintWriter(Writer out):创建不带自动行刷新的新 PrintWriter。 PrintWriter(Writer out, boolean autoFlush):创建新 PrintWriter。 一般方法: void close():关闭该流并释放与之关联的所有系统资源。 void flush():刷新该流的缓冲。 void write(char[] buf):写入字符数组。 void write(char[] buf, int off, int len):写入字符数组的某一部分。 void write(int c):写入单个字符。
47、 void write(String s):写入字符串。 void write(String s, int off, int len):写入字符串的某一部分 print方法:打印各种数据类型的方法。详情见jdk1.6 api println方法:带换行打印各种数据类型的方法。详情见jdk1.6 api ====================================================================== 6.7,对象序列化 对象序列化,也称作对象的持久化。是指将对象从堆内存中转移到硬盘的文件中保存,以方便下次程序运行直接取出来用,
48、 而不需要重新在内存中创建相同的对象。执行对象序列化需要用到两个功能流进行操作,ObjectOutputStream和ObjectInputStream。 1,ObjectOutputStream 构造方法: ObjectOutputStream(OutputStream out):创建写入指定 OutputStream 的 ObjectOutputStream。 常用方法: void close():关闭流。 void flush():刷新该流的缓冲。 void writeObject(Object obj):将指定的对象写入 ObjectOutputStream。 其它
49、写入各种数据类型的write方法,详情请查阅jdk1.6 api 2,ObjectInputStream 构造方法: ObjectInputStream(InputStream in):创建从指定 InputStream 读取的 ObjectInputStream。 常用方法: void close():关闭输入流。 Object readObject():从 ObjectInputStream 读取对象。 其它读取各种数据类型的read方法,详情请查阅jdk1.6 api 3,注意: (1)自定义序列号:public static final long seri
50、alVersionUID = 数值; (2)静态成员不能被序列化 (3)若想让非静态成员不被序列化,在非静态成员前加关键字 transient 声明。 ====================================================================== 6.8,RandomAccessFile 该类不算是IO体系中的子类,而是直接继承自Object。但是它是IO包中的成员,因为它具有读写功能。 内部封装了一个数组,而且通过指针对数组的元素进行操作。 可以通过getFilePointer获取指针的位置,同时可以通过seek改变指针的位置。
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818