I/O流

在这里插入图片描述

I/O流概述

IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按流向划分: 输入流,输出流
流按读写数据类型划分: 字节流,字符流


字节流:

可以读写任意类型的文件

输出流

FileOutputStream构造方法:

        //文件输出流是用于将数据写入 File
        //FileOutputStream(File file)
        //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
        //FileOutputStream(File file, boolean append)
        //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。

        //FileOutputStream(String name)
        //创建一个向具有指定名称的文件中写入数据的输出文件流。
        //FileOutputStream(String name, boolean append)
        //创建一个向具有指定 name 的文件中写入数据的输出文件流。

        //FileOutputStream(File file)
        //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
        //输出流,所关联的文件,如果不存在,会自动帮你创建一个
        File file = new File("a.txt");
        FileOutputStream out = new FileOutputStream(file);

        //直接传入一个字符串的文件路径,如果这个文件不存在,会自动帮你创建
        FileOutputStream out2 = new FileOutputStream("c.txt");

例:创建并写入一个数据的文件

public class Mydemo3 {
    public static void main(String[] args) throws IOException {
        // 1)创建一个向指定 File 对象表示的文件中写入数据的文件输出流
        File file = new File("a.txt");
        FileOutputStream out1 = new FileOutputStream(file);
        // 2)直接传入一个文件路径,如果该文件不存在则创建
        FileOutputStream out2 = new FileOutputStream("D:\\b.txt");
        //若下次写入时数据不被覆盖,则添加参数true
        FileOutputStream out3 = new FileOutputStream("D:\\c.txt",true);

        out1.write(98);
        out1.write("Hello World!".getBytes());
        //注意:一个汉字占三个字节(平台默认UTF-8编码)
        //写入字节数组的一部分 从某个索引开始,写多少个字节
        out1.write("爱生活,爱Java".getBytes(),0,9);
        //流使用完毕之后,必须释放资源
        out1.close();
    }
}

不同系统下换行注意:

        out1.write("\r\n".getBytes()); //Windows系统换行
        out1.write("\n".getBytes());   //Linux系统换行
        out1.write("\r".getBytes());   //Mac系统换行

例:流的异常处理
方式一:捕获处理异常

public class MyDemo4 {
    public static void main(String[] args) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream("a.txt");
            out.write("java".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

方式一:向上抛出异常

public class MyDemo5 {
    public static void main(String[] args) throws IOException {
        FileOutputStream out = new FileOutputStream("a.txt");
        out.write("java".getBytes());
        out.close();
    }
}
输入流

从文件系统中的某个文件中获得输入字节
FileInputStream构造方法:

        // FileInputStream 从文件系统中的某个文件中获得输入字节
        // FileInputStream(String name)
        // 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

        //FileInputStream(File file)
        //通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
        //输入流,所关联的文件如果不存在,就会报错
public class MyDemo6 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("a.txt");
        //读取数据方式一: 一次读一个字节,如果读超了则返回-1
        in.read();
        //读取数据方式二: 一次读一个字节数组 字节数组相当于一个缓冲区
        byte[] bytes = new byte[1024];
        int len=in.read(bytes);//len返回有效读取长度
        //遍历读出的数据
        String s = new String(bytes, 0, len);
        System.out.println(s);
    }
}

例:复制文件

public class MyDemo7 {
    public static void main(String[] args) throws IOException {
        //方式一:一次读取一个字节,写一个字节来复制,效率低
        //方式二:一次读取一个字节数组,写一个字节数组(以下代码采用此种方式)
        FileInputStream in = new FileInputStream("a.txt");
        FileOutputStream out = new FileOutputStream("b.txt");
        //创建一个字节缓冲区
        byte[] bytes = new byte[1024];
        int len=0;
        while ((len=in.read(bytes))!=-1){
            out.write(bytes,0,len);
            //刷新输出流,使缓存数据被写出来
            out.flush();
        }
        in.close();
        out.close();
    }
}

例:把这个音乐文件复制两份

