IO流学习笔记

IO流

File类的理解

  • File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)。

  • File类声明在java.io包下。

  • File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。

  • 后续File类的对象常会作为参数传递流到构造器中,指明读取或写入的“终点”。

    File的实例化

  • 常用改造器

    File(String filepath)
    File(String parentPath,String childPath)
    File(File parentPath,String childPath)
    
  • 路径的分类

    • 相对路径

    • 绝对路径

    • IDEA中:如果使用JUnit中的单元测试方法测试,相对路径即为当前Module下。

      ​ 如果使用main()测试,相对路径即为当前的Project下。

  • 路径分隔符

    • windows和DOS系统默认使用“\”来表示
    • UNIX和URL使用“/来表示”
  • File类的常用方法

IO流的分类

  • 数据的流向

    • 输入流
    • 输出流
  • 操作数据单位

    • 字节流:所有、图片、视频、音乐等
    • 字符流:字符、普通文本等
  • 流的角色

    • 节点流
    • 处理流
  • 流的体系结构

    抽象基类节点流(或文件流)缓冲流(处理流的一种)
    InputStreamFileInputStreamBufferedInputStream
    OutputStreamFileOutputStreamBufferedOutputStream
    ReaderFileReaderBufferedReader
    WriterFileWriterBufferedWriter
  • java 提供了那些流?每个流的特点?每个流的常用方法?

  • java中所有的流都在:java.io.*;下

  • 四大家族 都是抽象类:

    • java.io.InputStream 字节输入流
    • java.io.OutputStream 字节输出流
    • java.io.Reader 字符输入流
    • java.io.Writer 字符输出流
  • 所有输出流都实现了java.io.Flushable接口,都是可刷新的,都有flush()方法。

  • 这个刷新表示将管道当中的剩余未输出的数据强行输出完(清空管道)刷新的作用就是清空管道。

  • 注意:如果没有flush()可能会导致丢失数据。
    “类名”以Stream结尾的都是字节流;以“Reader”或“Writer”结尾的都是字符流。

    • 转换流:属于字符流,

      • java.io.InputStreamReader(将字节输入流转换成字符输入流)
      • java.io.OutputStreamWriter(将字符输出流转换成字节输出流)
    • 对象专属流

      • 用于存储和读取基本数据类型或对象的处理流。它的强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原回来。
      • ObjectInputStream(掌握)
        • 反序列化(DeSerialize):组合对象 将硬盘上的数据重新恢复到内存中,恢复成java对象。
      • ObjectOutputStream(掌握)
        • 序列化(Serialize):拆分对象 java对象存储到文件中,将java对象的状态保存下来的过程。
      • 参与序列化和反序列化的对象,必须实现Serializable接口,起到标志作用,jvm看到这个接口后,会为该类自动生成一个序列版本号。当前类提供一个全局变量:serialVersionUID
      • 对象序列化机制:允许把内存中的java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存到磁盘,或通过网络将这种二进制流传输到另一个网络节点。(序列化)当从其他程序获取了这种二进制流,就可以恢复成原来的Java对象。(反序列化)

