javaIO流(基础二)

学习目标

1.熟练掌握File类应用

一、File

1.1 File 类描述

<img src="images/1.png" />

1.2 File类构造方法

<img src="images/2.png" />

@Test // 1.构造方法只是抽象路径
public void test1() {
    //1. \代表window操作系统下一级访问路径  / 代表linux操作系统访问路径
    File file = new File("c:/aa");
    System.out.println(file);
    //2. 创建file实例 并指定抽象路径的父路径 和子路径
    File file2 = new File("c:/aa","bb");
    System.out.println(file2);
    //3. 创建file实例 并指定抽象路径的父路径 和子路径
    File file3 = new File(file2,"cc");
    System.out.println(file3);
}

1.3 File类普通方法

1.3.1 创建文件、目录
@Test//1.创建文件和目录
public void test1() throws IOException {
    File file = new File("c:\\a.txt");
    //1.创建文件
    boolean tag = file.createNewFile();
    System.out.println(tag);
    //2.创建目录 
    File file2 = new File("c:\\aa");
    boolean mkdir = file2.mkdir(); 
    System.out.println(mkdir);
    //3.创建多级目录
    File file3 = new File("c:\\a\\b\\c");
    //file3.mkdir(); 创建一个目录
    file3.mkdirs();
}
1.3.2 相对路径与绝对路径
@Test //相对路径与绝对路径
    public void test4() throws IOException {
        //1.相对于当前工程而言 :相对路径
        File file = new File("src//a.txt");
        file.createNewFile();
        //2.绝对路径
        File file2  = new File("c://aa//bb");
    }
1.3.3 删除文件、目录
@Test//1.删除文件或者目录
public void test2() throws IOException {
    File file = new File("c:\\a.txt");
    //file.createNewFile();
    //1.删除文件
    System.out.println(file.delete());
    File file2 = new File("c:\\aa");
    //file2.mkdir();
    //2.删除目录
    file2.delete();
    //3.只会删除ccc 因为抽象路径一直是c:\aaa\bbb\ccc 不会因为操作而改变
    File file3 = new File("c:\\aaa\\bbb\\ccc");
    file3.mkdirs();
    file3.delete();
    file3.delete();
    file3.delete();
    System.out.println(file3);
    //4.正确的级联删目录应该如下操作
    file3.getParentFile().delete();
    file3.getParentFile().getParentFile().delete();
}
1.3.4修改文件、目录
@Test //修改文件或者目录的名字(可以完成剪切操作)
public void test3() throws IOException {
    /*File file  = new File("c:\\aa\\bb\\cc");
        file.mkdirs();
        //1.修改文件目录
        file.renameTo(new File("c:\\aa\\bb\\ccc"));
        File file2 = new File("c:\\a.txt");
        file2.createNewFile();
        //2.修改文件
        file2.renameTo(new File("c:\\b.txt"));
        //3.剪切操作
*/        File file3 = new File("c:\\b.txt");
    file3.renameTo(new File("c:\\aa\\b.txt"));
}
1.3.5 File类的查询方法
@Test //查询方法
    public void test5() throws IOException {
        File file = new File("c://a.txt");
        //1.以e开头开头的方法
        //1.1判断file是否存在
        boolean exists = file.exists();
        System.out.println(exists);
        //2.以is开头的方法
        //2.1是否是绝对路径
        System.out.println(file.isAbsolute());
        //2.2是否是目录
        System.out.println(file.isDirectory());
        //2.3是否是文件
        System.out.println(file.isFile());
        //2.4是否是隐藏文件
        System.out.println(file.isHidden());
        //3.以can开头的方法
        //3.1 是否是可以执行的文件
        System.out.println(file.canExecute());
        //3.2是否是可读文件
        System.out.println(file.canRead());
        //3.3是否是可写文件
        System.out.println(file.canWrite());
        //4.以get开头的方法
        File fi = new File("c:\\");
        //4.1获得绝对路径 String类型
        System.out.println(fi.getAbsolutePath());
        //4.2获得剩余空间字节
        System.out.println(fi.getFreeSpace()/(double)(1024*1024*1024));
        //4.3获得文件或者目录的名字
        File file2  = new File("c:\\aa");
        System.out.println(file2.getName());
        //4.4获得当前路径
        System.out.println(fi.getPath());
        //4.4 当前路径总共空间大小 单位字节
        System.out.println(fi.getTotalSpace()/(double)(1024*1024*1024));
        //4.5 获得绝对路径 返回值是File类型
        System.out.println(fi.getAbsoluteFile());
        //4.6获得父路径返回值file
        System.out.println(fi.getParentFile());
        //4.7获得绝对路径返回字符串
        System.out.println(fi.getParent());
        //5.以l开头的方法
        //5.1返回的是当前路径的子目录 返回值是字符串数组
        String[] list = fi.list();
        for(String str : list) {
            System.out.println(str);
        }
        //5.2返回当前路径的子目录返回值是File[]
        File[] files = fi.listFiles();
        for(File f : files) {
            System.out.println(f);
        }
        //5.3 返回当前路径的最后修改时间
        System.out.println(
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").
                format(new Date(fi.lastModified())));
        File file4 = new File("c:\\aa.txt");
        //5.4返回当前文件内容的字节大小
        System.out.println(file4.length());
    }

