IO流
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
File
接触流之前,先了解一下File类
File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。
构造方法
File(String directoryPath)
File(String directoryPath, String filename)
File(File dirObj, String filename)
File(String directoryPath, String filename)
File(File dirObj, String filename)
例如:File file = new File("C:\\abc\\xyz\\hello\\abc.txt"); 注意路径
创建文件(夹)
boolean createNewFile();在指定路径创建文件,如果文件已经存在,则不创建,返回false.输出流对象一旦创建,如果文件存在,则会覆盖
boolean mkdir():创建一级文件夹
boolean mkdirs():创建多级文件夹
boolean mkdirs():创建多级文件夹
删除
boolean delete():删除失败返回假。如果文件正在使用,则删除不了返回false,只能删除没有儿子的
void deleteOnExit():程序退出时删除文件
void deleteOnExit():程序退出时删除文件
判断
isFile(); 是否是文件
isDirectory(); 是否是目录
isHidden(); 是否隐藏
isAbsolute();
isDirectory(); 是否是目录
isHidden(); 是否隐藏
isAbsolute();
获取信息
getName();
getPahth();//获取路径
getAbsoluteFile();//获取绝对路径封装成文件对象
getAbsolutPath();//获取绝对路径
getParent(); 返回此抽象路径名的父路径名的抽象路径名
lastModified();
length();
getParent();//该方法返回的是绝对路径中的父目录,如果获取的是相对路径,返回null.如果相对路径中有一级目录,那么该目录就是返回结果
renameto()
list() 这些字符串指定此抽象路径名表示的目录中的文件和目录。可以传过来策略
listFiles() 列出文件路径可以传过来策略
getPahth();//获取路径
getAbsoluteFile();//获取绝对路径封装成文件对象
getAbsolutPath();//获取绝对路径
getParent(); 返回此抽象路径名的父路径名的抽象路径名
lastModified();
length();
getParent();//该方法返回的是绝对路径中的父目录,如果获取的是相对路径,返回null.如果相对路径中有一级目录,那么该目录就是返回结果
renameto()
list() 这些字符串指定此抽象路径名表示的目录中的文件和目录。可以传过来策略
listFiles() 列出文件路径可以传过来策略
常见操作:递归删除
public static void deleteAll(File file){
if(file.isFile() || file.list().length == 0){
file.delete();
}
else{
File[] files = file.listFiles();
for(File f : files) {
deleteAll(f);
f.delete();
}
}
}
流
Java程序通过流来完成输入/输出。流是生产或消费信息的抽象,流通过Java的输入/输出系统与物理设备链接。
流的分类
1)从功能上分为两大类:输入流和输出流。
2)从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。
字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。
字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer
在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法。
3)按数据操作分节点流和过滤流
节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的,是对节点流的加工。
输出:节点流—>过滤流
输入:节点流<—过滤流
2)从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。
字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。
字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer
在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法。
3)按数据操作分节点流和过滤流
节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的,是对节点流的加工。
输出:节点流—>过滤流
输入:节点流<—过滤流
字节流
输入流:InputStream
1)InputStream中包含一套字节输入流需要的方法,可以完成最基本的从输入流读入数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的InputStream子类类型的对象来完成与该外设的连接,然后再调用执行这个流类对象的特定输入方法来实现对相应外设的输入操作。
2)层次
2)层次
节点流(和源交互) | 过滤流 | ||
FileInputStream | |||
ObjectInputStream | LineNumberInputStream | ||
InputStream | FilterInputStream | ---------> | DataInputStream |
PipedInputStream | BufferedInputStream | ||
SequenceInputStream | PushbackInputStream | ||
StringBufferInputStream |
3)基本方法
abstractint read():读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
int read(byte[]b):将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
int read(byte[] b, intoff, intlen) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。
void close():关闭输入流,释放和这个流相关的系统资源。
输出流:OutputStream
1)OutputStream是定义了流式字节输出模式的抽象类。2)层次
节点流(和源交互) | 过滤流 | ||
FileOutputStream | |||
ByteArrayOutputStream | PrintStream | ||
OutputStream | FilterOutputStream | ---------> | DataOutputStream |
ObjectOutputStream | BufferedOutputStream | ||
PipedOutputStream | PushbackInputStream | ||
3)基本方法
abstract void write(intb) :往输出流中写入一个字节。
void write(byte[]b) :往输出流中写入数组b中的所有字节。
void write(byte[]b, intoff, nt len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据
void flush() :刷新输出流,强制缓冲区中的输出字节被写出。
void close():关闭输出流,释放和这个流相关的系统资源(flush)。
字节流
1)FileInputStream和FileOutputStream节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。
FileInputStream 类创建一个能从文件读取字节的InputStream 类,它的两个常用的构造
方法如下
–FileInputStream(String filepath)
–FileInputStream(File fileObj)
例如:
FileInputStream 类创建一个能从文件读取字节的InputStream 类,它的两个常用的构造
方法如下
–FileInputStream(String filepath)
–FileInputStream(File fileObj)
例如:
InputStream is = new FileInputStream("c:/hello.txt");
byte[] buffer = new byte[200];
int length = 0;
while(-1 != (length = is.read(buffer, 0, 200))) {
String str = new String(buffer,0, length);
System.out.println(str);
}
is.close();
FileOutputStream 创建了一个可以向文件写入字节的类OutputStream,它常用的构造方法如下
FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
例如:
OutputStream os = new FileOutputStream("c:\\out.txt", true);
String str = "aaaaa";
byte[] buffer = str.getBytes();
os.write(buffer);
os.close();
2)BufferedInputStream和BufferedOutputStream过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率,减少频繁访问物理硬件,效率低。
OutputStream os = new FileOutputStream("1.txt");
BufferedOutputStream bos = new BufferedOutputStream(os);
bos.write("http://www.google.com".getBytes());
bos.close();
os.close();
3)ByteArrayInputStream与ByteArrayOutputStream
ByteArrayInputStream是把字节数组当成的输入流。该类有两个构造方法,每个造方法需要一个字节数组提供数据源
–ByteArrayInputStream(byte array[ ])
–ByteArrayInputStream(byte array[ ], intstartnumBytes)
String temp = "abc";
byte[] b = temp.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(b);
for(int i = 0; i < 2; i++){
int c;
while(-1 != (c = in.read())){
if(0 == i) {
System.out.println((char)c);
}else{
System.out.println(Character.toUpperCase((char)c));
}
}
System.out.println();
in.reset();
}
ByteArrayOutputStream是一个把字节数组当作输出流的实现。ByteArrayOutputStream有两个构造方法
–ByteArrayOutputStream( )
–ByteArrayOutputStream(intnumBytes)
–在第一种形式里,一个32位字节的缓冲区被生成。第二个构造方法生成一个numBytes大小的缓冲区。缓冲区保存在ByteArrayOutputStream的受保护的buf成员里。缓冲区的大小在需要的情况下会自动增加。缓冲区保存的字节数是由ByteArrayOutputStream的受保护的count域保存的
ByteArrayOutputStream f = new ByteArrayOutputStream();
String str = "hello world welcome";
byte[] buffer = str.getBytes();
f.write(buffer);
byte[] result = f.toByteArray();
for(int i = 0; i < result.length; i++){
System.out.println((char)result[i]);
}
OutputStream os = new FileOutputStream("test.txt");
f.writeTo(os);
f.close();
os.close();
4)DataInputStream和DataOutputStream过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。
使用数据文件流的一般步骤
–(1)建立字节文件流对象;
–(2)基于字节文件流对象建立数据文件流对象;
–(3)用流对象的方法对基本类型的数据进行输
入/输出。
如:
用,必须同时构造管道输入流和管道输出流。
使用数据文件流的一般步骤
–(1)建立字节文件流对象;
–(2)基于字节文件流对象建立数据文件流对象;
–(3)用流对象的方法对基本类型的数据进行输
入/输出。
如:
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data.txt")));
byte b = 3;
int i = 12;
char ch = 'a';
float f = 3.3f;
dos.writeByte(b);
dos.writeInt(i);
dos.writeChar(ch);
dos.writeFloat(f);
dos.close();
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("data.txt")));
//读和写的顺序要保持一致
System.out.println(dis.readByte());
System.out.println(dis.readInt());
System.out.println(dis.readChar());
System.out.println(dis.readFloat());
4)PipedInputStream和PipedOutputStream管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有
用,必须同时构造管道输入流和管道输出流。
过滤流
1)过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。
2)类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。
3)过滤流可以包装节点流,过滤流可在包装过滤流,进行功能丰富。
如:DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data.txt")));
输出二进制形式缓冲方式输出文件
2)类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类。
3)过滤流可以包装节点流,过滤流可在包装过滤流,进行功能丰富。
如:DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data.txt")));
输出二进制形式缓冲方式输出文件
字符流
尽管字节流提供了处理任何类型输入/输出操作的功能,它们不能直接操作Unicode字符。
既然Java的一个主要目的是支持“只写一次,到处运行”的哲学,包括直接的字符输入/输出支持是必要的。
由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。从Java1.1版开始,加入了专门处理字符流的抽象类Reader和Writer,前者用于处理输入,后者用于处理输出。这两个类类似于InputStream和OuputStream,也只是提供一些用于字符流的规定,本身不能用来生成对象。
Reader和Writer类也有较多的子类,与字节流类似,它们用来创建具体的字符流对象进行I/O操作。字符流的读写等方法与字节流的相应方法都很类似,但读写对象使用的是字符。
既然Java的一个主要目的是支持“只写一次,到处运行”的哲学,包括直接的字符输入/输出支持是必要的。
由于Java采用16位的Unicode字符,因此需要基于字符的输入/输出操作。从Java1.1版开始,加入了专门处理字符流的抽象类Reader和Writer,前者用于处理输入,后者用于处理输出。这两个类类似于InputStream和OuputStream,也只是提供一些用于字符流的规定,本身不能用来生成对象。
Reader和Writer类也有较多的子类,与字节流类似,它们用来创建具体的字符流对象进行I/O操作。字符流的读写等方法与字节流的相应方法都很类似,但读写对象使用的是字符。
字符流:Reader
1) Reader中包含一套字符输入流需要的方法,可以完成最基本的从输入流读入数据的功能。2) 层次
BufferedReader | ----------- | LineNumberReader | |
CharArrayReader | |||
Reader | FilterReader | ----------- | PushbackReader |
InputStreamReader | ----------- | FileReader | |
PipedReader | |||
StringReader |
字符流:Writer
1) Writer中包含一套字符输出流需要的方法,可以完成最基本的输出数据到输出流的功能。2) 层次
BufferedWriter | |||
CharArrayWriter | |||
FilterWriter | |||
Writer | OutputStreamWriter | ----------- | FileWriter |
PipedWriter | |||
PrintWriter | |||
StringWriter |
InputStreamReader和OutputStreamWriter
这是java.io包中用于处理字符流的基本类,用来在字节流和字符流之间搭一座“桥”。这里字节流的编码规范与具体的平台有关,可以在构造流对象时指定规范,也可以使用当前平台的缺省规范
主要构造:
public InputSteamReader(InputSteam in) 字节变字符
public InputSteamReader(InputSteam in,String enc)
public OutputStreamWriter(OutputStream out) 字符变字节
public OutputStreamWriter(OutputStream out,String enc)
其中in和out分别为输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示使用当前平台的缺省规范,可用getEncoding()方法得到当前字符流所用的编码方式)。
• 读写字符的方法read()、write(),关闭流的方法close()等与Reader和Writer类的
同名方法用法都是类似的。
主要构造:
public InputSteamReader(InputSteam in) 字节变字符
public InputSteamReader(InputSteam in,String enc)
public OutputStreamWriter(OutputStream out) 字符变字节
public OutputStreamWriter(OutputStream out,String enc)
其中in和out分别为输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示使用当前平台的缺省规范,可用getEncoding()方法得到当前字符流所用的编码方式)。
• 读写字符的方法read()、write(),关闭流的方法close()等与Reader和Writer类的
同名方法用法都是类似的。
public static void main(String[] args) throws Exception{
FileOutputStream fos = new FileOutputStream("file.txt"); //字节流
OutputStreamWriter osw = new OutputStreamWriter(fos); //字符流,桥梁
BufferedWriter bw = new BufferedWriter(osw);//过滤封装
bw.write("http://www.google.com");
bw.write("\n");
bw.write("http://www.baidu.com");
bw.close();
FileInputStream fis = new FileInputStream("file.txt");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
while(null != str){
System.out.println(str);
str = br.readLine();
}
br.close();
}
常见字符流操作
1)BufferedReader与BufferedWriter
BufferedReader 通过缓冲输入提高性能。它有两个构造方法
–BufferedReader(Reader inputStream)
–BufferedReader(Reader inputStream, int bufSize)
–第一种形式创建一个默认缓冲区长度的缓冲字符流。第二种形式,缓冲区长度由bufSize传入
例子:
BufferedWriter是一个增加了flush( )方法的Writer。flush( )方法可以用来确保数据缓冲区确实被写到实际的输出流。用BufferedWriter 可以通过减小数据被实际的写到输出流的次数而提高程序的性能。
BufferedWriter有两个构造方法:
–BufferedWriter(Writer outputStream)
–BufferedWriter(Writer outputStream, int bufSize)
–第一种形式创建了使用默认大小缓冲区的缓冲流。第二种形式中,缓冲区大小是由bufSize参数传入的
例子如上上
2)FileReader与FileWriter
FileReader类创建了一个可以读取文件内容的Reader类。FileReader继承于InputStreamReader。它最常用的构造方法显示如下
–FileReader(String filePath)
–FileReader(File fileObj)
例如:
–FileWriter(String filePath)
–FileWriter(String filePath, boolean
append)
–FileWriter(File fileObj)
–append :如果为 true,则将字节写入文件末尾处,而不是写入文件开始处
例如:
CharArrayReader 是一个把字符数组作为源的输入流的实现。该类有两个构造方法,每一个都需要一个字符数组提供数据源
–CharArrayReader(char array[ ])
–CharArrayReader(char array[ ], int start, int numChars)
例如:
–CharArrayWriter( )
–CharArrayWriter(int numChars)
–第一种形式,创建了一个默认长度的缓冲区。
–第二种形式,缓冲区长度由numChars指定。缓冲区保存在CharArrayWriter的buf 成员中。缓冲区大小在需要的情况下可以自动增长。
BufferedReader 通过缓冲输入提高性能。它有两个构造方法
–BufferedReader(Reader inputStream)
–BufferedReader(Reader inputStream, int bufSize)
–第一种形式创建一个默认缓冲区长度的缓冲字符流。第二种形式,缓冲区长度由bufSize传入
例子:
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String str;
while(null != (str = br.readLine())) {
System.out.println(str);
}
br.close();
BufferedWriter是一个增加了flush( )方法的Writer。flush( )方法可以用来确保数据缓冲区确实被写到实际的输出流。用BufferedWriter 可以通过减小数据被实际的写到输出流的次数而提高程序的性能。
BufferedWriter有两个构造方法:
–BufferedWriter(Writer outputStream)
–BufferedWriter(Writer outputStream, int bufSize)
–第一种形式创建了使用默认大小缓冲区的缓冲流。第二种形式中,缓冲区大小是由bufSize参数传入的
例子如上上
2)FileReader与FileWriter
FileReader类创建了一个可以读取文件内容的Reader类。FileReader继承于InputStreamReader。它最常用的构造方法显示如下
–FileReader(String filePath)
–FileReader(File fileObj)
例如:
FileReader fr = new FileReader("c:\\FileReader1.java");
BufferedReader br = new BufferedReader(fr);
String str;
while (null != (str = br.readLine())) {
System.out.println(str);
}
br.close();
FileWriter 创建一个可以写文件的Writer 类。 FileWriter继承于OutputStreamWriter.它最常用的构造方法如下:
–FileWriter(String filePath)
–FileWriter(String filePath, boolean
append)
–FileWriter(File fileObj)
–append :如果为 true,则将字节写入文件末尾处,而不是写入文件开始处
例如:
String str = "hello world welcome nihao hehe";
char[] buffer = new char[str.length()];
str.getChars(0, str.length(), buffer, 0);
FileWriter f = new FileWriter("file2.txt");
for(int i = 0; i < buffer.length; i++) {
f.write(buffer[i]);
}
f.close();
3)CharArrayReader与CharArrayWriter
CharArrayReader 是一个把字符数组作为源的输入流的实现。该类有两个构造方法,每一个都需要一个字符数组提供数据源
–CharArrayReader(char array[ ])
–CharArrayReader(char array[ ], int start, int numChars)
例如:
String tmp = "abcdefg";
char[] ch = new char[tmp.length()];
tmp.getChars(0, tmp.length(), ch, 0);
CharArrayReader input = new CharArrayReader(ch);
int i;
while(-1 != (i = input.read())) {
System.out.println((char)i);
}
CharArrayWriter 实现了以数组作为目标的输出流。CharArrayWriter 有两个构造方法
–CharArrayWriter( )
–CharArrayWriter(int numChars)
–第一种形式,创建了一个默认长度的缓冲区。
–第二种形式,缓冲区长度由numChars指定。缓冲区保存在CharArrayWriter的buf 成员中。缓冲区大小在需要的情况下可以自动增长。