public class MyDemo {
   public static void main(String[] args) throws IOException {
       //把这个音乐文件复制两份
       FileInputStream in = new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
       FileOutputStream out1 = new FileOutputStream("D:\\烟花易冷Live_林志炫1.mp3");
       FileOutputStream out2 = new FileOutputStream("D:\\烟花易冷Live_林志炫2.mp3");
       ArrayList<FileOutputStream> list = new ArrayList<>();
       list.add(out1);
       list.add(out2);
       byte[] bytes = new byte[1024 * 8];
       int len = 0;
       for (FileOutputStream out : list) {
           while ((len = in.read(bytes)) != -1) {
               out.write(bytes, 0, len);
               out.flush();
           }
          in= new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
       }
       //释放资源
       in.close();
       out1.close();
       out2.close();
   }
}

例:高效的输入、出流

BufferedInputStream与BufferedOutputStream

public class MyDemo8 {
    public static void main(String[] args) throws IOException {
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("a.txt"));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("c.txt"));
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes, 0, len);
            out.flush();
        }
        in.close();
        out.close();
    }
}

对时间效率差异的解释:
  BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。
  因此,当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
  BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了


字符流:

Writer与Reader

只能读写文本文件
字符流=字节流+编码表

编码:文本=》字节
解码:字节=》文本

public class MyDemo9 {
    public static void main(String[] args) {
        //编码:
        byte[] bytes = "爱生活,爱Java".getBytes();//平台默认编码
        for (byte aByte : bytes) {
            System.out.println(aByte);
        }
        //解码:
        String str = new String(bytes);
        System.out.println(str);
    }
}
public class MyDemo9 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //指定编码形式,注意编解码要一致
        byte[] bytes = "爱生活,爱Java".getBytes("gbk");
        String str = new String(bytes, "gbk");
        System.out.println(str);
    }
}

构造方法:

         //创建使用默认字符编码的 OutputStreamWriter
         OutputStreamWriter(OutputStream out)
         //创建使用给定字符集的 OutputStreamWriter
         OutputStreamWriter(OutputStream out, Charset cs)

         //创建一个使用默认字符集的 InputStreamReader
         //输入流所关联的文件,如果不存在 就会报错
         InputStreamReader(InputStream in)
         //创建使用给定字符集的 InputStreamReader
         InputStreamReader(InputStream in, Charset cs)   

例:字符流的文件复制

//方式一:
public class CopyFile {
    public static void main(String[] args) throws IOException {
        //读取一个字符,写一个字符,来复制文件
        InputStreamReader in = new InputStreamReader(new FileInputStream("MyDemo.java"));
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("MyDemoCopy.java"));

        int len=0;
        while ((len=in.read())!=-1){
            out.write(len);
            out.flush();
        }

        in.close();
        out.close();
    }
}
//方式二:
public class CopyFile2 {
    public static void main(String[] args) throws IOException {
        InputStreamReader in = new InputStreamReader(new FileInputStream("MyDemo.java"));
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("MyDemoCopy2.java"));
        //创建一个字符缓冲区
        char[] chars = new char[100];  
        int len = 0; //len 是啥意思:记录 你每次读取到的有效的字符个数
        while ((len=in.read(chars)) != -1) {
            out.write(chars, 0, len);//
            out.flush(); //字符流记得刷新一下
        }
        //释放资源
        in.close();
        out.close();
    }
}

例:高效的字符流
BufferedReader与BufferedWriter
构造方法:

       // 创建一个使用默认大小输入缓冲区的缓冲字符输入流
        BufferedReader(Reader in)
        String readLine () 一次读取一行文本
        
        // 创建一个使用默认大小输出缓冲区的缓冲字符输出流
        BufferedWriter(Writer out)
        void newLine () 写入一个换行符
