IO流

  1. 什么是io流

    存储和读取数据的解决方案

    I:input O:output

  2. io流的作用

    用于读写数据(本地文件,网络)

  3. io流按照流向可以分类哪两种流

    输出流:程序---->文件

    输入流:文件---->程序

  4. io流按照操作文件的类型可以分类哪两种流

    字节流:可以操作所有类型的文件

    字符流:只能操作纯文本文件

1.FileOutputStream流(本地字节输出流)

创建字节输出流对象:

  1. 参数是字符串表示的路径或者File对象都可以
  2. 如果文件不存在会创建一个新文件,但是要保证父级路径存在
  3. 如果文件已经存在,会清空文件
package com.zhang.ioStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //后面加上true会续写文件,不会清空文件。
        FileOutputStream fods = new FileOutputStream("src\\com\\zhang\\ioStream\\a.txt");
        byte[] bytes = {97,98,99,100,101};
        //写出数组
        fods.write(bytes);
        //换行操作
        String wap = "\r\n";
        byte[] bytes1 = wap.getBytes();
        fods.write(bytes1);
        //写出单个字符
        fods.write(34);
        //数组,起始位置,写出长度
        fods.write(bytes,1,2);
        //写出任意字符串
        String str = "dafffdsfaf";
        byte[] bytes2 = str.getBytes();
        fods.write(bytes2);
        //释放资源
        fods.close();
    }
}

2.FileInputStream(字节输入流)

package com.zhang.ioStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Demo02 {
    public static void main(String[] args) throws IOException {
        FileInputStream fie = new FileInputStream("src\\com\\zhang\\ioStream\\a.txt");
        int b;
        //不能把b删了,把(char)b换成(char)fie.read(),因为用一次会读取一个数据,移动一次指针,造成数据缺失
        while((b=fie.read())!=-1){ 
            System.out.println((char)b);
        }
        fie.close();
    }
}

小文件拷贝

package com.zhang.ioStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo03 {
    public static void main(String[] args) throws IOException {
        FileInputStream fie = new FileInputStream("数据源");
        FileOutputStream fos = new FileOutputStream("目的地");
        //拷贝核心思想:边读边写
        int b;
        while((b = fie.read())!=-1){
            fos.write(b);
        }
        //先开的最后关闭
        fos.close();
        fie.close();
    }
}

大文件拷贝

package com.zhang.ioStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo03 {
    public static void main(String[] args) throws IOException {
        FileInputStream fie = new FileInputStream("文件所在路径");
        FileOutputStream fos = new FileOutputStream("拷贝的路径");
        //拷贝核心思想:边读边写
        int len;
        byte[] bytes = new byte[1024*1024*5];
        while((len = fie.read())!=-1){
            fos.write(bytes,0,len);
        }
        //先开的最后关闭
        fos.close();
        fie.close();
    }
}

字符集详解(ASCII GBK)

  1. 计算机中最小的存储单元是一个字节
  2. ASCII字符集中,一个英文占一个字节
  3. 简体中文版Windows,默认使用GBK字符集
  4. GBK字符集完全兼容ASCII字符集:一个英文占一个字节,二进制第一位是0;一个中文占两个字节,二进制高位字节的第一位是1

Unicode字符集的UTF-8编码格式

一个英文占一个字节,二进制第一位是0,转成十进制是正数

一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数。

如何不产生乱码

  1. 不要用字节流读取文本文件
  2. 编码解码时使用同一个码表,同一个编码方式。

编码和解码代码的实现

package com.zhang.ioStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Demo04 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //编码
        String str = "ai你哈";
        byte[] bytes = str.getBytes();
        System.out.println(Arrays.toString(bytes));//[97, 105, -28, -67, -96, -27, -109, -120]
        byte[] bytes1 = str.getBytes("GBK");
        System.out.println(Arrays.toString(bytes1));//[97, 105, -60, -29, -71, -2]
        //解码
        String str2 = new String(bytes,"GBK");
        System.out.println(str2);   //ai浣犲搱   
        String str3 = new String(bytes1,"UTF-8");  //因为是GBK类型的,解码成UTF-8会出现乱码
        System.out.println(str3);   //ai���
    }
}

3.FileReader

package com.zhang.ioStream;
import java.io.FileReader;
import java.io.FilterReader;
import java.io.IOException;
public class Demo05 {
    public static void main(String[] args) throws IOException {
        FileReader fre = new FileReader("a.txt");
        char[] chars = new char[2];
        int len;
        while((len = fre.read(chars))!= -1){
            System.out.print(new String(chars,0,len));
        }
        fre.close();
    }
}

