05 IO流

来源:互联网 发布:mac air 电池 编辑:程序博客网 时间:2024/04/29 02:55
 05 IO流

###05.01_异常的概述和分类
A:异常的概述
    * 异常就是Java程序在运行过程中出现的错误。
B:异常的分类
    * 通过API查看Throwable
    * Error
        * 服务器宕机,数据库崩溃等
    * Exception
C:异常的继承体系
    * Throwable
        * Error    
        * Exception
            * RuntimeException所有的RuntimeException类及其子类的实例被称为运行时异常

###05.02_throw的概述以及和throws的区别
A:throw的概述
    * 在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
B:案例演示    
    * 分别演示编译时异常对象和运行时异常对象的抛出
C:throws和throw的区别
    * a:throws
        * 用在方法声明后面,跟的是异常类名
        * 可以跟多个异常类名,用逗号隔开(没有先后顺序)
        * 表示抛出异常,由该方法的调用者来处理
    * b:throw
        * 用在方法体内,跟的是异常对象名
        * 只能抛出一个异常对象名
        * 表示抛出异常,由方法体内的语句处理
    * 定义功能方法时,需要把出现的问题暴露出来让调用者去处理。
    * 在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

###05.03_finally关键字的面试题
A:面试题1
    * final,finally和finalize的区别
B:面试题2 
    * 如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后。 
         * A:面试题1
                 * final,finally是关键字;finalize是一个方法.

            * final可以修饰类,不能被继承
            * 修饰方法,不能被重写
            * 修饰变量,只能赋值一次
             
            * finally是try语句中的一个语句体,不能单独使用,用来释放资源 
             
            * finalize是一个方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
        * B:面试题2
            * 会,return建立了返回路径,再去执行finally,就等于执行了return。
            * finally语句体中不能写return语句。

###05.04_异(练习
键盘录入一个int类型的整数,对其求二进制表现形式
     * 如果录入的整数过大,给予提示,录入的整数过大请重新录入一个整数BigInteger
     * 如果录入的是小数,给予提示,录入的是小数,请重新录入一个整数
     * 如果录入的是其他字符,给予提示,录入的是非法字符,请重新录入一个整数
     public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入一个整数");
            String line = sc.nextLine();
            try {
                int num = Integer.parseInt(line); //将字符串转换为整数
                System.out.println(Integer.toBinaryString(num));//将整数转换为二进制
                System.out.println("输入的整数正确,退出程序");
                break;
            } catch (NumberFormatException e) {
                try {
                    new BigInteger(line); //如果BigInteger能装的下则就是整数录入过大
                    System.out.println("你输入的整数过大,请重新输入");
                } catch (Exception e1) {
                    try {
                        new BigDecimal(line); //如果BigDecimal能装的下则就是小数
                        System.out.println("你输入的是小数,请重新输入");
                    } catch (Exception e2) { 
                        System.out.println("你输入的是非法字符串,请重新输入");
                    }
                }
            }
        }
    }

###05.05_File类的概述和构造方法
File类的构造方法
    * 1 File file = new File("F:\\双元课堂\\day19\\video\\001_今日内容.avi");
    * 2 String parent = "F:\\双元课堂\\day19\\video";
        String child = "001_今日内容.avi";
        File file = new File(parent,child);
    * 3 File parent = new File("F:\\双元课堂\\day19\\video");
        String child = "001_今日内容.avi";
        File file = new File(parent, child);
File类的方法
    createNeFile() ; mkdir() ; mkdirs() ; renameTo() ; delete() ; 
    isDirectory() ; isFile() ; exists() ; canRead() ; canWrite() ; isHidden() ; 
    getAbsolutePath() ; getPath() ; getName() ; length() ; lastModifiled() ;
     list() ; listFiles() ; FilenameFilet接口; 

###05.06_IO流概述及其分类
1.概念
    * IO流用来处理设备之间的数据传输
    * Java对数据的操作是通过流的方式
    * Java用于操作流的类都在IO包中
    * 流按流向分为两种:输入流,输出流。
    * 流按操作类型分为两种:
        * 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
        * 字符流 : 字符流只能操作纯字符数据,比较方便。
2.IO流常用父类
    * 字节流的抽象父类:
        * InputStream 
        * OutputStreamm
    * 字符流的抽象父类:
        * Reader 
        * Writer        
3.IO程序书写
    * 使用前,导入IO包中的类
    * 使用时,进行IO异常处理
    * 使用后,释放资源
    * 尽量晚开早关
    
###05.07_定义小数组的标准格式
    * 字节流一次读写一个字节数组复制图片和视频
        FileInputStream fis = new FileInputStream("致青春.mp3");
        FileOutputStream fos = new FileOutputStream("copy.mp3");
        int len;
        byte[] arr = new byte[1024 * 8];          //自定义字节数组
        while((len = fis.read(arr)) != -1) {      //read()里面要有arr
            //fos.write(arr);
            fos.write(arr, 0, len);         //写出字节数组de有效个字节个数
        }
        fis.close();
        fos.close();