//方式一:
public class MyDemo7 {
    public static void main(String[] args) throws IOException {
        // BufferedReader(Reader in)
        // new BufferedReader(new InputStreamReader(""));
        BufferedReader in = new BufferedReader(new FileReader("MyDemo5"));

        //BufferedWriter(Writer out)
        //创建一个使用默认大小输出缓冲区的缓冲字符输出流。
        BufferedWriter out = new BufferedWriter(new FileWriter("MyDemo55.java"));

        //创建一个字符缓冲区
        char[] chars = new char[100];  //
        int len = 0; //len 是啥意思:记录 你每次读取到的有效的字符个数
        while ((len = in.read(chars)) != -1) {
            out.write(chars, 0, len);//
            out.flush(); //字符流记得刷新一下
        }
        //释放资源
        in.close();
        out.close();
    }
}
//方式二:
public class MyDemo2 {
    public static void main(String[] args) throws IOException {
        //使用高效的字符流,采用读取一行,写入一行的方式来复制文本文件
        BufferedReader in = new BufferedReader(new FileReader("MyDemo5"));
        //BufferedWriter(Writer out)
        //创建一个使用默认大小输出缓冲区的缓冲字符输出流。
        BufferedWriter out = new BufferedWriter(new FileWriter("MyDemo56666.java"));
        String line=null; //记录每次读取到的一行文本
        while ((line=in.readLine())!=null){ //这里注意读取不到返回null
            out.write(line);
            out.newLine(); //写入一个换行符
            out.flush();//刷新
        }
        //释放资源
        out.close();
        in.close();
    }
}

FileReader与FileWriter类

public class MyDemo {
    public static void main(String[] args) throws IOException {
        //InputStreamReader in = new InputStreamReader(new FileInputStream("MyDemo.java"));
        //OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("MyDemoCopy2.java"));
        //   父类----------------------子类
        // InputStreamReader -------  FileReader  便捷类 唯一缺点就是不能指定编码
        // OutputStreamWriter ------- FileWriter  便捷类
        FileReader in = new FileReader("MyDemo.java");
        FileWriter out = new FileWriter(new File("MyDemo5"));

        //FileWriter(File file)
        //根据给定的 File 对象构造一个 FileWriter 对象。
        //
        //FileWriter(String fileName)
        //根据给定的文件名构造一个 FileWriter 对象。
        //创建一个字符缓冲区
        char[] chars = new char[100];  //
        int len = 0; //len 是啥意思:记录 你每次读取到的有效的字符个数
        while ((len = in.read(chars)) != -1) {
            out.write(chars, 0, len);
            out.flush(); //字符流记得刷新一下
        }
        //释放资源
        in.close();
        out.close();
    }
}

注意
父类:InputStreamReader 与OutputStreamWriter
||
子类(不能指定编码):FileReader与FileWriter


其它的一些杂七杂八的流

数据输入/出流: DataInputStream与DataOutputStream

public class IODemo {
    public static void main(String[] args) throws IOException {
        
        //数据输入数据流:这个流能读写基本数据类型
        
        //怎么写的,怎么读,顺序不要乱
        DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
        boolean b = dis.readBoolean();
        double v = dis.readDouble();
        char c = dis.readChar();
        String s = dis.readUTF();
        System.out.println(b);
        System.out.println(v);
        System.out.println(c);
        System.out.println(s);
        dis.close();
        return;
    }
    //写方法
    private static void writeData() throws IOException {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));
        dos.writeBoolean(false);
        dos.writeDouble(3.14);
        dos.writeChar('A');
        dos.writeUTF("陈本豪");
        dos.close();
    }
}

内存操作流: 不关联文件,所有数据的读写,只在内存中操作,内存流也无须关闭

  • 1.操作字节数组
   ByteArrayOutputStream
   ByteArrayInputStream
public class IODemo2 {
    public static void main(String[] args) throws IOException {
        //ByteArrayOutputStream
        //ByteArrayInputStream
        //此流关闭无效,所以无需关闭
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //写入内存操作流的缓冲区里面
        bos.write("你好".getBytes());
        bos.write("明天".getBytes());
        bos.write("未来以来".getBytes());
        //取出缓冲区中所有的数据
        byte[] allBytes = bos.toByteArray();
        String s = new String(allBytes);
        System.out.println(s);
        //String s = bos.toString(); 把缓存中的数据,转成字符串
        //bos.close(); //此流无需关闭

        //读取一个字节数组中的数据
        ByteArrayInputStream bis = new ByteArrayInputStream(allBytes);
        byte[] bytes = new byte[1024];
        int len = bis.read(bytes, 0, 6);
        System.out.println(new String(bytes,0,len));
    }
}