空参的read();默认是一个字节一个字节读取,遇到中文会一次读取多个。在读取之后,方法的底层会进行解码转成十进制作为返回值,这个数据表示在字符集上的数字,要想看到中文,进行强制转换就可以了(char)..

有参read():读取数据,解码,强转三步合并,把强转的字符放到数组当中。

4.FileWriter

package com.zhang.ioStream;
import java.io.FileWriter;
import java.io.IOException;
public class Demo06 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("a.txt");
        fw.write("真的很好呀");
        fw.close();
    }
}

拷贝文件夹

package com.zhang.ioStream;
import java.io.*;
public class Demo06 {
    public static void main(String[] args) throws IOException {
        File src = new File("E:\\项目练习plus\\src");//数据源
        File dest = new File("E:\\项目练习plus\\dest");//目的地
        copdir(src,dest);
    }
    private static void copdir(File src, File dest) throws IOException {
        //dest不存在,创建文件夹dest
        dest.mkdir();
        //进入数据源
        File[] files = src.listFiles();
        //遍历数组
        for (File file : files) {
            //判断文件  拷贝
            if (file.isFile()){
                FileInputStream fie = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(new File(dest,file.getName()));
                byte[] bytes = new byte[1024];
                int len;
                while ((len=fie.read(bytes))!=-1){
                    fos.write(bytes,0,len);
                }
                fos.close();
                fie.close();
            }else{
                //判断文件夹  递归
                copdir(file,new File(dest,file.getName()));
            }
        }
    }
}

加密解密文件

package com.zhang.ioStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo07 {   //解密的话把文件路径换下
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("源文件路径");
        FileOutputStream fos = new FileOutputStream("加密之后路径");
        //加密处理
        int len;
        while ((len = fis.read())!=-1){
            //异或运算,异或相同的数两次还是本身
            fos.write(len^2);
        }  
        fos.close();
        fis.close();
    }
}

文件中由以下数据:2-1-9-4-7-8 将文件中的数据进行排序,变成以下数据:1-2-4-7-8-9

package com.zhang.ioStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
public class Demo08 {
    public static void main(String[] args) throws IOException {
        FileReader fis = new FileReader("a.txt");
        StringBuilder sb = new StringBuilder();
        int ch;
        while((ch=fis.read())!=-1){
            sb.append((char)ch);
        }
        fis.close();
        System.out.println(sb);
        //排序
        Integer[] arr = Arrays.stream(sb.toString()
                 .split("-"))
                 .map(Integer::parseInt)
                 .sorted()
                 .toArray(Integer[]::new);
        System.out.println(Arrays.toString(arr));
        //写出
        FileWriter fw = new FileWriter("a.txt");
        String s = Arrays.toString(arr).replace(",","-");
        String result = s.substring(1,s.length()-1);
        fw.write(result);
        fw.close();
    }
}

5.BufferedInputStream和BufferedOutputStream(字节缓冲流)**

package com.zhang.ioStream;
import java.io.*;
public class Demo09 {
    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.txt"));
        int b;
        while((b=bis.read())!=-1){
            bos.write(b);
        }
        bos.close();
        bis.close();
    }
}

一次读写一个字符数组

package com.zhang.ioStream;
import java.io.*;
public class Demo10 {
    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy1.txt"));
        byte[] bytes = new byte[1024];
        int len;
        while ((len = bis.read(bytes))!=-1){
            bos.write(bytes,0,len);
        }
        bos.close();
        bis.close();
    }
}

6.BufferedReader和BufferedWriter(字符缓冲输入流和字符缓冲输出流)

package com.zhang.ioStream;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo11 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        String line;
        while ((line = br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
    }
}
package com.zhang.ioStream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Demo12 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt",true));
        bw.write("爱你过绝望");
        //换行
        bw.newLine();
        bw.write("库一样");
        bw.newLine();
        bw.close();
    }

}

缓冲流为什么能提高性能

  1. 缓冲流自带长度为8192的缓冲区
  2. 可以显著提高字节流的读写性能
  3. 对于字符流提升不明显,对于字符缓冲流而言关键有两个特有的方法
  4. BufferedReader:readLine();一次读一行数据
  5. BufferedWriter:newLine();换行

恢复文本中的顺序