###05.08_字节流读写中文 
字节流读取中文的问题
    * 字节流在读中文的时候有可能会读到半个中文,造成乱码 
字节流写出中文的问题  (可以写但要变成字节数组)
    * 字节流直接操作的字节,写出中文必须将字符串转换成字节数组,写出回车换行  write("\r\n".getBytes());
     public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("xxx.txt");  
        fos.write("我读书少不要骗我".getBytes());
        fos.write("\r\n".getBytes());    
        fos.close();
    }

###05.09_流的标准处理异常代码
        FileInputStream fis = null;     //局部变量使用前要赋值,
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("aaa.txt");
            fos = new FileOutputStream("bbb.txt");
            int b;
            while((b = fis.read()) != -1) {
                fos.write(b);
            }
        } finally {   //try...finally嵌套的目的是能关一个是一个
            try {
                if(fis != null)  //不等于null,说明调用了,就关闭.不然没开启当然就不要关
                    fis.close();
            }finally {
                if(fos != null)
                    fos.close();
            }
        }

public class Demo2_标准代码关流2 {
    public static void main(String[] args) throws IOException {
        try(
            FileInputStream fis = new FileInputStream("aaa.txt");
            FileOutputStream fos = new FileOutputStream("bbb.txt");
            MyClose mc = new MyClose();   //MyClose实现了AutoCloseable接口,并重写了close方法
        ){
            int b;
            while((b=fis.read())!= -1){
                fos.write(b);
            }
        }
        
    }
}
class MyClose implements AutoCloseable{
    @Override
    public void close(){
        System.out.println("关闭了");
    }
}
原理:在try()中创建的流对象实现了AutoCloseable这个接口,如果实现了try后面的{}(读写代码)执行后,会自动调用流对象的close方法将流关掉 

###05.10_录入数据拷贝到文件
将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
        Scanner sc = new Scanner(System.in);
        FileOutputStream fos = new FileOutputStream("text.txt");
        System.out.println("请输入:");
        while(true) {
            String line = sc.nextLine();
            if("quit".equals(line))
                break;
            fos.write(line.getBytes());
            fos.write("\r\n".getBytes());
        }
        fos.close();

###05.11_字符流FileReader
1.字符流是什么
    * 字符流是可以直接读写字符的IO流
    * 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出.    
2.FileReader
    * FileReader类的read()方法可以按照字符大小读取 
        FileReader fr = new FileReader("aaa.txt");    //创建字符输入流对象,关联aaa.txt
        int ch;                //read()返回的是int类型
        while((ch = fr.read()) != -1) {            //将读到的字符赋值给ch   通过项目默认的码表一次读取一个字符
            System.out.println((char)ch);        //将读到的字符强转后打印
        }
        fr.close();           //关流 

###05.12_什么情况下使用字符流  只读、只写时使用
字符流也可以拷贝文本文件, 但不推荐使用. 因为读取时会把字节转为字符, 写出时还要把字符转回字节.
程序需要读取一段文本, 或者需要写出一段文本的时候可以使用字符流
    * 读取的时候是按照字符的大小读取的,不会出现半个中文
    * 写出的时候可以直接将字符串写出,不用转换为字节数组

字符流是否可以拷贝非纯文本的文件)
   * 不可以拷贝非纯文本的文件
   * 因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去
   * 如果是?,直接写出,这样写出之后的文件就乱了,看不了了

###05.13_ readLine()和newLine()方法 
BufferedReader的readLine()方法可以读取一行字符(不包含换行符号) ;只属于BufferedReader
BufferedWriter的newLine()可以输出一个跨平台的换行符号"\r\n"   ;只属于BufferedWriter

        BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
        String line;
        while((line = br.readLine()) != null) {  //返回值是null,底层做了判断public String readLine()
            bw.write(line);
            //bw.write("\r\n");     //只支持windows系统    \n linux    \r mac 
            bw.newLine();         //跨平台的  不通的系统里代表换行符
        }
        br.close();
        bw.close(); 

###05.14_LineNumberReader
LineNumberReader是BufferedReader的子类, 具有相同的功能, 并且可以统计行号
    * 调用getLineNumber()方法可以获取当前行号
    * 调用setLineNumber()方法可以设置当前行号 //若设置为100,则从101开始
        LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
        String line;
        lnr.setLineNumber(100);                                    //设置行号
        while((line = lnr.readLine()) != null) {      //readLine()一次就加1
            System.out.println(lnr.getLineNumber() + ":" + line);    //获取行号
        }
        lnr.close(); 