输出:
你好明天未来以来
你好

  • 2.操作字符数组
   CharArrayWrite
   CharArrayReader
public class IODemo3 {
    public static void main(String[] args) throws IOException {
        //操作字符数组
        CharArrayWriter writer = new CharArrayWriter();
        writer.write("abc");
        writer.write("bbbbb");
        writer.write(new char[]{'a','c','你'});
        String s = writer.toString();
        System.out.println(s);

    }
}

输出:
abcbbbbbac你

  • 3.操作字符串
   StringWriter
   StringReader
public class IODemo4 {
    public static void main(String[] args) {
        //操作字符串
        StringWriter writer = new StringWriter();
        writer.write("abc");
        writer.write("cccc");
        writer.write("eeee");
        writer.write("boolean");
        String s = writer.toString();
        System.out.println(s);
    }
}

输出:
abccccceeeeboolean


打印流: 不关联源文件,就是不能读取,只能输出

  • 1.字节流打印流
创建具有指定文件且不带自动行刷新的新打印流
PrintStream(File file)
public class IODemo {
    public static void main(String[] args) throws FileNotFoundException {
        //获取字节打印流  
        //关联屏幕 “标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出

        PrintStream out2 = new PrintStream(new File("b1.txt")); //关联文件
        out2.println(100);
        out2.print("abc");
    }
}
  • 2.字符流打印流
    使用指定文件创建不具有自动行刷新的新 PrintWriter
    PrintWriter(File file) 字符打印流
public class IODemo2 {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter writer = new PrintWriter(new File("c.txt"));
        writer.println("abc");
        writer.write("abcddddddd");
        writer.println(100);
        writer.println(3.14);
        writer.flush();//字符流记得刷新
        writer.close();
    }
}

字符流开启自动刷新:

public class IODemo3 {
    public static void main(String[] args) throws FileNotFoundException {
        //PrintWriter(OutputStream out, boolean autoFlush)
        //通过现有的 OutputStream 创建新的 PrintWriter。
        PrintWriter writer = new PrintWriter(new FileOutputStream("e1.txt"), true); //开启自动刷新
        //通过以下构造创建对象 能够启动自动刷新 然后调用println、printf 或 format 方法中的一个方法的时候, 会完成自动刷新
        writer.println(1001);
        writer.close();
    }
}

A:
案例演示:
打印流复制文本文件

public class IODemo4 {
    public static void main(String[] args) throws IOException {
       
        //找一个能读取的字符流
        BufferedReader bfr= new BufferedReader(new FileReader("IODemo.java"));
        PrintWriter writer = new PrintWriter(new FileOutputStream("IO.java"),true);
        String line=null;
        while ((line=bfr.readLine())!=null){
            writer.println(line);
        }
        bfr.close();
        writer.close();
    }
}

B:
案例演示:

public class IODemo5 {
    public static void main(String[] args) throws FileNotFoundException {
        //Scanner(File source)
        //构造一个新的 Scanner,它生成的值是从指定文件扫描的。
        Scanner scanner = new Scanner(new File("IO.java"));
        PrintWriter writer = new PrintWriter(new FileOutputStream("IO2.java"), true);
        while (scanner.hasNextLine()) {
            String s = scanner.nextLine();
            writer.println(s);
        }
        writer.close();
        scanner.close();
    }
}
public class IODemo {
    public static void main(String[] args) throws IOException {
        //键盘录入数据
        //in 是一个标准的输入流,对应的设备是键盘
        //Scanner scanner = new Scanner(System.in);
        //InputStream ins= System.in;
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true){
            System.out.println("请输入一行数据");
            String s = reader.readLine();
            //自己定义一个结束标记
            if("886".equals(s)){
                break;
            }
            System.out.println(s);
        }
    }
}