package com.zhang.ioStream;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Demo13 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        String line;
        ArrayList<String> arr = new ArrayList();
        while ((line = br.readLine())!=null){
            arr.add(line);
        }
        //排序
        Collections.sort(arr, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int i1 = Integer.parseInt(o1.split("\\.")[0]);
                int i2 = Integer.parseInt(o2.split("\\.")[0]);
                return i1-i2;
            }
        });
        //写出
        BufferedWriter bw = new BufferedWriter(new FileWriter("result.txt"));
        for (String str : arr) {
            bw.write(str);
            bw.newLine();
        }
        bw.close();
    }
}

第二种方法

package com.zhang.ioStream;
import java.io.*;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Demo14 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        String line;
        TreeMap<Integer,String> tm = new TreeMap<>();
        while ((line = br.readLine())!=null){
            String[] arr = line.split("\\.");
            tm.put(Integer.parseInt(arr[0]),line);
        }
        br.close();
        //写出数据
        BufferedWriter bw = new BufferedWriter(new FileWriter("result1.txt"));
        Set<Map.Entry<Integer,String>> entries = tm.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            String value = entry.getValue();
            bw.write(value);
            bw.newLine();
        }
        bw.close();
    }
}

7.InputStreamReader,OutputStreamWriter(字符转换输入流和字符转换输出流)

package com.zhang.ioStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
//利用字节流读取文件中的数据,每次读一整行,而且不能有乱码
public class Demo16 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("");//文件是UTF-8形式的,用字符流读取
        InputStreamReader isr = new InputStreamReader(fis);//把字符流转换成字节流
        BufferedReader br = new BufferedReader(isr);//缓冲流里面有读一整行的方法
        String str = br.readLine();//读一整行
        System.out.println(str);
        br.close();
        //第二种方法
        BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("")));
        String line;
        while((line = br1.readLine())!=null){
            System.out.println(line);
        }
        br1.close();
    }
}

转换流作用:字节流想要使用字符流中的方法

8.ObjectOutputStream (序列化流)

public class Student implements Serializable{}
//Serializable接口里面没有抽象方法,标记接口。一旦实现这个接口,表示当前的Student类可以被序列化
package com.zhang.ioStream;
import com.zhang.oop.Obct.Student;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Demo17 {
    public static void main(String[] args) throws IOException {
        Student stu = new Student("张三",23);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("copy.txt"));
        oos.writeObject(stu);
        oos.close();
    }
}

9.ObjeInputStream(反序列化流)

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("copy.txt"));
Object o = ois.readObject();
System.out.println(o);
ois.close();
  1. 使用序列化流将对象写到文件时,需要让Javabean类实现Serializable接口。否则,会出现NotSerializableException异常

  2. 序列化流写到文件中的数据是不能修改的,一旦修改无法再次读回来。

  3. 序列化对象后,修改了Javabean类,再次反序列化,会抛出InvalidClassException异常

    解决方案:给Javabean类添加serialVersionUID(序列号,版本号)

  4. 一个对象中的某个成员变量的值不想被序列化

    解决方案:给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程。

读写多个对象

package com.zhang.ioStream;
import com.zhang.oop.Obct.Student;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class Demo18 {
    public static void main(String[] args) throws IOException {
        Student s1 = new Student("张三",12);
        Student s2 = new Student("李四",22);
        Student s3 = new Student("王五",33);
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("copy.txt"));
        oos.writeObject(list);
        oos.close();
    }
}
package com.zhang.ioStream;
import com.zhang.oop.Obct.Student;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class Demo19 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("copy.txt"));
        ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
        for (Student student : list) {
            System.out.println(student);
        }
    }
}

10.PrintStream字节打印流

package com.zhang.ioStream;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Demo20 {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream ps = new PrintStream("copy1.txt");
        ps.println(97);//写出+自动刷新+自动换行
        ps.print(true);
        ps.printf("%s爱上了%s","阿珍","阿强");
        ps.close();
    }
}

11.PrintWriter字符打印流

package com.zhang.ioStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Demo21 {
    public static void main(String[] args) throws IOException {
        PrintWriter pw = new PrintWriter(new FileWriter("copy1.txt"));
        pw.println("谢谢你,张三");
        pw.print("你好你好");
        pw.printf("%s爱你%s","zhang","san");
        pw.close();
    }
}
posted on 2023-03-15 10:15  似初吖  阅读(36)  评论(0编辑  收藏  举报