###05.15_装饰设计模式
*  好处
*  耦合性不强,被装饰的类变化与装饰类的变化无关。如果是继承的话耦合性太强
        interface Coder {
            public void code();
        }
        
        class Student implements Coder {
            @Override
            public void code() {
                System.out.println("javase");
                System.out.println("javaweb");
            }
        }
        
        class HeiMaStudent implements Coder {
                     // 1获取被装饰的引用
            private Student s;                        //获取到被包装类的引用
            public HeiMaStudent(Student s) {        //通过构造函数创建对象的时候,传入被包装的对象
                    // 2在构造方法中传人被装饰类的对象
                this.s = s;
            }
                    // 3对其原有功能进行升级
            @Override
            public void code() {                    
                s.code();   //有被包装类的功能
                System.out.println("数据库");
                System.out.println("ssh");
                System.out.println("安卓");
                System.out.println(".....");
            }    
        } 

    HeiMaStudent hms = new HeiMaStudent(new Student());  //
    hms.code();

###05.16_使用指定的码表读写字符 
FileReader是使用默认码表读取文件, 如果需要使用指定码表读取, 那么可以使用InputStreamReader(字节流,编码表)
FileWriter是使用默认码表写出文件, 如果需要使用指定码表写出, 那么可以使用OutputStreamWriter(字节流,编码表)
*       InputStreamReader(InputStream in, String charsetName),字节流转字符流 
*
        BufferedReader br =                         //高效的,用指定的编码表读
                new BufferedReader(new InputStreamReader( new FileInputStream("UTF-8.txt"), "UTF-8"));  //码表不区分大小写
        BufferedWriter bw =                         //高效的,用指定的编码表写
                new BufferedWriter(new OutputStreamWriter( new FileOutputStream("GBK.txt"), "GBK"));
        int ch;
        while((ch = br.read()) != -1) {
            bw.write(ch);
        }
        br.close();
        bw.close();

###05.17_序列流
1.什么是序列流
    * 序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推.
2.使用方式
    * 整合两个: SequenceInputStream(InputStream, InputStream) // 将按顺序读取这两个参数,先读取 s1,然后读取 s2
    * 
            FileInputStream fis1 = new FileInputStream("a.txt");            //创建输入流对象,关联a.txt
            FileInputStream fis2 = new FileInputStream("b.txt");            //创建输入流对象,关联b.txt
            SequenceInputStream sis = new SequenceInputStream(fis1, fis2);    //将两个流整合成一个流
            FileOutputStream fos = new FileOutputStream("c.txt");            //创建输出流对象,关联c.txt
            int b;
            while((b = sis.read()) != -1) {                                    //用整合后的读
                fos.write(b);                                                //写到指定文件上
            }
            sis.close();  //会关掉所有的输入流
            fos.close(); 

###05.18_内存输出流
1.什么是内存输出流
    * 该输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取出所有数据 ,可以避免字符乱码
2.使用方式
    * 创建对象: new ByteArrayOutputStream() 
    * 写出数据: write(int), write(byte[])
    * 获取数据: toByteArray()
    *       toString() 
3.FileInputStream读取中文的时候出现了乱码
     * 解决方案
     * 1,字符流读取
     * 2,ByteArrayOutputStream内存输出流
            FileInputStream fis = new FileInputStream("a.txt");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();  //在内存中创建了一个可以增长的缓冲区 ;不需要baos.close();  不能关联文件
            int b;
            while((b = fis.read()) != -1) {
                baos.write(b);     //将读取到的数据逐个写到内存中
            }
            //byte[] newArr = baos.toByteArray();        //将内存缓冲区中所有的字节,存到newArr数组中
            //System.out.println(new String(newArr));  //newArr变成字符串输出

            System.out.println(baos.toString()); //将缓冲区的内容转换为了字符串
            fis.close();

###0519_数据输入输出流
1.什么是数据输入输出流
    * DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据
    * 例如按Long大小写出一个数字, 写出时该数据占8字节. 读取的时候也可以按照Long类型读取, 一次读取8个字节.
2.使用方式
    * DataOutputStream(OutputStream), writeInt(), writeLong() 
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("b.txt"));
            dos.writeInt(997);
            dos.writeInt(998);
            dos.writeInt(999);            
            dos.close();
    * DataInputStream(InputStream), readInt(), readLong()
            DataInputStream dis = new DataInputStream(new FileInputStream("b.txt"));
            int x = dis.readInt();
            int y = dis.readInt();
            int z = dis.readInt();
            System.out.println(x);
            System.out.println(y);
            System.out.println(z);
            dis.close();

###05.20_随机访问流概述和读写数据
A:随机访问流概述
    * RandomAccessFile概述
    * RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。
    * 支持对随机访问文件的读取和写入。
B:read(),write(),seek()
    RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
        //raf.write(97);   //写出的是a
    
        //int x = raf.read();
        //System.out.println(x); //读取数据
        
        raf.seek(10); //在指定位置设置指针
        raf.write(98);
        raf.close();
0 0
原创粉丝点击