随机访问流RandomAccessFile:

  • 最大特点 能读能写
  • RandomAccessFile类不属于流,是Object类的子类,但它融合了InputStream和OutputStream的功能,支持对随机访问文件的读取和写入
  • 此类的实例支持对随机访问文件的读取和写入,随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组
     //参1 你所要关联的文件,参数2 读写模式
     RandomAccessFile(File file, String mode)
     RandomAccessFile(String name, String mode)
public class MyDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile ra = new RandomAccessFile(new File("f.txt"), "rw");
        //ra.writeBoolean(true); //占1字节
        //ra.writeDouble(3.14); // 占8字节
        //ra.writeInt(100); //占4字节
        //ra.writeUTF("你好"); //占6字节
        //怎么写的你就怎么读
        boolean b = ra.readBoolean();
        double v = ra.readDouble();
        int i = ra.readInt();
        //从这个文件中读取一个字符串
        String s = ra.readUTF();
        //获取文件指针位置
        long pointer = ra.getFilePointer(); 
        System.out.println(pointer);
        System.out.println(b);
        System.out.println(v);
        System.out.println(i);
        System.out.println(s);
        //设置指针位置
        ra.seek(13);
        String s1 = ra.readUTF();
        System.out.println(s1);
    }
}

输出:
21
true
3.14
100
你好
你好

案例:把这个音乐文件复制两份

public class MyDemo {
    public static void main(String[] args) throws IOException {
        // FileInputStream in = new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
        RandomAccessFile in = new RandomAccessFile(new File("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3"), "rw");
        FileOutputStream out1 = new FileOutputStream("D:\\烟花易冷Live_林志炫1.mp3");
        FileOutputStream out2 = new FileOutputStream("D:\\烟花易冷Live_林志炫2.mp3");
        ArrayList<FileOutputStream> list = new ArrayList<>();
        list.add(out1);
        list.add(out2);
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
        for (FileOutputStream out : list) {
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
                out.flush();
            }
            //in= new FileInputStream("E:\\我的图片和音乐\\音乐\\烟花易冷Live_林志炫.mp3");
            in.seek(0);//设置文件指针位置
        }
        //释放资源
        in.close();
        out1.close();
        out2.close();
    }
}

序列化流与反序列化流: ObjectOutputStream 与 ObjectInputStream

序列化流: 把内存中的数据(对象)存到硬盘中;就是把对象通过流的方式存储到文件中.
注意: 此对象 要重写Serializable 接口才能被序列化
反序列化流: 把硬盘中的数据(对象)读取到内存中;就是把文件中存储的对象以流的方式还原成对象

  • 这个对流 最大的特点,能够读写对象

这一对流需要注意以下三个问题:

  • 1.要序列化该类对象,要求该类实现一个Serializable 序列化接口
  • 2.最好生成一个 private static final long serialVersionUID = 5017795716700497273L;
  • 3.transient 不需要将某个成员变量的数据序列化到硬盘上,可以使用这个关键字 来排除他
        //将指定的对象写入 ObjectOutputStream
        void writeObject (Object obj) 特有的方法
//Serializable 标记接口
 //要将一个类的对象,成功序列化到硬盘上,要求此类必须实现一个Serializable 这个标记接口,如果不实现,则无法序列化成功
class Student implements Serializable {
    //记着实现完 Serializable 接口 生成一个serialVersionUID
     //生成一个序列化ID 确保读写的对象,是同一个对象
    private static final long serialVersionUID = 5017795716700497273L;   
    private String name;
    private  int age; 
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class IODemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Student student = new Student("张三", 23);
        ObjectOutputStream objWriter = new ObjectOutputStream(new FileOutputStream("student.txt"));
     
        objWriter.writeObject(student);
        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("student.txt"));
        Student stu = (Student) objIn.readObject();
        String name = stu.getName();
        int age = stu.getAge();
        System.out.println(name);
        System.out.println(age);
    }
}

输出:
张三
23

