- IO流体系框架
- IO流体系分类
- 为什么要有IO流?
- IO流初涉:文件
- 如何打开文件
- File类的相关功能
- FileReader的操作
- FileWrite的操作
- 通过字节流实现图片的拷贝
- 使用处理流对文本操作
- 使用对象流实现序列化和反序列化
- RandomAccessFile的使用
| 分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
|---|---|---|---|---|
| 抽象基类 | InputStream | OutputStream | Reader | Writer |
| 访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
| 访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
| 访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
| 访问字符串 | StringReader | StringWriter | ||
| 缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
| 转换流 | InputStreamReader | OutputStreamWriter | ||
| 对象流 | ObjectInputStream | ObjectOutputStream | ||
| FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
| 打印流 | PrintStream | PrintWriter | ||
| 推回输入流 | PushbackInputStream | PushbackReader | ||
| 特殊流 | DataInputStream | DataOutputStream |
IO流初涉:文件 如何打开文件因为我们在编程过程中对文件进行操作,而Java中对文件的读写都是以流的形式来实现,也就是所谓的IO流。
又因为文件分文字节文件和字符文件,所以出现了字节流和字符流。之后针对不同的文件类型又出现了很多拥有特定功能的IO流子类。
File类的相关功能通过创建File类的实例来创建文件。File(String path),其中path可以使相对路径,也可以是绝对路径。
File file=new File("Hello.txt") 通过相对路径打开一个叫Hello.txt的文件
| File类的相关功能 | |||
|---|---|---|---|
| 获取功能 | 返回值 | 参数 | 说明 |
| getAbsolutePath() | String | 获取绝对路径 | |
| getPath() | String | 获取路径 | |
| getName() | String | 获取名称 | |
| getParent() | String | 获取上一层文件目录路径,不存在返回null | |
| length() | long | 获取文件长度(字节数) | |
| lastModified() | long | 获取最后一次修改时间,毫秒级 | |
| list() | String[] | 获取指定目录下的所有文件或者文件目录的名称数组 | |
| listFiles() | File[] | 获取指定目录下的所有文件或者文件目录的File数组 | |
| 重命名功能 | 返回值 | 参数 | 说明 |
| renameTo() | boolean | File dest | 把文件重命名为指定的文件路径 |
| 判断功能 | 返回值 | 参数 | 说明 |
| isDirectory() | boolean | 判断是否是文件目录 | |
| isFile() | boolean | 判断是否是文件 | |
| exists | boolean | 判断是否存在 | |
| canRead() | boolean | 判断是否可读 | |
| canWrite() | boolean | 判断是否可写 | |
| isHidden() | boolean | 判断是否隐藏 | |
| 创建功能 | 返回值 | 参数 | 说明 |
| createNewFile() | boolean | 创建文件。若文件存在就不创建并返回false | |
| mkdirs() | boolean | 创建文件目录。如果上层文件目录不存在,一并创建 | |
| 删除功能 | 返回值 | 参数 | 说明 |
| delete() | boolean | 删除文件或者文件夹(注意:不会进回收站) |
//创建
FileReader fr = new FileReader("file.txt");//文件file.txt必须存在,不然会抛出异常
//返回值为读取到的单个字符,对应的ASCII或者Unicod
ch = fr.read();
System.out.println(ch); //-1代表没有更多字符可以读取
fr.close();
FileWrite的操作
//指明写入到的文件
File file=new File("helloI.txt");//文件可以不存在,不存在会创建
try {
//提供FileWriter类的对象,用于数据写出
FileWriter fw=new FileWriter(file);
//写出数据
fw.write("hello IDEA");
//关闭流资源
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
通过字节流实现图片的拷贝
//源图片
File srcFile=new File("ganyu.jpg");
//目标图片
File desFile=new File("ganyu1.jpg");
//造节点流
//造输入节点流
FileInputStream fis=new FileInputStream(srcFile);
//造输出节点流
FileOutputStream fos=new FileOutputStream(desFile);
//造缓冲流,它是处理流,是对节点流的包装
//造输入缓冲流
BufferedInputStream bis=new BufferedInputStream(fis);
//造输出缓冲流
BufferedOutputStream bos=new BufferedOutputStream(fos);
//拷贝的细节
byte ch[]=new byte[100];
int len;
while ((len =bis.read(ch))!=-1){
bos.write(ch,0,len);
}
//关闭流(从内往外关闭)
bos.close();
bis.close();
fos.close();
fis.close();
使用处理流对文本操作
//方式一:使用数组
File srcFile=new File("hello.txt");
File desFile=new File("hello1.txt");
FileReader fr=new FileReader(srcFile);
FileWriter fw=new FileWriter(desFile);
BufferedReader br=new BufferedReader(fr);
BufferedWriter bw=new BufferedWriter(fw);
//实现的细节
char ch[]=new char[1024];
int len;
String data;
while ((len =br.read(ch))!=-1){
bw.write(ch,0,len);
// bos.flush();
}
//关闭流(从内往外关闭)
br.close();
bw.close();
fr.close();
fw.close();
//方式二:使用String
File srcFile=new File("hello.txt");
File desFile=new File("hello1.txt");
FileReader fr=new FileReader(srcFile);
FileWriter fw=new FileWriter(desFile);
BufferedReader br=new BufferedReader(fr);
BufferedWriter bw=new BufferedWriter(fw);
//实现的细节
char ch[]=new char[1024];
int len;
String data;
while ((data=br.readLine())!=null){
bw.write(data);
}
//关闭流(从内往外关闭)
br.close();
bw.close();
fr.close();
fw.close();
使用对象流实现序列化和反序列化
对象流(ObjectInputStream 和 ObjectOutputStream)的使用
作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
序列化机制:
- 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
public class Person implements Serializable{//必须要实现Serializable接口
public static final long serialVersionUID = 475463534532L;
private String name;
private int age;
private int id;
public Person(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public Person(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
", id=" + id +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
}
//序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去,使用ObjectOutputStream实现
public void testObjectOutputStream(){
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new String("我爱北京天安门"));
oos.flush();//刷新操作
oos.writeObject(new Person("王铭",23));
oos.flush();
oos.writeObject(new Person("张学良",23,1001));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(oos != null){
//3.
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//反序列化:将磁盘文件中的对象还原为内存中的一个java对象使用ObjectInputStream来实现
public void testObjectInputStream(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.dat"));
Object obj = ois.readObject();
String str = (String) obj;
Person p = (Person) ois.readObject();
Person p1 = (Person) ois.readObject();
System.out.println(str);
System.out.println(p);
System.out.println(p1);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
RandomAccessFile的使用
- RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口
- RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
- 如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。
如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖)- 可以通过相关的操作,实现RandomAccessFile“插入”数据的效果
//既可以作为一个输入流,又可以作为一个输出流的代码实现
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
//1.
raf1 = new RandomAccessFile(new File("爱情与友情.jpg"),"r");
raf2 = new RandomAccessFile(new File("爱情与友情1.jpg"),"rw");
//2.
byte[] buffer = new byte[1024];
int len;
while((len = raf1.read(buffer)) != -1){
raf2.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//3.
if(raf1 != null){
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(raf2 != null){
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//实现RandomAccessFile“插入”数据的效果
RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");
raf1.seek(3);//将指针调到角标为3的位置
//保存指针3后面的所有数据到StringBuilder中
StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
byte[] buffer = new byte[20];
int len;
while((len = raf1.read(buffer)) != -1){
builder.append(new String(buffer,0,len)) ;
}
//调回指针,写入“xyz”
raf1.seek(3);
raf1.write("xyz".getBytes());
//将StringBuilder中的数据写入到文件中
raf1.write(builder.toString().getBytes());
raf1.close();
说明:后面可能会有更新