1.4综合练习题

  1. 判断指定目录下是否有后缀名为.jpg的文件,如果有,就输出该文件名称
  2. 遍历指定目录所有文件名称,包括子文件目录中的文件。
  3. 模仿dos界面

二、IO流原理及分类

2.1 IO流原理

  • I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。
  • Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
  • java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
  • 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
  • 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。

<img src="images/3.png" />

2.2 IO流分类

  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流

<img src="images/5.png" />

三、IO流的结构体系

3.1 IO 流抽象基类介绍

  • Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。
  • 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

<img src="images/4.png" />

3.2 IO 流的体系

<img src="images/6.png" />

3.3 节点流与处理流的理解

  • 节点流:直接从数据源或目的地读写数据

<img src="images/7.png" />

  • 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

<img src="images/8.png" />

四、IO流的抽象基类介绍

4.1 字节流

4.1.1 InputStream

<img src="images/9.png" />

<img src="images/10.png" />

4.1.2 OutputStream

<img src="images/11.png" />

<img src="images/12.png" />

4.2字符流

4.2.1 Reader

<img src="images/13.png" />

<img src="images/15.png" />

4.2.2 Writer

<img src="images/16.png" />

<img src="images/17.png" />

五、节点流(文件流)

5.1 字节输入流(读取字节文件)

5.1.1 字节流描述

<img src="images/18.png" />

5.1.2 构造方法

<img src="images/19.png" />

//1.构造方法
@Test
public void test1() throws IOException {
    //1.构造方法 将内存到磁盘a.txt文件的连接打开。如果不存报文件找不到异常
    FileInputStream fileInputStream = new FileInputStream("c://as.txt");
    System.out.println(fileInputStream);
    File file = new File("c://a.txt");
    //2.构造方法 将内存到磁盘a.txt文件的连接打开。
    FileInputStream fileInputStream2 = new FileInputStream(file);
    System.out.println(fileInputStream2);
}
5.1.3普通方法

<img src="images/20.png" />

