博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

09java进阶——IO

Posted on 2019-02-02 20:58  心默默言  阅读(178)  评论(0编辑  收藏  举报

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
 *  在文件中,写入换行,符号换行  \r\n
 *  \r\n 可以写在上一行的末尾, 也可以写在下一行的开头
 */
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\n".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()文本中换行, \r\n也是文本换行
 *       方法具有平台无关性
 *       Windows  \r\n
 *       Linux    \n
 *       
 *       newLine()运行结果,和操作系统是相互关系
 *       JVM: 安装的是Windows版本,newLine()写的就是\r\n
 *            安装的是Linux版本,newLine()写的就是\n
 */
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() 读取文本行 \r\n
 *     
 *     方法读取到流末尾,返回null
 *     小特点:
 *       获取内容的方法一般都有返回值
 *       int 没有返回的都是负数
 *       引用类型 找不到返回null
 *       boolean 找不到返回false
 *       
 *       String s = null
 *       String s ="null"
 *       
 *       readLine()方法返回行的有效字符,没有\r\n
 */
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