public class MyDemo {
    public static void main(String[] args) throws Exception {
        //写:序列化
        Student student = new Student("张三", 23);
        Student student2 = new Student("李四", 24);
        Student student3 = new Student("王五", 25);
        ArrayList<Student> list = new ArrayList<>();
        list.add(student);
        list.add(student2);
        list.add(student3);
        ObjectOutputStream objWriter = new ObjectOutputStream(new FileOutputStream("student2.txt"));
        objWriter.writeObject(list);
        //读:反序列化
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("student2.txt"));
        ArrayList<Student> list2 = (ArrayList<Student>) in.readObject();
        Student student4 = list2.get(2);
        System.out.println(student4);
    }
}

输出:
Student{name=‘王五’, age=25}

//Serializable 标记接口
 //要将一个类的对象,成功序列化到硬盘上,要求此类必须实现一个Serializable 这个标记接口,如果不实现,则无法序列化成功
class Student implements Serializable {
    //记着实现完 Serializable 接口 生成一个serialVersionUID
     //生成一个序列化ID 确保读写的对象,是同一个对象
    private static final long serialVersionUID = 5017795716700497273L;   
    private String name;
    private transient int age; // transient 不需要将age的数据序列化到硬盘上,可以使用这个关键字 
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class MyDemo3 {
    public static void main(String[] args) throws Exception{

        //Student student = new Student("赵六", 26);
        //ObjectOutputStream objWriter = new ObjectOutputStream(new FileOutputStream("student4.txt"));
        //objWriter.writeObject(student);

        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("student4.txt"));
        Student stu = (Student) objIn.readObject();
        String name = stu.getName();
        int age = stu.getAge();
        System.out.println(name);
        System.out.println(age);
    }
}

输出:
赵六
0


集合:Properties

  • Properties 继承Hasthtable
  • 这个集合键和值的类型,已经规定是 String
public class IODemo {
    public static void main(String[] args) {
        //集合:属性集合
       // Properties 属性集合
       // Properties 继承Hasthtable
        //这个集合键和值的类型,已经规定是 String
        Properties properties = new Properties();
        //properties.put("username","zhangsan");
       // properties.put("password","123456");
        //String username = (String) properties.get("username");
        //String password = (String) properties.get("password");
        //System.out.println(username);
        //System.out.println(password);
        //Poperties 他自己特有的存储方法
        properties.setProperty("username","zhangsan");
        properties.setProperty("password","123456");
        //取出数据
        String username = properties.getProperty("username");
        //参数2 默认值,如果这个键没有找到对应的值,就返回默认值
        String pwd = properties.getProperty("password", "654321");
        System.out.println(username);
        System.out.println(pwd);
    }
}

输出:
zhangsan
123456

public class IODemo2 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        properties.setProperty("username", "zhangsan");
        properties.setProperty("password", "123456");
        //可以将集合中的数据保存到文件中去
       properties.store(new FileOutputStream("user.properties"),null);
    }
}

user.properties文件:
在这里插入图片描述

public class IODemo3 {
    public static void main(String[] args) throws IOException {
        //假如我有了一个文本文件,数据是这种键和值的数据 键值是用等号连接的
        //HashMap<String, String> hm = new HashMap<>();
        //BufferedReader bfr = new BufferedReader(new FileReader("user.properties"));
        //String one = bfr.readLine();
        //String[] strings = one.split("=");
        //hm.put(strings[0],strings[1]);
        //String two = bfr.readLine();
        //String[] strings2 = two.split("=");
        //hm.put(strings2[0], strings2[1]);
        //System.out.println(hm);
        Properties properties = new Properties();
        properties.load(new FileReader("user.properties"));
        System.out.println(properties);
        String username = properties.getProperty("username");
        System.out.println(username);
        String passwrod = properties.getProperty("passwrod", "123");
        System.out.println(username);
        System.out.println(passwrod);
    }
}
 A:
    案例演示
    需求:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
    请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
