java IO学习
流的概念
是内存和存储设备之间传输数据的一个通道
流的分类
-
按照单位:
1.字节流,可以输入任何数据,因为任何数据在内存中都是以字节的方式存储的
- 字符流,只能读取文本形式的数据,因为有的字符是一个字节、两个字节、三个字节
-
按照功能:
- 节点流,也叫底层流,具有实际传输数据的读写功能
- 缓冲流,在节点流只上实现的增强功能
字节流的学习
字节流输入的父类(抽象类):分别是InputStream和OutputStream
//用这两个抽象类的用来读文件的子类【FileInputStream,FileOutputStream】来读取文件和写入文件
//实现文件的复制
public class FileCopy {
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream("d:\\1.png");
FileOutputStream out = new FileOutputStream("d:\\2.png");
byte[] buffer = new byte[1024]; //此处的byte不能是Byte
int count=0;
while((count=in.read(buffer))!=-1){
out.write(buffer,0,count); //count输出的是读出字节的个数
}
in.close(); //用完之后记得关闭流
out.close();
}
}
缓冲流学习
- 缓冲流BufferedInputStream 和BufferedOutputStream实际上就是在类的内部加了一个8K的缓冲区,每次读写都会先放到缓冲区里面,提高了IO效率
//用BufferedInputStream实现文件读入
public class MyBufferdInput {
public static void main(String[] args) throws Exception {
//注意此处需要放入一个底层的 InputStream对象
BufferedInputStream bin = new BufferedInputStream(new FileInputStream("d:\\hello.txt"));
int data=0;
while((data=bin.read())!=-1){
System.out.print((char)data);
}
bin.close();
}
}
//用BufferedOutputStream实现文件写出
public class MyBufferdInput {
public static void main(String[] args) throws Exception {
//注意此处需要放入一个底层的 OutputStream对象【节点流】
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("d:\\helloout.txt"));
int data=0;
String s = "hello";
for (int i = 0; i < 10; i++) {
bout.write(s.getBytes());
bout.flush(); //这句代码的意思是,没写出到缓冲区一次就将内容写到磁盘,不等到写满8k
}
bout.close(); //如果上面没有刷新在这也会全部写出到磁盘
}
}
对象流
- 使用流 写入/读出 对象 就叫 序列化/反序列化
- 注意事项:
- 序列化的类必须实现Serializable接口
- 序列化类中的对象属性也需要实现Serializable接口
- 静态属性不能被序列化
- 如果类中的属性加上transient(瞬时的)之后,也不能被序列化
- 如果想要多个对象同时序列化,可以用集合 比如list来序列化
public class Serialize {
public static void main(String[] args) throws Exception{
//序列化,注意此处需要底层流对象
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("d:\\stu.txt"));
Student stu1 = new Student("张三", 18);
Student stu2 = new Student("李四", 22);
//out.writeObject(stu);
List<Student> list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
out.writeObject(list); //序列化一个链表
out.close();
System.out.println("序列化成功");
//反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("d://stu.txt"));
//Object returnstu=in.readObject();
ArrayList<Student> returnStu= (ArrayList<Student>) in.readObject();
in.close();
System.out.println(returnStu.toString());
}
}
class Student implements Serializable {
private String name;
private int age;
public static int id; //这两个属性不能序列化
public transient char sex;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//输出
序列化成功
[Student{name='张三', age=18}, Student{name='李四', age=22}]
字符流
- 常见字符编码:utf-8,gbk
- 因为字节流读汉字会存在问题,所以有了Reader和Writer(父类,抽象类)
//FileReader和FileWriter的使用:其实和上面的FileInputStream和FileOutputStream用法是一样的
public class FileReaderAndFileWriter {
public static void main(String[] args) throws Exception{
//将汉字写入文件
FileWriter fw = new FileWriter("d://filewrite.txt");
for (int i = 0; i < 5; i++) {
fw.write("你好世界\r\n");
}
fw.close();
FileReader fr = new FileReader("d://filewrite.txt");
int data=0;
while ((data = fr.read()) != -1) {
System.out.print((char)data);
}
}
}
字符缓冲流
- 可以读取一行
//BufferReader和BufferWriter的使用:和上面的字节缓冲流基本上没有区别
public class BufferedReaderAndBufferedWriter {
public static void main(String[] args) throws Exception {
BufferedWriter bw = new BufferedWriter(new FileWriter("d://bw.txt"));
for (int i = 0; i < 5; i++) {
bw.write("好好学习,天天向上");
bw.newLine(); //功能就是\r\n(换行)
}
bw.close(); //关闭流
System.out.println("写入成功");
BufferedReader br = new BufferedReader(new FileReader("d://bw.txt"));
String ans=null;
while((ans=br.readLine())!=null){ //可以一行一行的读取
System.out.println(ans);
}
br.close(); //关闭流
}
}