@Test //2.重点方法
public void test2() throws IOException {
    //1.构造方法 将内存到磁盘a.txt文件的连接打开。
    FileInputStream fileInputStream = new FileInputStream("c://a.txt");
    //1.读取一个字节 并返回当前字节,如果读完返回-1;
    /*int read = fileInputStream.read();
        System.out.println(read);
        read = fileInputStream.read();
        System.out.println(read);
        read = fileInputStream.read();
        System.out.println(read);
        read = fileInputStream.read();
        System.out.println(read);
        read = fileInputStream.read();
        System.out.println(read); */
    //2.将磁盘文件数据读取到byte数组,返回值代表读了几个字节。如果读完返回-1
    byte[] bb = new byte[3];
    int length = fileInputStream.read(bb);
    System.out.println(length);
    System.out.println(new String(bb,0,length));
    length = fileInputStream.read(bb);
    System.out.println(length);
    //System.out.println(new String(bb));
    System.out.println(new String(bb,0,length));
    length = fileInputStream.read(bb);
    System.out.println(length);
    //3.关闭连接方法
    fileInputStream.close();
}
@Test //5.其余方法了解
public void test5() throws IOException {
    FileInputStream fileInputStream = new FileInputStream("c://a.txt");
    /*    //1.磁盘文件还剩余多少没有读取
        int available = fileInputStream.available();
        System.out.println(available);
        fileInputStream.read();
        available = fileInputStream.available();
        System.out.println(available);*/
    //2.skip 跳过n个字节在读
    fileInputStream.skip(2);
    System.out.println(fileInputStream.read());
}
5.1.4 注意点
  • 定义文件路径时,注意:可以用“/”或者“\”。
  • 在读取文件时,必须保证该文件已存在,否则报异常。
  • 字节流操作字节,比如:.mp3,.avi,.rmvb,mp4,.jpg,.doc,.ppt
  • 字符流操作字符,只能操作普通文本文件。最常见的文本文件:.txt,.java,.c,.cpp 等语言的源代码。尤其注意.doc,excel,ppt这些不是文 本文件
5.1.5 循环读取字节文件
@Test //3.循环读取字节文件 1
public void test3() {
    FileInputStream fileInputStream = null;
    try {
        fileInputStream = new FileInputStream("c://a.txt");
        int read;
        while((read=fileInputStream.read())!=-1) {
            System.out.print((char)read);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}
    }

}
@Test //4.循环读取字节文件 2
public void test4() {
    FileInputStream fileInputStream = null;
    try {
        fileInputStream = new FileInputStream("c://a.txt");
        byte[] bb = new byte[3];
        int len;
        while((len=fileInputStream.read(bb))!=-1) {
            System.out.print(new String(bb,0,len));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}
    }

}

5.2 字节输出流(写入字节文件)

5.2.1构造方法

<img src="images/21.png" />

@Test//构造方法 
public void test1() throws IOException {
    //1.必须保证父路径存在,才知道往哪个路径下写文件数据否则报错FileNotFoundException
    //2.该构造方法打开内存到磁盘的连接准备写数据,未开启续写模式,也就是重新覆盖原来的数据。
    //FileOutputStream fileOutputStream = new FileOutputStream("c:\\b.txt");
    //功能一样只是参数类型不同
    //FileOutputStream fileOutputStream = new FileOutputStream(new File("c:\\b.txt"));        
    //3.该构造方法如果第二个参数写false和上面的构造方法功能一样,如果写true代表开启续写模式
    FileOutputStream fileOutputStream = new FileOutputStream("c:\\b.txt", true);
    //功能一样只是参数类型不同
    //FileOutputStream fileOutputStream = new FileOutputStream(new File("c:\\b.txt"),true);
    //System.out.println(fileOutputStream);
    fileOutputStream.write(97);

}
5.2.1普通方法

<img src="images/22.png" />

@Test//普通方法
public void test2() throws IOException {
    FileOutputStream fileOutputStream = new FileOutputStream("c:\\b.txt");
    //1.写入一个字节
    fileOutputStream.write(97);
    //2.写入一个字节数组
    fileOutputStream.write("abc".getBytes());
    //3.写入一个字节数组并指定从几下标开始,写了几个字节 字节强行操作字符可能出现乱码这里演示
    fileOutputStream.write("我爱你中国".getBytes(), 0, 5);
    //4.将内存数据刷到磁盘
    fileOutputStream.flush(); 
    //5.将内存数据刷到磁盘并关闭资源
    fileOutputStream.close();
}
5.2.2 注意点
  • 在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文 件将被覆盖。
  • 如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖, 在文件内容末尾追加内容。

5.3 字节流循环读写