public class IODemo4 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        properties.load(new FileReader("student.txt"));
        //判断这个键存不存在
        if (properties.containsKey("lisi")) {
            properties.setProperty("lisi", "100");//键相同,值覆盖
        }
        properties.store(new FileOutputStream("student.txt"), null);
    }
}
B:
     案例需求:
     将a.txt和b.txt两个文本文件的内容合并到c.txt
public class MyTest {
    public static void main(String[] args) throws IOException {
        File a = new File("a.txt");
        File b = new File("b.txt");
        File c = new File("c.txt");
        FileInputStream in1 = new FileInputStream(a);
        FileInputStream in2 = new FileInputStream(b);
        FileOutputStream out = new FileOutputStream(c);
        ArrayList<FileInputStream> list = new ArrayList<>();
        list.add(in1);
        list.add(in2);
        //遍历集合 写数据
        int len = 0;
        byte[] bytes = new byte[1024];
        for (FileInputStream in : list) {
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
                out.flush();
            }
            in.close();
        }
        out.close();
    }
}

SequenceInputStream流
SequenceInputStream: 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

//通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2)
SequenceInputStream(InputStream s1, InputStream s2)
public class MyTest2 {
    public static void main(String[] args) throws IOException {
        File a = new File("a.txt");
        File b = new File("b.txt");
        File c = new File("c.txt");
        FileInputStream in1 = new FileInputStream(a);
        FileInputStream in2 = new FileInputStream(b);
        //创建一个顺序流,传入两个输入流
        SequenceInputStream in = new SequenceInputStream(in1, in2);
        FileOutputStream out = new FileOutputStream(c);
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes, 0, len);
            out.flush();
        }
        in.close();
        in1.close();
        in2.close();
        out.close();
    }
}
A:
     案例需求:
     将三个文件中的内容,合并到一个文件中
     用顺序流做
public class MyTest3 {
    public static void main(String[] args) throws IOException {
        //将三个文件中的内容,合并到一个文件中
        File a = new File("a.txt");
        File b = new File("b.txt");
        File c = new File("c.txt");
        FileInputStream in1 = new FileInputStream(a);
        FileInputStream in2 = new FileInputStream(b);
        FileInputStream in3 = new FileInputStream(c);
        //用顺序流做
        SequenceInputStream in4 = new SequenceInputStream(in1, in2);
        SequenceInputStream in5 = new SequenceInputStream(in4, in3);
    }
}

C:
        案例需求:
        将一个music.mp3文件, 拆分成多个小文件, 再将多个小文件, 合并成一个mp3文件
         mp3 4.5M  一份拆成 1M  总共拆分五份  最后一份是0.5M
         最后将5份 再合成一份
public class MyTest5 {
    public static void main(String[] args) throws IOException {
        // 1. 先封装源文件
        File file1 = new File("E:\\music");
        File[] files = file1.listFiles();
        Vector<FileInputStream> v = new Vector<>();
        for (File f : files) {
            if (f.isFile() && f.getName().endsWith(".mp3")) {
                FileInputStream in = new FileInputStream(f);
                v.add(in);
            }
        }

        SequenceInputStream sin = new SequenceInputStream(v.elements());
        byte[] bytes = new byte[1024 * 1024];
        int len = 0;
        FileOutputStream out = new FileOutputStream("E:\\夜夜夜夜-齐秦.mp3");
        while ((len = sin.read(bytes)) != -1) {
            out.write(bytes, 0, len);
            out.flush();
        }
        sin.close();
        out.close();

        return;
    }

    private static void chaifen() throws IOException {
        File file = new File("夜夜夜夜.mp3");
        //2.封装一个文件夹
        File file1 = new File("E:\\music");
        if (!file1.exists()) {
            file1.mkdirs();
        }
        FileInputStream in = new FileInputStream(file);

        //拆分文件
        byte[] bytes = new byte[1024 * 1024];
        int len = 0;
        int i = 1;
        while ((len = in.read(bytes)) != -1) {
            FileOutputStream out = new FileOutputStream(new File(file1, (i++) + ".mp3"));
            out.write(bytes, 0, len);
            out.close();
        }
        in.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值