流的读、写、复制

  • 读数据示例

    *
        将day02的hello.txt文件内容读入程序中,并输出控制台
        read():返回读入的一个字符。如果达到文件末尾,返回-1
        read(char[] c):返回每次读入c数组的字符的个数。如果达到文件末尾,返回-1*/
    //实例化File对象,指明要操作的文件
            File file = new File("day02\\hello.txt");
            System.out.println(file.getAbsolutePath());
            //提供具体的流
            FileReader f = null;
            try {
                f = new FileReader(file);
    //            方式一
    //            int data;
    //            while ((data = f.read()) != -1){
    //                System.out.print((char)data);
    //            }
    //            方式二
                char[] c = new char[5];
                int len;
                while ((len=f.read(c))!=-1){
    //                for (int i=0; i<len;i++){
    //                    System.out.print(c[i]);
    //                }
                    String str = new String(c,0,len);
                    System.out.print(str);
                }
    
  • 写数据示例

    /*
    	从内存中写出数据到硬盘的文件里
        说明:
        1.输出操作,对应的File可以不存在。
        2.File对应的硬盘文件如果不存在,在输出过程中,会自动创建此文件。
        File对应的硬盘文件如果存在:
        如果流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件覆盖;
        如果刘使用的构造器是:FileWriter(file,true):对原有文件追加内容。
    */
    File file = new File("day02\\hello1.txt");
            FileWriter fileWriter = null;
            try {
                fileWriter = new FileWriter(file);
                fileWriter.write("I am Student!\n");
                fileWriter.write("Hello World!");
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    fileWriter.flush();
                    if (fileWriter!=null){
                        fileWriter.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
  • 复制文本文件内容

    /*
        复制文件内容
     */
            //需要写入的文件
            File file1 = new File("day02\\hello.txt");
            //需要读入的文件
            File file2 = new File("day02\\hello1.txt");
    
            //获取读流、写流
            FileWriter w = null;
            FileReader r = null;
            try {
                r = new FileReader(file2);
                w = new FileWriter(file1);
                char[] c = new char[5];
                int len;
                while ((len=r.read(c))!=-1){
                    w.write(c,0,len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (r!=null){
                    try {
                        r.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (w!=null){
                    try {
                        w.flush();
                        w.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
    BufferedReader bis = null;
            BufferedWriter bos = null;
            try {
               bis = new BufferedReader(new FileReader(new File("images\\desk.jpg")));
               bos = new BufferedWriter(new FileWriter(new File("images\\desk3.jpg")));
                //方式一
    //           char[] c = new char[1024];
    //           int len;
    //           while ((len = bis.read(c)) != -1){
    //               bos.write(c,0,len);
    //           }
                //方式二
                String data;
                while((data = bis.readLine()) != null){
    //                bos.write(data+"\n");//方式一
                    //方式二
                    bos.write(data);
                    bos.newLine();
                }
    
  • 复制非文本文件

    /*
    int read(byte[] b)
        一次最多读取b.length个字节
        减少硬盘和内存的交互,提高程序的执行效率。
        往byte[]中读
     */
    public class FileInputScreamTest02 {
        public static void main(String[] args) {
            FileInputStream fis = null;//要读的文件
            FileOutputStream fos = null;//要写入的文件
            try {
                //IDEA默认的当前路径:工程Project的根
                fis = new FileInputStream("images\\desk.jpg");
                fos = new FileOutputStream("images\\desk1.jpg");
                //读
                byte[] b = new byte[1024];
                int readcount = 0;
                while((readcount = fis.read(b))!= -1){
    //                System.out.print(new String(b,0,readcount));
                    fos.write(b,0,readcount);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    *
    处理流之一:缓冲流的使用
    1.缓冲流:
    BufferedInputStream
    BufferedOutputStream
    BufferedReader
    BufferedWriter
    2.作用:提高流的读取、写入速度
        原因:内部提供了一个缓冲区
    3.处理流就是“套接”在已有的流的基础上。
     */
    public class BufferedTest {
        /**
         * 实现非文件的复制
         */
    
        public static void main(String[] args) {
            //1.造文件
            FileInputStream srcFis = null;
            FileOutputStream destFis = null;
            //2.造缓冲流
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
    
            try {
                srcFis = new FileInputStream("images\\desk.jpg");
                destFis = new FileOutputStream("images\\desk2.jpg");
    
                bis = new BufferedInputStream(srcFis);
                bos = new BufferedOutputStream(destFis);
    
                //3.复制的细节:读取、写入
                byte[] b = new byte[1024];
                int len;
                while ((len = bis.read(b)) != -1){
                    bos.write(b,0,len);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //关闭流
                //要求:先关闭外层的流,再关闭内层的流
                //说明:关闭外层流的同时,内层流也会自动进行关闭。关于内层流的关闭,我们可以省略
                if(bos != null){
                    try {
                        bos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(bis != null){
                    try {
                        bos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  • 练习:获取文本上每个字符出现的次数。

    ​ 提示:遍历文本的每一个字符,字符及出现的次数保存在Map 中,将Map中数据写入文件。

    /**
     * 练习:获取文本上每个字符出现的次数。
     *    提示:遍历文本的每一个字符,字符及出现的次数保存在Map中,
     *                将Map中数据写入文件。
     */
    public class test1 {
        public static void main(String[] args) {
            BufferedReader bis = null;
            BufferedWriter bos = null;
    
            try {
                //创建集合
                Map<Character,Integer> map = new HashMap();
    
                bis = new BufferedReader(new FileReader("day02\\hello.txt"));
                bos = new BufferedWriter(new FileWriter("day02\\count.txt"));
    
                int len = 0;
                while ((len = bis.read()) != -1){
                    char r = (char)len;
                    if(map.get(r) == null){
                        map.put(r,1);
                    }else{
                        map.put(r,map.get(r)+1);
                    }
                }
    			//遍历集合
                Set<Map.Entry<Character, Integer>> entrSet = map.entrySet();
                for (Map.Entry<Character,Integer> entry : entrSet) {
                    switch (entry.getKey()){
                        case ' ':
                            bos.write("空格" + entry.getValue());
                            break;
                        case '\n':
                            bos.write("换行" + entry.getValue());
                            break;
                        case '\t':
                            bos.write("tab键" + entry.getValue());
                            break;
                        case '\r':
                            bos.write("回车" + entry.getValue());
                            break;
                        default:
                            bos.write(entry.getKey()+"-->"+entry.getValue());
                            break;
                    }
                    bos.newLine();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (bis != null){
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bos != null){
                    try {
                        bos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值