练习:将一个图片1.jpg写入到另一个地方叫2.jpg

@Test// 复制字节文件
public void test3() {
    //1.创建对象
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream = null;
    try {
        fileInputStream = new FileInputStream("c://1.jpg");
        fileOutputStream = new FileOutputStream("c://2.jpg");
        //2.循环读写
        int read;
        while((read=fileInputStream.read())!=-1) {
            fileOutputStream.write(read);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //3.关闭资源 后开先关
    try {fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}
    try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}

}
@Test// 复制字节文件2
public void test4() {
    //1.创建对象
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream = null;
    try {
        fileInputStream = new FileInputStream("c://1.jpg");
        fileOutputStream = new FileOutputStream("c://3.jpg");
        //2.循环读写
        byte[] bb = new byte[1024*1024];
        int len;
        while((len=fileInputStream.read(bb))!=-1) {
            fileOutputStream.write(bb,0,len);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //3.关闭资源 后开先关
    try {fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}
    try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}
    }

5.4字符流读取流

5.4.1构造方法

<img src="images/23.png" />

@Test//1.构造方法
public void test1() throws FileNotFoundException {
    FileReader fileReader = new FileReader("c://a.txt");
    FileReader fileReader2 = new FileReader("c://a.txt");
    System.out.println(fileReader);
    System.out.println(fileReader2);
}
5.4.2 普通方法

<img src="images/24.png" />

@Test//2.普通方法
public void test2() throws IOException {
    FileReader fileReader = new FileReader("c://b.txt");
    //1.一个字符一个字符的读取,返回当前字符;如果读完返回-1
    int read = fileReader.read();
    System.out.println((char)read);
    //2.读取字符到字符数组,返回值代表读了几个字符,如果读完返回-1
    char[] cc = new char[3];
    int len = fileReader.read(cc);
    System.out.println(len);
    System.out.println(new String(cc,0,len));
}

5.5字符流写入流

5.5.1 构造方法

<img src="images/25.png" />

@Test//1.构造方法
public void test1() throws IOException {
    //1.构造方法,没有开启续写模式
    FileWriter fileWriter = new FileWriter(new File("c://b.txt"));
    //2.构造方法,没有开启续写模式
    FileWriter fileWriter2 = new FileWriter("c://b.txt");
    //3.构造方法 开启续写模式
    FileWriter fileWriter3 = new FileWriter(new File("c://b.txt"),true);
    //4.构造方法开启续写模式
    FileWriter fileWriter4  = new FileWriter("c://b.txt", true);
}
5.5.2普通方法

<img src="images/26.png"/>

@Test //2.普通方法
public void test2() throws IOException {
    FileWriter fileWriter = new FileWriter("c://b.txt");
    //1.写入一个字符
    fileWriter.write(97);
    //2.写入一个字符数组
    fileWriter.write("我爱你中国".toCharArray());
    //3.写入字符串
    fileWriter.write("我爱你中国");
    //4.写入一个字符数组并指定从几下标开始,写入多少个
    fileWriter.write("我爱你中国".toCharArray(), 0, 3);
    //5.写入一个字符串并指定从几下标开始,写入多少个
    fileWriter.write("我爱你中国", 0, 3);
    //6.注意:字符数据必须手动刷入数据
    fileWriter.flush();
    //7.将内存数据刷到磁盘并关闭资源
    fileWriter.close();
}

5.6 字符流循环读写

@Test //3.循环读写字符
public void test3() {
    //1.创建对象
    FileReader fileReader = null;
    FileWriter fileWriter = null;
    try {
        fileReader = new FileReader("c://a.txt");
        fileWriter = new FileWriter("c://b.txt");
        //2.循环读写
        int read;
        while((read=fileReader.read())!=-1) {
            fileWriter.write(read);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {fileWriter.close();} catch (IOException e) {e.printStackTrace();}
        try {fileReader.close();} catch (IOException e) {e.printStackTrace();}
    }
}
@Test //3.循环读写字符
public void test4() {
    //1.创建对象
    FileReader fileReader = null;
    FileWriter fileWriter = null;
    try {
        fileReader = new FileReader("c://a.txt");
        fileWriter = new FileWriter("c://b.txt");
        //2.循环读写
        char[] cc = new char[10];
        int len;
        while((len=fileReader.read(cc))!=-1) {
            fileWriter.write(cc, 0, len);
            fileWriter.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {fileWriter.close();} catch (IOException e) {e.printStackTrace();}
        try {fileReader.close();} catch (IOException e) {e.printStackTrace();}
    }
}

六、装饰设计模式

装饰设计模式是对一个类原有的功能进行先调用,在装饰。

//定义一个手机类
public class Phone {
    //1.玩游戏
    public void play(String param) {
        System.out.println("玩游戏");
        if(param.equals("胜利")) {
            System.out.println("接着玩");
        }else {
            System.out.println("摔手机");
        }
    }
}
// 手机壳 装饰手机
public class PhoneShell {
    //1.定义手机属性
    private Phone phone;

    public PhoneShell(Phone phone) {
        this.phone = phone;
    }
    public void play(String param) {
        phone.play(param);
        System.out.println("咦,没摔坏,有手机壳");
    }
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.play("失败");
        PhoneShell phoneShell = new PhoneShell(phone);
        phoneShell.play("失败");
    }
}

七、缓冲流

7.1缓冲流概述

  • 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区
  • 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
  • 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流
  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流
  • flush()方法的使用:手动将buffer中内容写入文件
  • 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出

<img src="images/27.png" />

<img src="images/28.png" />

7.2 缓冲流分类

  • 字节流
    • 字节输入流 BufferedInputStream
    • 字节输出流BufferedOutputStream
  • 字符流
    • 字符读取流BufferedReader
    • 字符写入流BufferedWriter
@Test //普通方法
public void test2() throws Exception {
    //1.构造方法 创建字符缓冲输入流 缓冲大小8k
    BufferedInputStream bufferedInputStream = 
        new BufferedInputStream(new FileInputStream("c://a.txt"));
    //2.读取一个字节并返回 如果读完返回-1
    int read = bufferedInputStream.read();
    //3.读取n个字节到字节数据,返回值代表读了几个字节读完返回-1
    byte[] bb = new byte[3];
    int len = bufferedInputStream.read(bb);
    //4.关闭资源 关闭外部的处理流就会自动关闭里面的字节流资源
    bufferedInputStream.close();
}

7.3练习题

练习题1

将一个字节文件复制一份

@Test //复制字节文件
public void test1() {
    //1创建对象
    BufferedInputStream bufferedInputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    try {
        bufferedInputStream = new BufferedInputStream(new FileInputStream("c://1.jpg"));
        bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("c://4.jpg"));
        //2.循环读写
        int read;
        while((read=bufferedInputStream.read())!=-1) {
            bufferedOutputStream.write(read);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}
        try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}
    }

}
@Test //复制字节文件
public void test2() {
    //1创建对象
    BufferedInputStream bufferedInputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    try {
        bufferedInputStream = new BufferedInputStream(new FileInputStream("c://1.jpg"));
        bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("c://4.jpg"));
        //1.定义byte数组
        byte[] bb = new byte[1024];
        int len;
        while((len=bufferedInputStream.read(bb))!=-1) {
            bufferedOutputStream.write(bb,0,len);
            bufferedOutputStream.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}
        try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}
    }

}

