IO流总结
File类:文件和目录路径名的抽象表示形式。
无论是抽象路径名还是路径名字符串,都可以是绝对路径名或相对路径名。
绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。相反,相对路径名必须使用取自其他路径名的信息进行解释。默认情况下,java.io 包中的类总是根据当前用户目录来解析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。
关于File实际用法:http://blog.csdn.net/qq_36330228/article/details/77856289
重点:文件过滤器FilenameFilter接口
用于抽象路径名的过滤器。
唯一方法:
boolean accept(File pathname)
测试指定抽象路径名是否应该包含在某个路径名列表中。
||| 建议使用匿名内部类方法来实现该接口
用法可参考:http://blog.csdn.net/qq_36330228/article/details/77856361
IO流分类:
输入流和输出流:输入流只能从中读取数据,而不能写入数据;输出流只能向其写入数据,而不能从中读取数据;
字节流和字符流:字节流操作的数据单元是8位的字节,而字符流操作的数据单元是16位的字符;
节点流和处理流:节点流可以从/向一个特定的IO设备读/写数据的流;处理流则用于对一个已存在的流进行连接或封装;
Java的IO流的40多个类是从4个抽象基类派生的。
InputStream /Reader:所有输入流的基类,它们把输入设备抽象成一个“水管”,水管里的每个“水滴”依次排列,输入流使用隐式的记录指针来表示当前正准备从哪个“水滴”开始读取,每当程序从输入流取出一个或多个水滴,记录指针自动向后移动;
OutputStream /Writer:所有输出流的基类,原理与输入流相同;
字节流:
FileInputStream**和**FileOutputStream
FileInputStream 从文件系统中的某个文件中获得输入字节。
FileOutputStream 用于写入诸如图像数据之类的原始字节的流。
package com.wql.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 字节流读取文件FileInputStream
* 字节流写入文件FileOutputStream
* @author wql
*
*/
public class FileStreamDemo {
public static void main(String[] args) throws FileNotFoundException,
IOException {
//相对路径:./src/com/wql/io/hello.txt,提前在该路径下建立hello.txt
try (FileInputStream fis = new FileInputStream(
"./src/com/wql/io/hello.txt");) {
byte[] buffer = new byte[1024];
int hasRead = 0;
System.out.println(fis.available());//返回字节数。
//read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
while ((hasRead = fis.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, hasRead));
}
fis.close();
}
try(FileOutputStream fos=new FileOutputStream("./src/com/wql/io/hello2.txt");){
String str="Hello IO";
byte[] b=str.getBytes(); //将字符串str转为字节数组
fos.write(b); //写入字节数组
fos.write(32); //写入指定字节
fos.flush(); //刷新
fos.close();
}
}
}
ByteArrayInputStream和ByteArrayOutputStream
ByteArrayInputStream和ByteArrayOutputStream是以字节数组为节点的节点流;
ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
ByteArrayOutputStream类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
package com.wql.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* @author wql
*
*/
public class ByteArrayStream {
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
byte[] buf = { 'A', 'B', 'C' };// 在内存缓冲中中写一个数组
try (ByteArrayInputStream bis = new ByteArrayInputStream(buf);
ByteArrayOutputStream bos = new ByteArrayOutputStream();) {
byte[] b = new byte[1024];
int hasRead;
while ((hasRead = bis.read(b)) != -1) {
System.out.println(new String(b, 0, hasRead));
}
bos.write(buf);// 写入一个字节数组
System.out.println(bos.toString());
System.out.println(bos.size());// 获取当前缓冲区大小
bos.flush();
bis.close();
bos.close();
}
}
}
DataInputStream和DataOutputStream特殊字节处理流
DataInputStream和DataOutputStream允许应用程序以与机器无关方式从底层输入流中读取或写入基本Java数据类型。
package com.wql.io;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*
* @author wql
*
*/
public class DataStream {
public static void main(String[] args) throws FileNotFoundException,
IOException {
// TODO 自动生成的方法存根
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("./data.txt"));
DataInputStream dis = new DataInputStream(new FileInputStream("./data.txt"));) {
dos.writeBoolean(true);//写一个布尔类型
dos.writeChar('A'); //写一个字符
dos.writeFloat(10.23f);//写一个float类型
dos.writeLong(500000L);//写一个long类型
//****************读出********************
byte[] buf=new byte[1024];
int hasRead=0;
while((hasRead=dis.read(buf))!=-1){
System.out.println(new String(buf,0,hasRead));
}
}
}
}
字符流
FileReader和FileWriter
字符流读取文件FileReader 字符流写入文件FileWriter
重点说下这个方法
write(byte[] b, int off, int len);是将数组 b 中的 len 个字节按顺序写入输出流。 所以如果 b 为 null,则抛出 NullPointerException。如果 off 为负,或 len 为负,又或者 off+len 大于数组 b 的长度, 则抛出 IndexOutOfBoundsException。如果 len 为零,则不写入字节。否则,首先写入字节b[off],然后写入字节 b[off+1], 依此类推;最后一个写入字节是 b[off+len-1].
package com.wql.io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderWriter {
public static void main(String[] args) throws FileNotFoundException,
IOException {
// TODO 自动生成的方法存根
try (FileReader fr = new FileReader("./src/com/wql/io/hello.txt");
FileWriter fw = new FileWriter(
"./src/com/wql/io/copy_hello.txt");) {
char[] buffer = new char[1024];
int hasRead = 0;
while ((hasRead = fr.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, hasRead));
fw.write(buffer);
fw.flush();
}
System.out.println(fw.getEncoding()); // 获取输出流当前编码
String str = "xyz";
fw.write(str, 0, 2);// 将str字符串里从off位置开始,长度为len的字符输出到指定输出流中;
fw.flush();
fr.close();
fw.close();
}
}
}
CharArrayReader和CharArrayWriter
CharArrayReader类实现一个可用作字符输入流的字符缓冲区。
CharArrayWriter类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用 toCharArray() 和 toString() 获取数据。
package com.wql.io;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.IOException;
/**
*
* @author wql
*
*/
public class CharReaderWirter {
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
char[] buf = { 'A', 'B', 'C' };// 在内存缓冲中写一个字符数组
try (CharArrayReader car = new CharArrayReader(buf);
CharArrayWriter caw = new CharArrayWriter();) {
char[] c = new char[1024];
int hasRead;
while ((hasRead = car.read(c)) != -1) {
System.out.println(new String(c, 0, hasRead));
}
caw.write(buf);// 写入一个数组
System.out.println(caw.toString());
String str = "DEF";
caw.write(str);// 写入一个字符串
System.out.println(caw.toString());
char ch = 'W';
caw.append(ch);// 将指定字符添加到此 writer
System.out.println(caw.toString());
caw.flush();
car.close();
caw.close();
}
}
}
StringReader和StringWriter
StringReader和StringWriter使用字符串作为物理节点,用户实现从字符串读取内容,或将内容写入字符串。
package com.wql.io;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
/**
*
* @author wql
*
*/
public class StringReaderWriter {
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
String str = "abcde\nsss";
try (StringReader sr = new StringReader(str);
StringWriter sw = new StringWriter();) {
char[] buf = new char[1024];
int hasRead = 0;
while ((hasRead = sr.read(buf)) != -1) {
System.out.println(new String(buf, 0, hasRead));
}
// *************输出操作**************
sw.write(str);
System.out.println(sw.toString());
sw.append('G');// 添加一个字符
System.out.println(sw.toString());
sw.flush();
sw.close();
sr.close();
}
}
}
BufferedReader和BufferedWriter
BufferedReader和BufferedWriter创建一个使用默认大小输入/输出缓冲区的缓冲字符输入/输出流;
BufferedReader 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
*BufferedWriter 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
package com.wql.io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 字符处理流,需要底层的字符节点流
*
* @author wql
*
*/
public class BufferReaderWriter {
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
// 读取当前文件BufferReaderWriter.java文件,然后写入到buffered.txt中
try (BufferedReader br = new BufferedReader(new FileReader(
"./src/com/wql/io/BufferReaderWriter.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter(
"./buffered.txt"));) {
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);// 在控制台打印下
bw.write(str);
bw.newLine();// 换行,不然会写在一行
bw.flush();// 刷新
}
bw.close();
br.close();
}
}
}
InputStreamReader和OutputStreamWriter
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器
EG:
OutputStream out = new FileOutputStream(“temp01.txt”);
Writer w = new OutputStreamWriter(out);
InputStream in = new FileInputStream(“temp01.txt”);
Reader r = new InputStreamReader(in);
重点说下节点流和处理流:
区别:节点流可以从/向一个特定的IO设备读/写数据的流;处理流则用于对一个已存在的流进行连接或封装;
处理流可以隐藏底层设备上节点流的差异,并对外提供更加方便的输入/输出方法,因此使用处理流是的思路是:使用处理流来包装节点流,程序通过处理流执行输入/输出功能,让节点流与底层的I/O设备、文件交互。