IO流
0 ,文件File
- 可以把文件File的对象理解成一个句柄,用这个抽象的句柄来操作实际文件
- 文件对象句柄的创建
File file = new File("c:\\a.txt");
File file2 = new File("c:\\heihei", b.txt)
这样就创建了一个句柄,它能操作C盘下a.txt这个文件(文件事先不存在也是可以创建的)
File类中常用方法 | 说明 |
---|
boolean createNewFile() | 文件路径正确且事先不存在则返回true,否则false |
boolean delete() | 文件则删除成功返回true,是目录则需要保证是空目录 |
boolean exists() | 判断文件 / 目录是否存在,存在返回true,否则false |
String getAbsolutePath() | 获得文件 / 目录的绝对路径 |
String getName() | 得到文件 / 目录名 |
String getParent() | 获得文件 / 目录所在目录路径 |
boolean isDirectory() | 顾名思义 |
boolean isFile() | 顾名思义, too |
long length() | 返回文件 / 目录下字节数(即多少B) |
String[] list() | 返回当前目录句柄下所有文件/目录路径的数组,句柄是文件会报错 |
File[] listFiles() | 返回当前目录句柄下所有文件/目录的句柄的数组,句柄是文件会报错 |
File[] listFiles(FileFilter filter) | 同上,但是事先会按照文件过滤器来过滤一下 |
boolean renameTo(File dest) | 将本句柄移动到destination文件句柄所指的文件路径下,成功会本句柄将会被删除 |
0.1 ,文件过滤器FIleFilter
- 文件过滤器是一个接口,实现它的子类需要重写accpt方法,按照此方法中的规则过滤。看一个Demo。
package day16;
import java.io.File;
import java.io.FileFilter;
public class Demo {
public static void main(String[] args) {
File file = new File("C:\\");
listFiles(file);
}
public static void listFiles(File file){
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.getName().endsWith(".avi") || pathname.isDirectory()){
return true;
}
return false;
}
});
if(files != null && files.length > 0){
for(File f: files){
if(f.isDirectory())
listFiles(f);
else
System.out.println("发现一个avi: " + f.getAbsolutePath());
}
}
}
}
- 使用内部匿名类的方法创建FileFilter的实例,句柄里的每个元素都要过一遍这个过滤器,符合条件的将会存在files[]数组里。
2 ,IO流概述
- 可以将IO流理解为数据的流动,比如在一个java文件中,读入java文件的数据就是Input,而从java文件产生,从java文件写出至他处的,就是Output。
- Java中的IO操作主要指java.io包下的一些常用类的使用,通过对这些常用类对数据进行读取(Input)和写出(Output)。
- IO流的分类
- 按流动的方向来分,可以分为输入流与输出流
- 按流动的数据类型来分,可以分为字节流与字符流
- 字节流:
- 输入流:InputStream
- 输出流:OutputStream
- 字符流:
3 ,OutputStream
- OutputStream是一个抽象类,用来写字节流,所有带OutputStream的类的爸爸,这个类有5个重要的方法,4个具体方法,1个抽象的。
OutputStream重要方法 | 说明 |
---|
void close() | 用完关闭输出流 |
void flush() | 将缓存中的数据输出,形象点理解为冲马桶 |
void write(byte b[], int off, int len) | 经典的写方法,控制开始位置和长度 |
void write(byte b[]) | 将整个byte字符数组写出 |
abstract void write(int b) | 写一个字符,取int中后8位bit |
3.1, FileOutputStream
- FileOutputStream是OutputStream里最常见的直接子类。
- 构造方法
FileOutputStream fos = new FileOutputStream("C:\\c.txt", true);
FileOutputStream fos1 = new FileOutputStream("C:\\c.txt");
- 3个写方法的案例
package day16;
import java.io.*;
public class Demo2 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("C:\\c.txt", true);
byte bytes[] = {66, 67, 68, 69};
fos.write(65);
fos.write("abcde".getBytes());
fos.write(bytes,1, 2);
fos.close();
}
}
- c.txt文件中显示AabcdeCD
- 用完记得关闭流
- 若再次运行,会继续追加,而非覆盖
4,InputStream
- InputStream也是一个抽象类,用来读字节流。是所有带InputStream的爸爸,关注其4个方法。
InputStream重要方法 | 说明 |
---|
abstract int read() | 一次读一个字节,最开始指向第一个,读完指向下一个,读完了返回-1 |
int read(byte b[]) | 一次读一组字节,读完了返回-1,否则返回本次读取的字节长度 |
int read(byte b[], int off, int len) | 一次读一组字节中[off, off+len]的字节,读完返回-1 |
4.1, FileInputStream
- FileInputStream是InputStream最常用的子类,其他的InputStream用法可借鉴FileInputStream的玩法。
- 构造方法
FileInputStream fis = new FileInputStream("C:\\c.txt");
- 常用方法案例
package day16;
import java.io.FileInputStream;
import java.io.IOException;
public class Demo3 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\c.txt");
while(true){
int r = fis.read();
if(r == -1) break;
System.out.println((char)r);
}
fis = new FileInputStream("C:\\c.txt");
while(true){
byte bytes[] = new byte[3];
int len = fis.read(bytes);
if(len == -1) break;
System.out.println(new String(bytes));
}
fis = new FileInputStream("C:\\c.txt");
while(true){
byte bytes[] = new byte[3];
int len = fis.read(bytes, 1, 2);
if(len == -1) break;
System.out.println(new String(bytes));
}
fis.close();
}
}
5, Writer
- Writer是用于写入字符流的抽象类。 子类必须实现的唯一方法是write(char [],int,int),flush()和close()。 但是,大多数子类将覆盖此处定义的一些方法,以提供更高的效率,附加功能或两者兼而有之。
- 与写字节流的OutputStream的方法相似。可以自行对比API看
用法 | 说明 |
---|
Writer append(char c) | 追加一个字符 |
Writer append(CharSequence csq, int start, int end) | 按要求追加字符串 |
Writer append(CharSequence csq) | 追加字符串 |
5.1 ,FileWriter
package day16;
import java.io.FileWriter;
import java.io.IOException;
public class Demo4 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("c:\\b.txt", true);
fw.append('0').append('u');
fw.append("我认为,你很捞");
fw.append("你在骂我");
fw.close();
}
}
6,Reader
- Reader类是用于读取字符流的抽象类。 子类必须实现的唯一方法是read(char [],int,int)和close()。 但是,大多数子类将覆盖此处定义的一些方法,以提供更高的效率,附加功能或两者兼而有之。
- 用法和InputStream中的read()方法相似。可以自行查看API。
方法 | 说明 |
---|
int read() | 读取一个字符,返回读取字符的长度,读完返回-1 |
int read(char cbuf[]) | 读取字符串,返回的结果同上 |
abstract int read(char cbuf[], int off, int len) | 读取从off开始,长度len的字符串 |
6.1 ,FileReader
- FireReader类也只不过是实现了自己的构造方法,FireReader直接继承InputStreamReader,这个具体类直接继承Reader,并实现了抽象方法。
- 看一段代码
package day16;
import java.io.FileReader;
import java.io.IOException;
public class Demo5 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("c:\\b.txt");
char chars[] = new char[100];
int len = fr.read(chars);
String text = new String(chars, 0, len);
System.out.println(text);
System.out.println(text.length());
fr.close();
}
}
7,字节流转换为字符流
- 在实际应用环境中,大部分都在传字节流,但是有时候操作字节流不如操作字符流那么方便,java提供了这样的转换方式。
7.1,InputStreamReader与OutputStreamWriter
package day16.com.java;
import java.io.*;
public class Demo6 {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:\\c.txt"));
osw.append("床前明月光").append(",").append("清明上河图").append(".");
osw.close();
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\c.txt"));
while(true){
char chars[] = new char[2];
int len = isr.read(chars);
if(len == -1) break;
System.out.println(new String(chars));
}
isr.close();
}
}
8, 总结
- 总结一下,其实IO流用法都大同小异,字节流用的更多,因为毕竟计算机的蓬勃发展是在西方,只需要传英文,字节流已经够用了,哪儿想到后来普及到世界各地去了。字符流可以创建实例直接操作,也可以由字节流转换后操作。
- 对于字节流,掌握读InputStream和写OutputStream这两个抽象类,掌握常用的读写方法和其子类的常用构造方法。
字节流 | 抽象方法以及子类的构造方法 | 说明 |
---|
InputStream | void close() | 关闭流 |
InputStream | abstract int read() | 读一个 |
InputStream | int read(byte b[]) | 读一组 |
InputStream | int read(byte b[], int off, int len) | 读一组中的几个 |
FileInputStream | FileInputStream(String name) | 构造方法,传pathname字符串 |
FileInputStream | FileInputStream(File file) | 构造方法,传file对象 |
字节流 | 抽象方法以及子类的构造方法 | 说明 |
---|
OutputStream | void close() | 关闭流 |
OutputStream | void flush() | 冲马桶,清缓存 |
OutputStream | abstract void write(int b) | 写一个 |
OutputStream | void write(byte b[]) | 写一组 |
OutputStream | void write(byte b[], int off, int len) | 写一组中的几个 |
FileOutputStream | FileOutputStream(String name) | 构造方法,传pathname字符串 |
FileOutputStream | FileOutputStream(String name, boolean append) | 构造方法,是否开启追加模式 |
FileOutputStream | FileOutputStream(File file) | 构造方法:传pathname字符串 |
FileOutputStream | FileOutputStream(File file, boolean append) | 构造方法,是否开启追加模式 |
- 对于字符流,掌握读Reader和写Writer这两个抽象类,掌握常用的读写方法和常用子类的构造方法。
字符流 | 抽象方法以及子类的构造方法 | 说明 |
---|
Reader | abstract void close() | 关闭流 |
Reader | int read() | 读一个 |
Reader | int read(char cbuf[]) | 读一组 |
Reader | abstract int read(char cbuf[], int off, int len) | 读一组中的几个 |
FileReader | FileReader(String fileName) | 构造方法,传pathname |
FileReader | FileReader(File file) | 构造方法,传File对象 |
字符流 | 抽象方法以及子类的构造方法 | 说明 |
---|
Writer | abstract void close() | 关闭流 |
Writer | abstract void flush() | 冲马桶,清缓存 |
Writer | abstract void write(char cbuf[], int off, int len) | 写一串字符 |
Writer | append(char c) | 写一个字符 |
Writer | append(CharSequence csq) | 写一组字符 |
Writer | append(CharSequence csq, int start, int end) | 写一组字符里的几个 |
FileWriter | FileWriter(String fileName, Charset charset, boolean append) | 构造方法,传pathname,字符编码,是否开启追加模式 |
FileWriter | FileWriter(File file, Charset charset, boolean append) | 构造方法,传File对象 ,其他同上,参数1必传,后面两个可以任意组合 |
- 对于转换流(字节—>字符),掌握InputStreamReader 和 OutputStreamWriter这两个具体类,除了他们的构造方法,有点不一样,创建完之后就和操作字符流一样了。
类 | 构造方法 | 说明 |
---|
OutputStreamWriter | OutputStreamWriter(OutputStream out) | 参数1:字节流 |
OutputStreamWriter | OutputStreamWriter(OutputStream out, String charsetName) | 参数1:字节流;参数2:字符编码 |
类 | 构造方法 | 说明 |
---|
InputStreamReader | InputStreamReader(InputStream in) | 参数1:字节流 |
InputStreamReader | InputStreamReader(InputStream in, String charsetName) | 参数1:字节流;参数2:字符编码 |