• 09java进阶——IO


    1.File类

    1.1目录及路径分隔符

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    
    public class Test01FileSeparator {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            // File类静态成员变量
            // 与系统有关的路径分隔符
            String separator = File.pathSeparator;
            System.out.println(separator);// 是一个分号,目录的分割 Linux :
    
            // 与系统有关的默认名称分隔符
            separator = File.separator;
            System.out.println(separator);// 向右  目录名称分割 Linux /
        }
    
    }

    1.2三种构造方法

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    
    public class Test02Constructor {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            function();
            System.out.println();
            function_1();
            System.out.println();
            function_2();
        }
    
        /*
         *  File(File parent,String child)
         *  传递路径,传递File类型父路径,字符串子路径
         *  好处: 父路径是File类型,父路径可以直接调用File类方法
         */
        public static void function_2() {
            File parent = new File("d:");
            File file = new File(parent, "eclipse");
            System.out.println(file);
        }
    
        /*
         *  File(String parent,String child)
         *  传递路径,传递字符串父路径,字符串子路径
         *  好处: 单独操作父路径和子路径
         */
        public static void function_1() {
            File file = new File("d:", "eclipse");
            System.out.println(file);
        }
    
        /*
         *  File(String pathname)
         *  传递路径名: 可以写到文件夹,可以写到一个文件
         *  c:\abc   c:\abc\Demo.java
         *  将路径封装File类型对象
         */
        public static void function() {
            File file = new File("d:\eclipse");
            System.out.println(file);
        }
    }

    1.3创建、删除文件和文件夹

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    import java.io.IOException;
    
    public class Test03DeleteAndCreate {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            function();
            function_1();
            function_2();
        }
    
        /*
         *  File类的删除功能
         *  boolean delete()
         *  删除的文件或者是文件夹,在File构造方法中给出
         *  删除成功返回true,删除失败返回false
         *  删除方法,不走回收站,直接从硬盘中删除
         *  删除有风险,运行需谨慎
         */
        public static void function_2() {
            File file = new File("d:\a.txt");
            boolean b = file.delete();
            System.out.println(b);
        }
    
        /*
         *  File创建文件夹功能
         *  boolean mkdirs() 创建多层文件夹,也可以创建单层文件夹(推荐使用)
         *  boolean mkdir() 只能创建单层文件夹
         *  创建的路径也在File构造方法中给出
         *  文件夹已经存在了,不在创建
         */
        public static void function_1() {
            File file = new File("d:\abc");
            boolean b = file.mkdirs();
            System.out.println(b);
        }
    
        /*
         *  File创建文件的功能
         *  boolean createNewFile()
         *  创建的文件路径和文件名,在File构造方法中给出
         *  文件已经存在了,不在创建
         */
        public static void function() throws IOException {
            File file = new File("d:\a.txt");
            boolean b = file.createNewFile();
            System.out.println(b);
        }
    }

    1.4获取功能

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    
    /*
     *  File类的获取功能
     */
    public class Test04Get {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            function();
            function_1();
            function_2();
            function_3();
        }
    
        /*
         * File类的获取功能
         * String getParent() 返回String对象
         * File getParentFile()返回File对象
         * 获取父路径
         */
        public static void function_3() {
            File file = new File("d:\eclipse\eclipse.exe");
            File parent = file.getParentFile();
            System.out.println(parent);
        }
    
        /*
         * File类获取功能
         * String getAbsolutePath() 返回String对象
         * File   getAbsoluteFile() 返回File对象
         * 获取绝对路径
         * eclipse环境中,写的是一个相对路径,绝对位置工程根目录
         */
        public static void function_2() {
            File file = new File("src");
            File absolute = file.getAbsoluteFile();
            System.out.println(absolute);
        }
    
        /*
         * File类获取功能
         * long length()
         * 返回路径中表示的文件的字节数
         */
        public static void function_1() {
            File file = new File("d:\eclipse\eclipse.exe");
            long length = file.length();
            System.out.println(length);
        }
    
        /*
         *  File类的获取功能
         *  String getName()
         *  返回路径中表示的文件或者文件夹名
         *  获取路径中的最后部分的名字
         */
        public static void function() {
            File file = new File("d:\eclipse\eclipse.exe");
            String name = file.getName();
            System.out.println(name);
    
            /*String path = file.getPath();
            System.out.println(path);*/
    //        System.out.println(file);
        }
    }

    1.5判断功能

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    
    public class Test05JudgingFunction {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            function();
            function_1();
        }
    
        /*
         *  File判断功能
         *  boolean isDirectory()
         *  判断File构造方法中封装的路径是不是文件夹
         *  如果是文件夹,返回true,不是文件返回false
         *  
         *  boolean isFile()
         *  判断File构造方法中封装的路径是不是文件
         */
        public static void function_1() {
            File file = new File("d:\eclipse\eclipse.exe");
            if (file.exists()) {
                boolean b = file.isDirectory();
                System.out.println(b);
            }
        }
    
        /*
         *  File判断功能
         *  boolean exists()
         *  判断File构造方法中封装路径是否存在
         *  存在返回true,不存在返回false
         */
        public static void function() {
            File file = new File("src"); // 如果用相对路径,默认的路径为当前项目的工作路径
            boolean b = file.exists();
            System.out.println(b);
        }
    }

    1.6list获取功能

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    
    public class Test06List {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            function();
            System.out.println();
            function_1();
            System.out.println();
            function_2();
        }
    
        public static void function_2() {
            // 获取系统中的所有根目录
            File[] fileArr = File.listRoots();
            for (File f : fileArr) {
                System.out.print(f + " ");
            }
            System.out.println();
        }
    
        /*
         *  File类的获取功能
         *  File[] listFiles()
         *  获取到,File构造方法中封装的路径中的文件和文件夹名 (遍历一个目录)
         *  返回的是目录或者文件的全路径
         */
        public static void function_1() {
            File file = new File("d:\eclipse");
            File[] fileArr = file.listFiles();
            for (File f : fileArr) {
                System.out.print(f + " ");
            }
            System.out.println();
        }
    
        /*
         *  File类的获取功能
         *  String[] list()
         *  获取到,File构造方法中封装的路径中的文件和文件夹名 (遍历一个目录)
         *  返回只有名字
         */
        public static void function() {
            File file = new File("c:");
            String[] strArr = file.list();
            System.out.println(strArr.length);
            for (String str : strArr) {
                System.out.print(str+" ");
            }
            System.out.println();
        }
    }

    1.7文件过滤器

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    import java.io.FileFilter;
    
    public class Test07Filter {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            File file = new File("c:\demo");
            File[] fileArr = file.listFiles(new MyFilter());
            for (File f : fileArr) {
                System.out.println(f);
            }
        }
    }
    
    class MyFilter implements FileFilter {
        public boolean accept(File pathname) {
            /*
             * pathname 接受到的也是文件的全路径
             * c:\demo\1.txt
             * 对路径进行判断,如果是java文件,返回true,不是java文件,返回false
             * 文件的后缀结尾是.java
             */
            // String name = pathname.getName();
            return pathname.getName().endsWith(".java");
    
        }
    }

    1.8递归遍历所有文件

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    
    public class Test08VisitAllDirectories {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            File dir = new File("c:\demo");
            getAllDir(dir);
        }
    
        /*
         *  定义方法,实现目录的全遍历
         */
        public static void getAllDir(File dir) {
            System.out.println(dir);
            // 调用方法listFiles()对目录,dir进行遍历
            File[] fileArr = dir.listFiles();
            for (File f : fileArr) {
                // 判断变量f表示的路径是不是文件夹
                if (f.isDirectory()) {
                    // 是一个目录,就要去遍历这个目录
                    // 本方法,getAllDir,就是给个目录去遍历
                    // 继续调用getAllDir,传递他目录
                    getAllDir(f);
                } else {
                    System.out.println(f);
                }
            }
        }
    }

    1.9搜索指定目录中的.java文件(含子目录)

    需求:打印指定目录即所有子目录中的.java文件的文件路径

    要求:编写一个方法用来打印指定目录中的.java文件路径,并进行方法的调用

    若指定的目录有子目录,那么把子目录中的.java文件路径也打印出来

    步骤:

             1. 指定要打印的目录File对象

             2. 调用getFileAll()方法,传入要打印的目录File对象

                       2.1 通过FilenameFilter过滤器获取指定目录中的所有.java类型的File对象

                       2.2 遍历得到每一个File对象

                       2.3 判断当前File 对象是否是目录

                                判断结果为true,说明为目录,通过递归,再次调用步骤2的getFileAll()方法

                                判断结果为false,说明是文件,打印文件的路径

    package cn.jxufe.java.chapter09.demo01;
    
    import java.io.File;
    import java.io.FileFilter;
    
    /*
     *  遍历目录,获取目录下的所有.java文件
     *  遍历多级目录,方法递归实现
     *  遍历的过程中,使用过滤器
     */
    public class Test09Filter {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            getAllJava(new File("c:\demo"));
        }
    
        /*
         * 定义方法,实现遍历指定目录
         * 获取目录中所有的.java文件
         */
        public static void getAllJava(File dir) {
            // 调用File对象方法listFiles()获取,加入过滤器
            File[] fileArr = dir.listFiles(new MyJavaFilter());
            for (File f : fileArr) {
                // 对f路径,判断是不是文件夹
                if (f.isDirectory()) {
                    // 递归进入文件夹遍历
                    getAllJava(f);
                } else {
                    System.out.println(f);
                }
            }
        }
    }
    
    class MyJavaFilter implements FileFilter {
        public boolean accept(File pathname) {
            // 判断获取的是目录,直接返回true
            if (pathname.isDirectory())
                return true;
            return pathname.getName().toLowerCase().endsWith(".java");// 包括或缀名为大写的
        }
    
    }

    2.字节流

    2.1OutPutStream

    /*
     *  字节输出流
     *    java.io.OutputStream 所有字节输出流的超类
     *    作用: 从Java程序,写出文件
     *    字节: 这样流每次只操作文件中的1个字节
     *    写任意文件
     *    
     *    方法都是写文入的方法
     *    write(int b) 写入1个字节
     *    write(byte[] b) 写入字节数组
     *    write(byte[] b,int,int)写入字节数组,int 开始写入的索引, int 写几个
     *    close() 方法,关闭流对象,释放与次流相关的资源
     *    
     *    流对象,操作文件的时候, 自己不做,依赖操作系统
     */

    2.2FileOutputStream

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *   FileOutputStream
     *   写入数据文件,学习父类方法,使用子类对象
     *   
     *   子类中的构造方法: 作用:绑定输出的输出目的
     *     参数:
     *       File    封装文件
     *       String  字符串的文件名
     *   
     *   流对象使用步骤
     *     1. 创建流子类的对象,绑定数据目的
     *     2. 调用流对象的方法write写
     *     3. close释放资源
     *     
     *    流对象的构造方法,可以创建文件,如果文件存在,直接覆盖
     */
    public class Test01FileOutputStream {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            FileOutputStream fos = new FileOutputStream("d:\aa.txt"); // aa.txt文件中显示的不是100,而是d,ASCII表
            // 流对象的方法write写数据
            // 写1个字节
            fos.write(97);
    
            // 写字节数组
            byte[] bytes = { 65, 66, 67, 68 };
            fos.write(bytes);
    
            // 写字节数组的一部分,开始索引,写几个
            fos.write(bytes, 1, 2);
    
            // 写入字节数组的简便方式
            // 写字符串
            fos.write("hello".getBytes());
    
            // 关闭资源
            fos.close();
        }
    }

    2.3文件的续写和换行问题

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *  FileOutputStream 文件的续写和换行问题
     *  续写: FileOutputStream构造方法, 的第二个参数中,加入true
     *  在文件中,写入换行,符号换行  
    
     *  
     可以写在上一行的末尾, 也可以写在下一行的开头
     */
    public class Test02FileOutputStream {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            File file = new File("d:\b.txt");
            FileOutputStream fos = new FileOutputStream(file, true);// 默认为false
            fos.write("hello
    ".getBytes());
            fos.write("world".getBytes());
            fos.close();
        }
    }

    2.4IO中的异常处理

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *   IO流的异常处理
     *   try catch finally
     *   
     *   细节:
     *     1. 保证流对象变量,作用域足够
     *     2. catch里面,怎么处理异常
     *         输出异常的信息,目的看到哪里出现了问题
     *         停下程序,从新尝试
     *     3. 如果流对象建立失败了,需要关闭资源吗
     *         new 对象的时候,失败了,没有占用系统资源
     *         释放资源的时候,对流对象判断null
     *         变量不是null,对象建立成功,需要关闭资源
     */
    public class Test03IOException {
    
        public static void main(String[] args) {
            // try 外面声明变量,try 里面建立对象
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream("d:\a.txt");
                fos.write(100);
            } catch (IOException ex) {
                System.out.println(ex);
                throw new RuntimeException("文件写入失败,重试");
            } finally {
                try {
                    if (fos != null)
                        fos.close();
                } catch (IOException ex) {
                    throw new RuntimeException("关闭资源失败");
                }
            }
        }
    
    }

    2.5InPutStream

    /*
     *   字节输入流
     *     java.io.InputStream 所有字节输入流的超类
     *   作用: 读取任意文件,每次只读取1个字节
     *   读取的方法  read
     *     int  read() 读取1个字节
     *     int  read(byte[] b) 读取一定量的字节,存储到数组中
     */

    2.6FileInputStream

    、 

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    /*
     *  FileInputStream读取文件
     *  
     *  构造方法: 为这个流对象绑定数据源
     *  
     *    参数: 
     *      File 类型对象
     *      String 对象
     *   输入流读取文件的步骤
     *     1. 创建字节输入流的子类对象
     *     2. 调用读取方法read读取
     *     3. 关闭资源
     *     
     *     read()方法,
     *       read()执行一次,就会自动读取下一个字节
     *       返回值,返回的是读取到的字节, 读取到结尾返回-1
     */
    public class Test04FileInputStream {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            FileInputStream fis = new FileInputStream("d:\a.txt");
            // 读取一个字节,调用方法read 返回int
            // 使用循环方式,读取文件, 循环结束的条件 read()方法返回-1
            int len = 0;// 接受read方法的返回值
    
            while ((len = fis.read()) != -1) {
                System.out.print((char) len);
            }
            // 关闭资源
            fis.close();
            /*
             * int i = fis.read();
                    System.out.println(i);
                    
                    i = fis.read();
                    System.out.println(i);
                    
                    i = fis.read();
                    System.out.println(i);
                    
                    i = fis.read();
                    System.out.println(i);
             */
        }
    
    }

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    /*
     *  FileInputStream读取文件
     *   读取方法  int read(byte[] b) 读取字节数组
     *   数组作用: 缓冲的作用, 提高效率
     *   read返回的int,表示什么含义 读取到多少个有效的字节数
     */
    public class Test05FileInputStream {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            FileInputStream fis = new FileInputStream("d:\a.txt");
            // 创建字节数组
            byte[] b = new byte[1024];
    
            int len = 0;
            while ((len = fis.read(b)) != -1) {
                System.out.print(new String(b, 0, len));// 每次取的字符数组个长度,必须借用len来判断,不然可能会有重复
            }
            fis.close();
        }
    
    }
    /*
     * 
            int len = fis.read(b);
            System.out.println(new String(b));//ab
            System.out.println(len);//2
            
            len = fis.read(b);
            System.out.println(new String(b));//cd
            System.out.println(len);//2
            
            len = fis.read(b);
            System.out.println(new String(b));//ed
            System.out.println(len);//1
            
            len = fis.read(b);
            System.out.println(new String(b));//ed
            System.out.println(len);//-1
            */

    2.7字节流复制文件

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *  将数据源 d:\a.txt
     *  复制到 c:\a.txt  数据目的
     *  字节输入流,绑定数据源
     *  字节输出流,绑定数据目的
     *  
     *  输入,读取1个字节
     *  输出,写1个字节
     */
    public class Test06Copy {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            // 定义两个流的对象变量
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                // 建立两个流的对象,绑定数据源和数据目的
                fis = new FileInputStream("d:\a.txt");
                fos = new FileOutputStream("e:\a.txt");
                // 字节输入流,读取1个字节,输出流写1个字节
                int len = 0;
                while ((len = fis.read()) != -1) {
                    fos.write(len);
                }
            } catch (IOException ex) {
                System.out.println(ex);
                throw new RuntimeException("文件复制失败");
            } finally {
                try {
                    if (fos != null)
                        fos.close();
                } catch (IOException ex) {
                    throw new RuntimeException("释放资源失败");
                } finally {
                    try {
                        if (fis != null)
                            fis.close();
                    } catch (IOException ex) {
                        throw new RuntimeException("释放资源失败");
                    }
                }
            }
        }
    
    }
    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *  字节流复制文件
     *   采用数组缓冲提高效率
     *   字节数组
     *   FileInputStream 读取字节数组
     *   FileOutputStream 写字节数组
     */
    public class Test07CopyWithArray {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            long s = System.currentTimeMillis();
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                fis = new FileInputStream("c:\t.zip");
                fos = new FileOutputStream("d:\t.zip");
                // 定义字节数组,缓冲
                byte[] bytes = new byte[1024 * 10];
                // 读取数组,写入数组
                int len = 0;
                while ((len = fis.read(bytes)) != -1) {
                    fos.write(bytes, 0, len);
                }
            } catch (IOException ex) {
                System.out.println(ex);
                throw new RuntimeException("文件复制失败");
            } finally {
                try {
                    if (fos != null)
                        fos.close();
                } catch (IOException ex) {
                    throw new RuntimeException("释放资源失败");
                } finally {
                    try {
                        if (fis != null)
                            fis.close();
                    } catch (IOException ex) {
                        throw new RuntimeException("释放资源失败");
                    }
                }
            }
            long e = System.currentTimeMillis();
            System.out.println(e - s);
        }
    
    }

    2.8字符输出流FileWriter

    局限性:只能写文本文件

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    /*
     *   字符输出流
     *     java.io.Writer 所有字符输出流的超类
     *   写文件,写文本文件
     *   
     *   写的方法 write
     *     write(int c) 写1个字符
     *     write(char[] c)写字符数组
     *     write(char[] c,int,int)字符数组一部分,开始索引,写几个
     *     write(String s) 写入字符串
     *     
     *   Writer类的子类对象 FileWriter
     *   
     *   构造方法:  写入的数据目的
     *     File 类型对象
     *     String 文件名
     *     
     *   字符输出流写数据的时候,必须要运行一个功能,刷新功能
     *   flush()
     */
    public class Test08FileWriter {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            FileWriter fw = new FileWriter("d:\1.txt");
    
            // 写1个字符
            fw.write(100);
            fw.flush();
    
            // 写1个字符数组
            char[] c = { 'a', 'b', 'c', 'd', 'e' };
            fw.write(c);
            fw.flush();
    
            // 写字符数组一部分
            fw.write(c, 2, 2);
            fw.flush();
    
            // 写如字符串
            fw.write("hello");
            fw.flush();
    
            fw.close();
        }
    
    }

    2.9字符输入流FileReader

    局限性:只能读取文本文件

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileReader;
    import java.io.IOException;
    
    /*
     *  字符输入流读取文本文件,所有字符输入流的超类
     *    java.io.Reader
     *  专门读取文本文件
     *  
     *  读取的方法 : read()
     *   int read() 读取1个字符
     *   int read(char[] c) 读取字符数组
     *   
     *   Reader类是抽象类,找到子类对象 FileReader
     *   
     *   构造方法: 绑定数据源
     *     参数:
     *        File  类型对象
     *        String文件名
     */
    public class Test09FileReader {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            FileReader fr = new FileReader("d:\1.txt");
            /*int len = 0 ;
            while((len = fr.read())!=-1){
                System.out.print((char)len);
            }*/
            char[] ch = new char[1024];
            int len = 0;
            while ((len = fr.read(ch)) != -1) {
                System.out.print(new String(ch, 0, len));
            }
    
            fr.close();
        }
    
    }

    2.10字符流复制文件

    package cn.jxufe.java.chapter09.demo02;
    
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /*
     *  字符流复制文本文件,必须文本文件
     *  字符流查询本机默认的编码表,简体中文GBK
     *  FileReader读取数据源
     *  FileWriter写入到数据目的
     */
    public class Test10Copy {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            FileReader fr = null;
            FileWriter fw = null;
            try {
                fr = new FileReader("d:\1.txt");
                fw = new FileWriter("e:\1.txt");
                char[] cbuf = new char[1024];
                int len = 0;
                while ((len = fr.read(cbuf)) != -1) {
                    fw.write(cbuf, 0, len);
                    fw.flush();
                }
    
            } catch (IOException ex) {
                System.out.println(ex);
                throw new RuntimeException("复制失败");
            } finally {
                try {
                    if (fw != null)
                        fw.close();
                } catch (IOException ex) {
                    throw new RuntimeException("释放资源失败");
                } finally {
                    try {
                        if (fr != null)
                            fr.close();
                    } catch (IOException ex) {
                        throw new RuntimeException("释放资源失败");
                    }
                }
            }
        }
    }

    3.转换流

    3.1OutputStreamWriter类

    查阅OutputStreamWriter的API介绍,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节。它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。

    package cn.jxufe.java.chapter09.demo03;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    
    /*
     *  转换流
     *    java.io.OutputStreamWriter 继承Writer类
     *    就是一个字符输出流,写文本文件
     *    write()字符,字符数组,字符串
     *    
     *    字符通向字节的桥梁,将字符流转字节流
     *    
     *    OutputStreamWriter 使用方式
     *     构造方法:
     *       OutputStreamWriter(OuputStream out)接收所有的字节输出流
     *       但是: 字节输出流:  FileOutputStream
     *       
     *      OutputStreamWriter(OutputStream out, String charsetName)
     *      String charsetName 传递编码表名字 GBK  UTF-8 
     *      
     *      OutputStreamWriter 有个子类,  FileWriter
     */
    public class Test01OutputStreamWriter {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            writeGBK();
            writeUTF();
        }
    
        /*
         * 转换流对象OutputStreamWriter写文本
         * 采用UTF-8编码表写入
         */
        public static void writeUTF() throws IOException {
            FileOutputStream fos = new FileOutputStream("d:\utf.txt");
            OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");// 编码方式不区分大小写
            osw.write("你好我好大家好");
            osw.close();
        }
    
        /*
         * 转换流对象 OutputStreamWriter写文本
         * 文本采用GBK的形式写入
         */
        public static void writeGBK() throws IOException {
            FileOutputStream fos = new FileOutputStream("d:\gbk.txt");
            OutputStreamWriter osw = new OutputStreamWriter(fos);// 默认为gbk
            osw.write("你好我好大家好");
            osw.close();
        }
    }

    3.2InputStreamReader类

    查阅InputStreamReader的API介绍,InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

    package cn.jxufe.java.chapter09.demo03;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /*
     *  转换流
     *    java.io.InputStreamReader 继承 Reader
     *    字符输入流,读取文本文件
     *    
     *    字节流向字符的敲了,将字节流转字符流
     *    
     *    读取的方法:
     *       read() 读取1个字符,读取字符数组
     *    
     *    技巧:  OuputStreamWriter写了文件
     *    InputStreamReader读取文件
     *    
     *    OuputStreamWriter(OuputStream out)所有字节输出流
     *    InputStreamReader(InputStream in) 接收所有的字节输入流
     *      可以传递的字节输入流: FileInputStream
     *    InputStreamReader(InputStream in,String charsetName) 传递编码表的名字
     */
    public class Test02InputStreamReader {
        public static void main(String[] args) throws IOException {
            readGBK();
            readUTF();
        }
    
        /*
         *  转换流,InputSteamReader读取文本
         *  采用UTF-8编码表,读取文件utf
         */
        public static void readUTF() throws IOException {
            FileInputStream fis = new FileInputStream("d:\utf.txt");
            InputStreamReader isr = new InputStreamReader(fis, "utf-8");
            char[] ch = new char[1024];
            int len = isr.read(ch);
            System.out.println(new String(ch, 0, len));
        }
    
        /*
         *  转换流,InputSteamReader读取文本
         *  采用系统默认编码表,读取GBK文件
         */
        public static void readGBK() throws IOException {
            FileInputStream fis = new FileInputStream("d:\gbk.txt");
            InputStreamReader isr = new InputStreamReader(fis);
            char[] ch = new char[1024];
            int len = isr.read(ch);
            System.out.println(new String(ch, 0, len));
        }
    }

    3.3转换流和子类区别

    发现有如下继承关系:

    OutputStreamWriter:

      |--FileWriter:

    InputStreamReader:

      |--FileReader;

    父类和子类的功能有什么区别呢?

    OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。

    FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。

    InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。

    InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。

    FileReader fr = new FileReader("a.txt");

    这三句代码的功能是一样的,其中第三句最为便捷。

    注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?

    条件:

    1、操作的是文件。2、使用默认编码。

    总结:

    字节--->字符 : 看不懂的--->看的懂的。  需要读。输入流。 InputStreamReader

    字符--->字节 : 看的懂的--->看不懂的。  需要写。输出流。 OutputStreamWriter

    4.缓冲流

    Java中提高了一套缓冲流,它的存在,可提高IO流的读写速度

    缓冲流,根据流的分类分类字节缓冲流与字符缓冲流。

    4.1字节缓冲流

    字节缓冲流根据流的方向,共有2个

    •  写入数据到流中,字节缓冲输出流 BufferedOutputStream
    •  读取流中的数据,字节缓冲输入流 BufferedInputStream

    它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度

    4.1.1字节缓冲输出流BufferedOutputStream

    通过字节缓冲流,进行文件的读写操作 写数据到文件的操作 

    • 构造方法
    • public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 
    package cn.jxufe.java.chapter09.demo03;
    
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *  字节输出流的缓冲流
     *   java.io.BufferedOuputStream 作用: 提高原有输出流的写入效率
     *   BufferedOuputStream 继承 OutputStream
     *   方法,写入 write 字节,字节数组
     *   
     *   构造方法:
     *     BufferedOuputStream(OuputStream out)
     *     可以传递任意的字节输出流, 传递的是哪个字节流,就对哪个字节流提高效率
     *     
     *     FileOutputSteam
     */
    public class Test03BufferOutputStream {
        // 创建字节输出流,绑定文件
        // FileOutputStream fos = new FileOutputStream("c:\buffer.txt");
        // 创建字节输出流缓冲流的对象,构造方法中,传递字节输出流
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\buffer.txt"));
            bos.write(55);
            byte[] bytes = "good".getBytes();
            bos.write("hello".getBytes());
            bos.write(bytes);
            bos.write(bytes, 1, 3);
            bos.close();
        }
    
    }

    4.1.2字节缓冲输入流 BufferedInputStream

    刚刚我们学习了输出流实现了向文件中写数据的操作,那么,现在我们完成读取文件中数据的操作

    • 构造方法
    • public BufferedInputStream(InputStream in)
    package cn.jxufe.java.chapter09.demo03;
    
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    /*
     *  字节输入流的缓冲流
     *    java.io.BufferedInputStream 
     *     继承InputStream,标准的字节输入流
     *     读取方法  read() 单个字节,字节数组
     *    
     *    构造方法:
     *      BufferedInputStream(InputStream in)
     *      可以传递任意的字节输入流,传递是谁,就提高谁的效率
     *      可以传递的字节输入流 FileInputStream
     */
    public class Test04BufferInputStream {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            // 创建字节输入流的缓冲流对象,构造方法中包装字节输入流,包装文件
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\buffer.txt"));
            byte[] bytes = new byte[10];
            int len = 0;
            while ((len = bis.read(bytes)) != -1) {
                System.out.print(new String(bytes, 0, len));
            }
            bis.close();
        }
    
    }

    5.几种读取文件方式效率的对比

    package cn.jxufe.java.chapter09.demo03;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *  文件复制方式,字节流,一共4个方式
     *  1. 字节流读写单个字节                    125250 毫秒
     *  2. 字节流读写字节数组                    193    毫秒  OK
     *  3. 字节流缓冲区流读写单个字节     1210   毫秒
     *  4. 字节流缓冲区流读写字节数组     73     毫秒  OK
     */
    public class Test05CopyContrast {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            long s = System.currentTimeMillis();
            copy_4(new File("c:\q.exe"), new File("d:\q.exe"));
            long e = System.currentTimeMillis();
            System.out.println(e - s);
        }
    
        /*
         * 方法,实现文件复制
         *  4. 字节流缓冲区流读写字节数组
         */
        public static void copy_4(File src, File desc) throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc));
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
            }
            bos.close();
            bis.close();
        }
    
        /*
         * 方法,实现文件复制
         *  3. 字节流缓冲区流读写单个字节
         */
        public static void copy_3(File src, File desc) throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc));
            int len = 0;
            while ((len = bis.read()) != -1) {
                bos.write(len);
            }
            bos.close();
            bis.close();
        }
    
        /*
         * 方法,实现文件复制
         *  2. 字节流读写字节数组
         */
        public static void copy_2(File src, File desc) throws IOException {
            FileInputStream fis = new FileInputStream(src);
            FileOutputStream fos = new FileOutputStream(desc);
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len);
            }
            fos.close();
            fis.close();
        }
    
        /*
         * 方法,实现文件复制
         *  1. 字节流读写单个字节
         */
        public static void copy_1(File src, File desc) throws IOException {
            FileInputStream fis = new FileInputStream(src);
            FileOutputStream fos = new FileOutputStream(desc);
            int len = 0;
            while ((len = fis.read()) != -1) {
                fos.write(len);
            }
            fos.close();
            fis.close();
        }
    }

    6.字符缓冲流

    6.1字符缓冲输出流 BufferedWriter

    package cn.jxufe.java.chapter09.demo04;
    
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    
    /*
     *   字符输出流缓冲区流
     *     java.io.BufferedWriter 继承 Writer
     *     写入方法 write () 单个字符,字符数组,字符串
     *     
     *     构造方法:
     *       BufferedWriter(Writer w)传递任意字符输出流
     *       传递谁,就高效谁
     *         能传递的字符输出流 FileWriter, OutputStreamWriter
     *         
     *    BufferedWriter 具有自己特有的方法
     *      void  newLine() 写换行
     *      
     *       newLine()文本中换行, 
    也是文本换行
     *       方法具有平台无关性
     *       Windows  
    
     *       Linux    
    
     *       
     *       newLine()运行结果,和操作系统是相互关系
     *       JVM: 安装的是Windows版本,newLine()写的就是
    
     *            安装的是Linux版本,newLine()写的就是
    
     */
    public class Test01BufferWriter {
        public static void main(String[] args) throws IOException {
            // 创建字符输出流,封装文件
            FileWriter fw = new FileWriter("d:\buffer.txt");
            BufferedWriter bfw = new BufferedWriter(fw);
    
            bfw.write("你好");
            bfw.newLine();
            bfw.flush();
    
            bfw.write("我好好");
            bfw.newLine();
            bfw.flush();
    
            bfw.write("大家都好");
            bfw.flush();
    
            bfw.close();
    
        }
    }

    6.2字符缓冲输入流 BufferedReader

     

    UTF-8的编码方式创建的

    package cn.jxufe.java.chapter09.demo04;
    
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /*
     *  字符输入流缓冲流
     *    java.io.BufferedReader 继承 Reader
     *    读取功能 read() 单个字符,字符数组
     *    构造方法:
     *      BufferedReader(Reader r)
     *      可以任意的字符输入流
     *         FileReader  InputStreamReader
     *         
     *     BufferedReader自己的功能
     *     String readLine() 读取文本行 
    
     *     
     *     方法读取到流末尾,返回null
     *     小特点:
     *       获取内容的方法一般都有返回值
     *       int 没有返回的都是负数
     *       引用类型 找不到返回null
     *       boolean 找不到返回false
     *       
     *       String s = null
     *       String s ="null"
     *       
     *       readLine()方法返回行的有效字符,没有
    
     */
    public class Test02BufferedReader {
    
        public static void main(String[] args) throws IOException {
            // 创建字符输入流缓冲流对象,构造方法传递字符输入流,包装数据源文件
            FileInputStream fis = new FileInputStream("d:\a.txt");
            InputStreamReader isr = new InputStreamReader(fis, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            // 调用缓冲流的方法 readLine()读取文本行
            // 循环读取文本行, 结束条件 readLine()返回null
            String line = null;
            int lineNumber = 0;
            while ((line = br.readLine()) != null) {
                lineNumber++;
                System.out.println(lineNumber + "  " + line);
            }
            br.close();
        }
    
        /*    String linString = br.readLine();
            System.out.println(linString);
            linString = br.readLine();
            System.out.println(linString);
            linString = br.readLine();
            System.out.println(linString);
            linString = br.readLine();
            System.out.println(linString);*/
    }

     

    7.使用字符缓冲流完成文本文件的复制

    package cn.jxufe.java.chapter09.demo04;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Test03Copy {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            BufferedReader bfr = new BufferedReader(new FileReader("d:\a.txt"));// 复制文件的时候不用担心编码问题了
            BufferedWriter bfw = new BufferedWriter(new FileWriter("d:\a2.txt"));
            // 读取文本行, 读一行,写一行,写换行
            String line = null;
            while ((line = bfr.readLine()) != null) {
                bfw.write(line);
                bfw.newLine();
                bfw.flush();
            }
            bfw.close();
            bfr.close();
        }
    
    }

    8.流的操作规律

    IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢?  

    把IO流进行了规律的总结(四个明确):

    • 明确一:要操作的数据是数据源还是数据目的。

                      源:InputStream    Reader

                      目的:OutputStream Writer

    先根据需求明确要读,还是要写。

    • 明确二:要操作的数据是字节还是文本呢?

                      源:

                               字节:InputStream

                               文本:Reader

                      目的:

                               字节:OutputStream

                               文本:Writer

    已经明确到了具体的体系上。

    • 明确三:明确数据所在的具体设备。

                      源设备:

                               硬盘:文件  File开头。

                               内存:数组,字符串。

                               键盘:System.in;

                               网络:Socket

                      目的设备:

                               硬盘:文件  File开头。

                               内存:数组,字符串。

                               屏幕:System.out

                               网络:Socket

    完全可以明确具体要使用哪个流对象。

    • 明确四:是否需要额外功能呢?

                      额外功能:

                               转换吗?转换流。InputStreamReader OutputStreamWriter

                               高效吗?缓冲区对象。BufferedXXX

     InputStream

           FileInputStream

           BufferedInputStream

    OuputStream

       FileOutputStream

       BufferedOuputStream

    Writer

      OutputStreamWriter

         FileWriter

          BufferedWriter

    Reader

      InputStreamReader

         FileReader

     BufferedReader

  • 相关阅读:
    BZOJ1051:受欢迎的牛(并查集 / Tarjan)
    ZOJ3261:Connections in Galaxy War(逆向并查集)
    POJ2912:Rochambeau(带权并查集)
    POJ1308:Is It A Tree?(并查集)
    RBAC权限管理
    RBAC权限管理
    用户密码加密简介
    用户密码加密简介
    Java文件路径
    Java文件路径
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/10964339.html
Copyright © 2020-2023  润新知