练习题2

将一个字符文件复制一份

//复制字符文件
@Test
public void test3() {
    //1.创建对象
    BufferedReader bufferedReader = null;
    BufferedWriter bufferedWriter = null;
    try {
        bufferedReader = new BufferedReader(new FileReader("c://a.txt"));
        bufferedWriter = new BufferedWriter(new FileWriter("c://b.txt"));
        //2.循环读写
        int read;
        while((read=bufferedReader.read())!=-1) {
            bufferedWriter.write(read);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {bufferedWriter.close();} catch (IOException e) {e.printStackTrace();}
        try {bufferedReader.close();} catch (IOException e) {e.printStackTrace();}
    }

}
@Test
public void test4() {
    //1.创建对象
    BufferedReader bufferedReader = null;
    BufferedWriter bufferedWriter = null;
    try {
        bufferedReader = new BufferedReader(new FileReader("c://a.txt"));
        bufferedWriter = new BufferedWriter(new FileWriter("c://b.txt"));
        //2.循环读写
        char[] cc = new char[10];
        int len;
        while((len=bufferedReader.read(cc))!=-1) {
            bufferedWriter.write(cc, 0, len);
            bufferedWriter.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {bufferedWriter.close();} catch (IOException e) {e.printStackTrace();}
        try {bufferedReader.close();} catch (IOException e) {e.printStackTrace();}
    }

}
@Test
public void test5() {
    //1.创建对象
    BufferedReader bufferedReader = null;
    BufferedWriter bufferedWriter = null;
    try {
        bufferedReader = new BufferedReader(new FileReader("c://a.txt"));
        bufferedWriter = new BufferedWriter(new FileWriter("c://b.txt"));
        //2.循环读写 读一行刷一行
        String line;
        while((line=bufferedReader.readLine())!=null) {
            bufferedWriter.write(line);
            //写入换行符
            bufferedWriter.newLine();
            bufferedWriter.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {bufferedWriter.close();} catch (IOException e) {e.printStackTrace();}
        try {bufferedReader.close();} catch (IOException e) {e.printStackTrace();}
    }

}

八、转换流

8.1概述

  • 转换流提供了在字节流和字符流之间的转换
  • Java API提供了两个转换流: InputStreamReader:将InputStream转换为Reader
  • OutputStreamWriter:将Writer转换为OutputStream 转换为Writer
  • 很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能。

<img src="images/29.png" />

8.2 综合练习

@Test//1.构造方法
public void test1() throws Exception {
    //1.按照平台默认编码集读取文件
    InputStreamReader inputStreamReader = 
        new InputStreamReader(new FileInputStream("c:\\a.txt"));
    //2.按照gbk编码集读取文件
    InputStreamReader inputStreamReader2 = 
        new InputStreamReader(new FileInputStream("c:\\a.txt"),"gbk"); 
    //3.将数据按照平台默认编码集写入到b.txt文件
    OutputStreamWriter writer = 
        new OutputStreamWriter(new FileOutputStream("c:\\b.txt"));
    //4.将数据按照gbk编码集写入到b.txt文件
    OutputStreamWriter writer2 = 
        new OutputStreamWriter(new FileOutputStream("c:\\b.txt"),"gbk");
}
@Test//2.循环读写//将a.txt文件 读写到b.txt文件 要求转为utf-8编码
public void test2() {
    //1.创建字符输入流
    InputStreamReader reader = null;
    //2.将数据按照gbk编码写入到b.txt文件
    OutputStreamWriter writer = null;
    try {
        reader = new InputStreamReader(new FileInputStream("c:\\a.txt"),"gbk");
        writer = new OutputStreamWriter(new FileOutputStream("c:\\b.txt"),"utf-8");
        int read;
        while((read=reader.read())!=-1){
            writer.write(read);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        try {writer.close();} catch (IOException e) {e.printStackTrace();}
        try {reader.close();} catch (IOException e) {e.printStackTrace();}
    }
}
@Test//2.
//1.将a.txt(gbk)文件内如读写到b.txt文件 要求转为utf-8编码
//2.转换的过程中加入转换缓存
public void test3() {
    //1.创建对象
    BufferedReader bufferedReader = null;
    BufferedWriter bufferedWriter = null;
    try {
        bufferedReader = new BufferedReader(
            new InputStreamReader(
                new FileInputStream("c:\\a.txt"),"gbk"));
        bufferedWriter = new BufferedWriter(
            new OutputStreamWriter(
                new FileOutputStream("c:\\b.txt"),"utf-8"));
        //2.循环读写
        String line;
        while((line=bufferedReader.readLine())!=null) {
            bufferedWriter.write(line);
            bufferedWriter.newLine();
            bufferedWriter.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3.关闭资源
        try {bufferedWriter.close();} catch (IOException e) {e.printStackTrace();}
        try {bufferedReader.close();} catch (IOException e) {e.printStackTrace();}
    }
}

九、标准输入输出流(了解)

  • System.in和System.out分别代表了系统标准的输入和输出设备
  • 默认输入设备是:键盘,输出设备是:显示器
  • System.in的类型是InputStream
  • System.out的类型是PrintStream
  • 重定向:通过System类的setIn,setOut方法对默认设备进行改变。 注意:此方法一定在使用标准流之前调用。
    • public static void setIn(InputStream in)
    • public static void setOut(PrintStream out)
//标准输入输出流
public class SystemIODemo {
    @Test //输入流演示
    public void test1() throws IOException {
        //1.标准输入流(输入设备是键盘)
        InputStream in = System.in;
        int read;
        while((read=in.read())!=-1) {
            System.out.print((char)read);
        }
    }
    @Test //输出流演示
    public void test2() throws IOException {
        //1.标准输出流(输出设备屏幕)
        PrintStream out = System.out;
        out.print("哈哈");    
    }
    @Test //输入流演示切换设备
    public void test3() throws IOException {
        //1.切换输入设备
        System.setIn(new FileInputStream("c:\\b.txt"));
        //1.标准输入流(输入设备是键盘)
        InputStream in = System.in;
        int read;
        while((read=in.read())!=-1) {
            System.out.print((char)read);
        }
    }
    @Test //输出流切换设备演示
    public void test4() throws IOException {
        System.setOut(new PrintStream("c:\\c.txt"));
        //1.标准输出流(输出设备屏幕)
        PrintStream out = System.out;
        out.print("哈哈");    
    }
}

十、打印流(了解)

  • 实现将基本数据类型的数据格式转化为字符串输出
  • 打印流:PrintStream和PrintWriter
    • 提供了一系列重载的print()和println()方法,用于多种数据类型的输出
    • PrintStream和PrintWriter的输出不会抛出IOException异常
    • PrintStream和PrintWriter有自动flush功能
    • PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。 在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。
    • System.out返回的是PrintStream的实例
/**
  1.字节打印流
*/
public class PrintStreamDemo {
  @Test
  public void test1() throws FileNotFoundException {
      //1.构造方法可以指定打印的文件,也可以指定打印的流:如果指定打印的流必须是字节流
      //PrintStream printStream = new PrintStream("c://d.txt");
      PrintStream printStream = new PrintStream(new FileOutputStream("c://e.txt"));
      printStream.print(true);
      printStream.print("我爱你中国");
  }
}
/**
    1.字符打印流
 */
public class PrintWrierDemo {
    @Test
    public void test1() throws IOException {
        //1.通过构造方法指定打印的文件或者打印的流
        //PrintWriter printWriter = new PrintWriter("c:\\f.txt");
        //2.开启自动线冲洗。  也就是换行就自动刷新数据
        PrintWriter printWriter2 = 
                new PrintWriter(new FileWriter("c:\\g.txt"),true);
        //1.不会自动刷新,需要手动刷新
        printWriter2.println("true");
        printWriter2.println("我爱你中国");
        //printWriter2.flush();
    }
}

十一、数据流(了解)

  • 为了方便地操作Java语言的基本数据类型和String的数据,可以使用数据流。
  • 数据流有两个类:(用于读取和写出基本数据类型、String类的数据)
  • DataInputStream 和 DataOutputStream
  • 分别“套接”在 InputStream 和 OutputStream 子类的流上
  • DataInputStream中的方法
    • boolean readBoolean()
    • byte readByte()
    • char readChar()
    • float readFloat()
    • double readDouble()
    • short readShort()
    • long readLong()
    • int readInt()
    • String readUTF() void readFully(byte[] b)
  • DataOutputStream中的方法
    • 将上述的方法的read改为相应的write即可。
@Test
public void test1() throws IOException { 
    //1.字节数据写入流 数据输出流使应用程序以便携式方式将原始Java数据类型写入输出流。
    DataOutputStream dataOutputStream = 
        new DataOutputStream(new FileOutputStream("c://aa.txt"));
    dataOutputStream.writeInt(12);
    dataOutputStream.writeBoolean(true);
    dataOutputStream.flush();
    //2.字节数据读取流 
    //数据输入流使应用程序以便携式方式将原始Java数据类型读取输入流。 
    DataInputStream dataInputStream = 
        new DataInputStream(new FileInputStream("c://aa.txt"));
    int readInt = dataInputStream.readInt();
    System.out.println(readInt);
    boolean readBoolean = dataInputStream.readBoolean();
    System.out.println(readBoolean);
}

十二、对象流

12.1 对象流介绍

  • ObjectOutputStream: 该类用于处理序列化问题
  • ObjectInputStream : 该类用于处理反序列化问题

1.2.2 序列化与反序列化介绍

  • 序列化:将内存中的Java对象转换成平台无关的二进制流存储到磁盘上或者在网络上传输的过程叫序列化 。
  • 反序列化:将磁盘上或者网络上的二进制流转换成内存上可以运行的java对象的过程 。

12.3 序列化与反序列化要求

  • ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
  • 要序列化的对象必须实现序列化接口
    • Serializable
    • Externalizable
  • 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:private static final long serialVersionUID;
    • serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象 进行版本控制,有关各版本反序列化时是否兼容。
    • 如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自 动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议, 显式声明。

12.4使用序列化流序列化对象

  • 若某个类实现了 Serializable 接口,该类的对象就是可序列化的:
    • 创建一个 ObjectOutputStream
    • 调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象
    • 注意写出一次,操作flush()一次
  • 反序列化
    • 创建一个 ObjectInputStream
    • 调用 readObject() 方法读取流中的对象
  • 强调:如果某个类的属性不是基本数据类型或 String 类型,而是另一个 引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的Field 的类也不能序列化

案例

public class ObjectStreamDemo {
    @Test
    public void test1() throws IOException, ClassNotFoundException {
        //1.创建序列化对象
        ObjectOutputStream objectOutputStream =
                new ObjectOutputStream(new FileOutputStream("c:\\b.txt"));
        //2.序列化数据到磁盘
        objectOutputStream.writeObject("hello");

        //3.创建反序列化对象
        ObjectInputStream objectInputStream = 
                new ObjectInputStream(new FileInputStream("c:\\b.txt"));
        //4.反序列化
        Object readUTF = objectInputStream.readObject();
        System.out.println(readUTF);
    }
    /**
     * 1.序列化要求
     *     1.实现序列化接口
     *     2.定义序列id 
     *     3.被static和transient修饰的属性不会被序列化
     */
    @Test
    public void test2() throws IOException, ClassNotFoundException{
        //1.序列化过程
        ObjectOutputStream objectOutputStream = 
                new ObjectOutputStream(new FileOutputStream("c:\\e.txt"));
        User user = new User();
        user.setId(1);
        user.setName("小黑");
        user.setPwd("123456");
        objectOutputStream.writeObject(user);
    }
    @Test//序列要求
    public void test3() throws IOException, ClassNotFoundException {
        //2.反序列化过程
        ObjectInputStream objectInputStream = 
                new ObjectInputStream(new FileInputStream("c:\\e.txt"));
        User u = (User)objectInputStream.readObject();
        System.out.println(u);
        System.out.println(u.j);
        System.out.println(User.i);

    }
}

十三、第三方jar包工具类

13.1 导入jar包

<img src="images/30.png" />

<img src="images/31.png" />

13.2 使用工具类

@Test
public void test1() throws IOException {
    //1.复制文件
    FileUtils.copyFile(new File("c:\\1.jpg"),new File("c:\\2.jpg"));
}
  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Highly_倾斜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值