Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 595|回复: 0

Java 异常 文件操作 IO流

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-9-7 14:38:36 | 显示全部楼层 |阅读模式

    1. 程序的异常

    严重问题:Error 不处理,问题严重,比如内存溢出

    问题:Exception:

    编译器问题:不是运行期RuntimeException的异常,必须进行处理,不处理将不能通过编译

    运行期问题:RuntimeException 这种问题也不处理,程序的严谨性问题

     如果程序出现了问题,我们没有处理,虚拟机将默认进行处理:把异常问题,出现的原因输出在控制台,同时结束程序

    1.1 try...catch...finally处理格式

    try {
        //可能出现问题的代码,代码量越少越好,虚拟机需要开辟新的问题处理这个问题
    }catch(异常名称) {
        //针对问题的处理
    }finally {
        //释放资源
    } 
    // 变形格式
    try {
        //可能出现问题的代码,try问题出现以后,将会去catch里面查找,但是不能继续执行try里面的代码
    }catch(异常名称) {    
        //异常名称写成Exception可以接收所有的异常,能明确尽量明确,针对问题的处理,需要有处理方式
    }

    例如:

       public static void main(String[] args) {
            int a = 20;
            int b = 0;
            
            try {
                System.out.println(a / b);
            }catch(ArithmeticException s) {
                System.out.println("除数不能为0");
            }
            System.out.println("over");
        }

    JDK7异常处理新特性:

        public static void method2() {
            int a = 0;
            int b = 0;
            int[] arr = {1, 2, 3};
            try {
                System.out.println(a / b);
                System.out.println(arr[3]);
            }catch(ArithmeticException | ArrayIndexOutOfBoundsException  s){
                System.out.println("有问题");
            }
            System.out.println("over");

    注意:异常必须是同级关系,不能够是继承关系,并且所有的异常执行同一种操作

    异常的几个常用方法:

    public String getMessage():返回异常的消息字符串

    public String toString():返回throwable的简短描述,将由一下字符串拼接而成:

      此对象的类的名称(全路径名)

      ": "冒号和一个空格

      调用此对象getLocalizedMessage()方法的结果

    public String getLocalizedMessage():创建throwable的本地化描述,子类可以重写此方法,以便生成特定语言环境的消息,对于不重写此方法的子类,将默认返回与getMessage()的结果

    void printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回void

    void printStackTrace(PrintStream s):通常用该方法将异常的内容存储到日志文件中,以便日后查看

        public static void main(String[] args) {
            String s = "2014-01";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            
            try {
                Date d = sdf.parse(s);
                System.out.println(d);
            } catch (ParseException e) {
                System.out.println(e.getMessage());
                System.out.println(e.toString());
                e.printStackTrace();
            }
            
        }

    finally:finally控制的语句一定会得到执行,但是如果执行finally之前jvm退出,将不能执行

    finally主要用于释放资源,在IO流和数据库的操作中会经常遇到,try...finally可以单独使用

    final:最终的意思,可以修饰类,成员变量,成员方法

    修饰类:类不能够被继承

    修饰变量:该变量是常量

    修饰方法:方法不能够被重写

    finalize:是Object类的一个方法,用于垃圾回收。

     

    1.2 throws处理格式

    特点:自身不能处理或者没有权限处理,抛出后是编译器的异常必须要处理,运行期可以不处理

        public static void main(String[] args) {
            System.out.println("今天的天气很好");
            try {
                method();
            } catch (ParseException e) {
                e.printStackTrace();
            }
            System.out.println("就是有点热");
        }
    
        public static void method() throws ParseException {
            String s = "2015-11-20";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//不能处理或者没有权限处理
            Date d = sdf.parse(s);
        }

    1.3 throw以及与throws的区别

    throws:

      用在方法声明后面,后面跟的是异常的名称

      可以跟多个异常类名称,用逗号隔开

      表示抛出异常,由该方法的调用者来处理这个异常

      throws表示出现异常的一种可能性,并不一定会发生这些异常

    throw:

      用在方法体中,跟的是异常的对象名

      只能抛出一个异常对象名

      表示抛出异常,由方法体内的语句处理

      throw则是抛出了异常,执行throw则一定是抛出了某种异常

        public static void main(String[] args) {
            method1();
            try {
                method2();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static void method1() {
            int a = 10;
            int b = 0;
            if (b == 0) {
                throw new ArithmeticException();
            }else {
                System.out.println(a / b);
            }
        }
        
        public static void method2() throws Exception {
            int a = 10;
            int b = 0;
            if(b == 0) {
                throw new Exception();
            }else {
                System.out.println(a / b);
            }
        }

    throws和try到底应该用哪个:

    如果后续程序需要继续运行就执行try

    如果后续程序不需要继续运行就执行throws

     

    面试题:如果catch里面由return语句,那么finally里面的代码是否会执行,如果会,请问在return 前还是在return 后:会,前,但是return 的返回路径已经确定,准确的说finally在return 的中间

        public static void main(String[] args) {
            System.out.println(getInt());
        }
        
        public static int getInt() {
            int a = 10;
            try {
                System.out.println(a / 0);
                a = 20;
            }catch(ArithmeticException e) {
                System.out.println("出错啦");
                a = 30;
                return a;
            }finally {
                System.out.println("到底在哪里呢");
                a = 40;
            }
            return a;
        }
    
    程序运行结果:
    出错啦
    到底在哪里呢
    30

     1.4 自定义异常

    public class MyException extends Exception{
        public MyException() {
            
        }
        
        public MyException(String message) {
            super(message);
        }
    }
    public class Teacher {
        public void check(int score) throws MyException {
            if(score > 100 || score < 0) {
                throw new MyException("分数必须在0到100之间");
            }else {
                System.out.println("分数没有问题");
            }
        }
    }

    异常的注意事项:

    1. 子类重写父类方法时,子类的方法必须抛出相同的异常或者父类异常的子类,

    2. 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者它的子类的异常,子类不能够抛出父类没有的异常

    3. 如果被重写的方法没有异常抛出,那么子类的方法绝对不能够通过throw抛出异常,如果子类方法有异常发生,那么子类只能用try不能用throw

     

    2. 文件操作

    2.1 File类和构造方法

    定义:文件或者目录路径名的抽象表现形式,未必真实存在

    构造方法:一下三种方式的效果相同,一般采用第一种方法:

    public File(String pathname):根据路径得到一个File对象

    public File(String parent, String child):根据一个目录和一个子文件得到File对象

    public File(File parent, String chile):根据一个父File对象和一个子文件/目录得到File对象

    2.2 成员方法

    创建功能:

    public boolean createNewFile():创建文件,如果存在,就不创建并返回false

    public boolean mkdir():创建文件夹,如果存在,不创建并返回false

    public boolean mkdirs():创建文件夹,如果父文件夹不存在,也会创建,多层。

    注意:创建文件或者文件夹时需要选择正确的方法。

    如果没有写盘符文件,默认在项目文件路径下

    删除文件:

    public boolean delete():删除文件或者文件夹,删除最后一层,Java删除时不走回收站,

               删除文件夹时,只有是空文件夹只能删除

    重命名功能:

    public boolean renameTo(File dest):重命名file文件夹成dest

                      路径名相同重命名,不同时先剪切在重命名

    判断功能:

    public boolean isDirectory():判断是否是目录

    public boolean isFile():判断是否是文件

    public boolean exists():判断是否存在

    public boolean canRead():判断是否可读

    public boolean isHidden():判断是否隐藏

        public static void main(String[] args) {
            File file1 = new File("D:\\Wet_Download\\Xunlei_Download\\wangwangwang");
            System.out.println("mkdir:" + file1.mkdir());
            System.out.println("mkdir:" + file1.mkdir());
    
            File file2 = new File("D:\\Wet_Download\\Xunlei_Download\\xiaojingzi.txt");
            try {
                System.out.println("mkdir:" + file2.createNewFile());
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            File file3 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy\\xio.txt");
            System.out.println("mkdirs:" + file3.mkdirs());
    
            System.out.println("delete:" + file3.delete());
            System.out.println("delete:" + file3.delete());
            System.out.println("delete:" + file1.delete());
            System.out.println("delete:" + file2.delete());
    
            File file4 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy\\hello.txt");
            File file5 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy\\gulao.txt");
            System.out.println(file4.renameTo(file5));
            System.out.println("------------");
    
            File file6 = new File("D:\\Wet_Download\\Xunlei_Download\\wyy");
            System.out.println(file6.isDirectory());
            System.out.println(file6.isFile());
            System.out.println(file6.exists());
            System.out.println(file6.canRead());
            System.out.println(file6.canWrite());
            System.out.println(file6.isHidden());
    
        }

    获取功能:

    public String getAbsolutePath():获取绝对路径

    public String getPath():获取相对路径

    public String getName():获取名称

    public long length():获取字节数

    public long lastModified():获取最后一次修改时间,毫秒值

        public static void main(String[] args) {
            File file = new File("D:\\Wet_Download\\Xunlei_Download\\wyy");
            
            System.out.println("getAbsolutePath:" + file.getAbsolutePath());
            System.out.println("getPath:" + file.getName());
            System.out.println("getName:" + file.getName());
            System.out.println("length:" + file.length());
            System.out.println("lastModified:" + file.lastModified());
            
            Date d = new Date(1533819207190l);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String s = sdf.format(d);
            System.out.println(s);
            
            Date da = new Date();    // 获取现在的时间
            SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String st = sdf.format(da);
            System.out.println(st);
        }

    插入:时间转字符串以及字符串转时间

    // 时间转字符串输出:
            Date d = new Date(1533819207190l);    // 毫秒值
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String s = sdf.format(d);
            System.out.println(s);
            
            Date da = new Date();    // 获取现在的时间
            SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String st = sdf.format(da);
            System.out.println(st);
    
    // 字符串转时间输出:
                    String s = "2015-11-20";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//不能处理或者没有权限处理
            Date d = sdf.parse(s);            

    高级获取功能:

    public String[] list():返回指定文件夹或文件字符串文件名数组

    public File[] listFiles():返回指定文件夹或文件的文件类数组

        public static void main(String[] args) {
            File file = new File("D:\\Wet_Download");
            
            String[] st = file.list();
            System.out.println(Arrays.toString(st));
            
            File[] fi = file.listFiles();
            System.out.println(Arrays.toString(fi));
        }

    文件名称过滤器:

    public String[] list(FilenameFilter filter):根据过滤器返回指定文件夹或文件字符串文件名数组

    public File[] listFiles(FilenameFilter filter):根据过滤器返回指定文件夹或文件的文件类数组

        public static void main(String[] args) {
            File file = new File("D:\\Wang_File\\Home_Work\\dynamic_convolution");
            String[] strArray = file.list(new FilenameFilter() {
                public boolean accept(File dir, String name) {
    /*                File fil = new File(dir, name);
                    if(fil.isFile()) {
                        if(name.endsWith(".jpg")) {
                            return true;
                        }
                    }
                    return false;*/
                    return new File(dir, name).isFile() && name.endsWith(".jpg");
                }
            });
            System.out.println(Arrays.toString(strArray));
        }

     

    3. IO流

    3.1 递归

    递归:方法内部调用方法本身的现象

    注意事项

    1. 递归需要有出口,否则就是死递归

    2. 递归的次数不能够太多,否则就会导致内存溢出

    3. 构造方法不能够递归调用

        public static int calc(int n) {
            if(n == 1) {
                return 1;
            }else {
                return n * calc(n - 1);
            }
        }
        public static void deleteFolder(File srcFolder) {
            File[] fileArray = srcFolder.listFiles();
            for(File file : fileArray) {        // 删除文件
                if(file.isDirectory()) {
                    deleteFolder(file);
                }else {
                    System.out.println(file.getName() + "----" + file.delete());
                }
            }
            System.out.println(srcFolder.getName() + "----" + srcFolder.delete());    // 删除文件夹
        }

    3.2 java IO流的分类:

    按照流向:输入流:写数据,输出流:读数据

    按照数据类型:字节流:都可以使用字节流来传输

    输入字节流:读取数据  InputStream

    输出字节流:写出数据  OutputStream

    字符流:如果是文本类型的数据,可以使用记事本打开,就可以采用字符流来传输

    输入字符流:读取数据  Reader

    输出字符流:写出数据  Writer

    3.2.1 OutputStream

    FileOutputStream的构造方法:

    FileOutputStream(File file):

    FileOutputStream(String name):调用系统功能创建文件,创建fos对象,把fos对象指向这个文件

    FileOutputStream(String name, boolean append):true时追加

    FileOutputStream(File file, boolean append):true时追加

     

    close():

    A 让流对象变成垃圾,这样就可以被垃圾回收器回收了

    B 通知系统去释放文件相关的资源

    public void write(int b):

    public void write(byte[] b):

    public void write(byte[] b, int off, int len):

        public static void main(String[] args) throws IOException {
            OutputStream fos = new FileOutputStream("fos.txt");
            fos.write("hello,Io".getBytes());
            fos.write("xiaojingzi".getBytes());
            fos.write(382);
            fos.write("xiaojingzi".getBytes(), 2, 3);
            byte[] bys = {'a', 'b', 'c'};
            fos.write(bys);
            fos.close();    // A 让流对象变成垃圾,这样就可以被垃圾回收器回收了 B 通知系统去释放与该文件有关的资源
        }

    加入异常处理的字节输出流操作

            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream("fos1.txt");
                fos.write("wa".getBytes());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fos != null) {
                    try {
                        fos.close(); // 只有fos不是null才能够调用
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
            }

    3.2.2 OutputStream

    构造方法:

    FileInputStream(File file):

    FileInputStream(FileDescriptor fdObj):

    FileInputStream(String name):

        public static void main(String[] args) throws IOException {
            FileInputStream fos = new FileInputStream("fos.txt");
            int by = 0;
            while((by = fos.read()) != -1) {
                System.out.print((char)by);
            }
        }

    文件的复制:可以复制中文,IO流先读再写,没有做任何转换,所以可以做正常显示

        public static void main(String[] args) throws IOException {
            FileInputStream file = new FileInputStream("fos.txt");
            FileOutputStream fos = new FileOutputStream("b.txt");
            int by = 0;
            while((by = file.read()) != -1) {
                fos.write(by);
            }
            fos.close();
            file.close();
        }

    !字节流适用于任意格式的文件

    高效率读取:

        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("fos.txt");
            byte[] bys = new byte[5];
            int len = 0;
            while((len = fis.read(bys)) != -1) {
                System.out.print(new String(bys, 0, len));
            }
        }

     最终版:数组的长度一般是1024或者1024的整数倍

        public static void main(String[] args) throws IOException {
            FileInputStream fis = new FileInputStream("fos.txt");
            byte[] bys = new byte[1024];
            int len = 0;
            while((len = fis.read(bys)) != -1) {
                System.out.print(new String(bys, 0, len));
            }
        }

    3.3 字节缓冲流

    字节流读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java在本身设计时考虑到这样的设计思想,提供了字节缓冲区流

    字节缓冲输出流:BufferedOutputStream

    构造方法:一般使用默认的缓冲器大小即可

    BufferedOutputStream(OutputStream out):使用默认输出缓冲区的缓冲字符输出流

    BufferedOutputStream(OutputStream out, int size):指定输出缓冲区的缓冲字符输出流

    字节缓冲输入流:BufferedInputStream

    BufferedInputStream(InputStream out):使用默认输出缓冲区的缓冲字符输出流

    BufferedInputStream(InputStream out, int size):指定输出缓冲区的缓冲字符输出流

    例:传输视频文件:

        public static void main(String[] args) throws IOException {
            BufferedInputStream buf = new BufferedInputStream(new FileInputStream("D:\\Wet_Download\\Baiduyun_Download\\day20\\avi\\20.01_IO流(递归概述和注意事项).avi"));
            BufferedOutputStream bof = new BufferedOutputStream(new FileOutputStream("D:\\Wet_Download\\copy.avi"));
            
            byte[] bys = new byte[1024];
            int len;
            while((len = buf.read(bys)) != -1) {
                bof.write(bys, 0, len);
            }
        }

    3.4 转换流

    字符流=字节流+编码表

    编码表:由现实世界额字符和对应的数值组成的一张表

    ASCII码表,最高位为符号位,其余为数值位

    ISO-8859-1,拉丁码表,8位表示一个数据

    gb2313:中文编码表

    gbk:

    Unicode:国际标准码,融合了一个文字,所有文字都用两个字节表示,java使用的都是Unicode

    Utf-8:最多用三个字节来表示一个字符,使用尽可能少的字节数来表示一个字符

    String类中的编码与解码问题:

    String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
    byte[] getBytes(string charsetName):使用指定的字符集合将字符串编码为字节数组

    windows:默认本地系统编码为GBK

     

        public static void main(String[] args) throws UnsupportedEncodingException {
            byte[] bys = "你好".getBytes("GBK");
            System.out.println(Arrays.toString(bys));//[-60, -29, -70, -61]
            String ss = new String(bys, "GBK");
            System.out.println(ss);
            
            byte[] bts = "你好".getBytes("UTF-8");
            System.out.println(Arrays.toString(bts));//[-28, -67, -96, -27, -91, -67]
            String bs = new String(bts, "UTF-8");
            System.out.println(bs);
        }

    3.4.1 字符流(转换流)

    3.4.1 OutputStreamWriter

    构造方法:

    OutputStreamWriter(OutputStream out):创建一个使用默认字符编码的OutputStreamWriter

    OutputStreamWriter(OutputStream out, Charset cs):创建一个使用给定字符集的OutputStreamWriter

    OutputStreamWriter(OutputStream out, CharsetEncoder enc):创建一个使用给定字符集编码器的OutputStreamWriter

    OutputStreamWriter(OutputStream out, Striing charsetName):创建一个使用命名字符集的OutputStreamWriter

        public static void main(String[] args) throws IOException {
            OutputStreamWriter osv = new OutputStreamWriter(new FileOutputStream("xiaojignzi.txt"), "UTF-8");
            osv.write("中国");
            osv.close();
        }

    接口方法:

    public void write(int c):写一个字符

    public void write(char[] cbuf):写一个字符数组

    public void write(char[] cbuf,int off, int len):写一个字符数组的一部分

    public void write(Striing str):写一个字符串

    public void write(String str, int off, int len):写一个字符串的一部分

        public static void main(String[] args) throws IOException {
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("xiaojignzi.txt"));
            char[] ch = {'a', 'b', 'c'};
            
            osw.write("小镜子");
            osw.write(ch);
            osw.write(ch, 0, 1);
            osw.write("小君子", 0, 1);
            osw.flush();
            
            osw.close();    //先刷新后关闭
        }

    3.4.2 InputStreamReader

    构造方法:

    InputStreamReader(InputStream in):创建一个使用默认字符集的InputStreamReader

    InputSteamReader(InputStream in, Charset cs):创建一个使用给定字符集的InputStreamReader

    InputStreamReader(InputStream in, CharsetDecoder dec):创建一个使用给定字符集编码器的InputStreamReader

    InputStreamReader(InputStream in, String charsetName):创建一个使用命名字符集的InputStreamReader

        public static void main(String[] args) throws IOException {
            InputStreamReader isr = new InputStreamReader(new FileInputStream("xiaojignzi.txt"), "GBK");
            int ch = 0;
            while((ch = isr.read()) != -1) {
                System.out.print((char)ch);
            }
            isr.close();
        }

    使用什么编码方式写的数据,则以哪种编码方式写数据

    接口方法:

    public int read():一次读取一个字符

    public read(char[] chs):一次读取一个字符数组

        public static void main(String[] args) throws IOException {
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("xiaojingzi.txt"), "UTF-8");
            osw.write("xiaojingzi\r\n微信开发者工具");
            osw.close();
            InputStreamReader ops = new InputStreamReader(new FileInputStream("xiaojingzi.txt"), "UTF-8");
            OutputStreamWriter ors = new OutputStreamWriter(new FileOutputStream("xiaojunzi.txt"), "UTF-8");
            
            char[] ch = new char[1024];
            int len = 0;
            while((len = ops.read(ch)) != -1) {
                ors.write(ch, 0, len);
            }
            ors.close();
            ops.close();
        }

    3.4.3 FileWriter:采用本地的编码方式

    OutputStreamWriter的子类

    构造方法:

    FileWriter(File file):File指定文件名

    FileWriter(File file, boolean append):File指定文件名,并确定是否追加

    FileWriter(FileDescriptor fd):

    FileWriter(String fileName):用String指定文件名

    FileWriter(String fileName, boolean append):用String指定文件名,并确定是否追加

    3.4.4 FileReader:采用本地的编码方式

    InputStreamReader的子类

    构造方法:

    FileReader(File file):指定的file读取

    FileReader(FileDescriptor fd):给定的FileDescriptor读取

    FileReader(String fileName):给出读取文件的名称

        public static void main(String[] args) throws IOException {
            FileReader fr = new FileReader("D:\\Wet_Download\\Baiduyun_Download\\04.Python3.5 装饰器编程 18课\\源码\\内置方法.py");
            FileWriter fw = new FileWriter("D:\\wang.txt");
            
            char[] ch = new char[1024];
            int len = 0;
            while((len = fr.read(ch)) != -1) {
                fw.write(ch, 0, len);
            }
            fw.close();
            fr.close();
        }

    3.4.5 字符缓冲输出流:BufferedWriter,如果是追加写,FileWriter("文件名", true)

    构造方法:

    BufferedWriter(Writer in):创建使用默认大小的输入缓冲区缓冲区字符输入流

    BufferedWriter(Writer in, int sz):创建使用指定大小的输入缓冲区字符输入流

    接口方法:

    public void newLine():根据系统来产生一个换行符

    3.4.6 字符缓冲输入流:BufferedReader

    构造方法:

    BufferedReader(Reader in):创建使用默认大小的输入缓冲区缓冲区字符输入流

    BufferedReader(Reader in, int sz):创建使用指定大小的输入缓冲区字符输入流

    接口方法:

    public String readLine():一次读取一行数据

    不包含换行符,读不到新行放回null

        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new FileReader("xiaojingzi.txt"));
            BufferedWriter bw = new BufferedWriter(new FileWriter("wanwang.txt"));
            char[] chs = new char[1024];
            int len = 0;
            while((len = br.read(chs)) != -1) {
                bw.write(chs, 0, len);
            }
            br.close();
            bw.close();
        }

     按照行复制文件的案例:

        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new FileReader("xiaojingzi.txt"));
            BufferedWriter bw = new BufferedWriter(new FileWriter("hh.txt"));
            String line = null;
            while((line = br.readLine()) != null) {
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
        }

     

    复制多级文件的案例

    package dat_20;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class MoreFile {
        public static void main(String[] args) throws IOException {
            File srcFile = new File("D:\\简历");
            File destFile = new File("D:\\move");
            System.out.println(destFile.mkdir());
            
            copyFolder(srcFile, destFile);
        }
        
        public static void copyFolder(File srcFile, File destFile) throws IOException {
            if(srcFile.isDirectory()) {
                File newFolder = new File(destFile, srcFile.getName());
                newFolder.mkdir();
                File[] fileArray = srcFile.listFiles();
                for(File file : fileArray) {
                    copyFolder(file, newFolder);
                }
            }else {
                File newFile = new File(destFile, srcFile.getName());
                copyFile(srcFile, newFile);
            }
        }
        
        public static void copyFile(File srcFile, File destFile) throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
            
            byte[] bys = new byte[1024];
            int len = 0;
            while((len = bis.read(bys)) != -1) {
                bos.write(bys, 0, len);
            }
            bos.close();
            bis.close();
        }
    }

     学生类根据总分从分高到低排序:

        public static void main(String[] args) throws IOException{
            TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
    
                @Override
                public int compare(Student o1, Student o2) {
                    int num1 = o2.getSum() - o1.getSum();
                    int num2 = num1 == 0 ? o2.getChinese() - o1.getChinese() : num1;
                    int num3 = num2 == 0 ? o2.getMath() - o1.getMath() : num2;
                    int num4 = num3 == 0 ? o2.getName().compareTo(o1.getName()) : num3;
                    return num4;
                }
                
            });
            for(int x = 0; x < 5; x++){
                Student st = new Student();
                Scanner sc = new Scanner(System.in);
                System.out.println("please input student grade" + x);
                System.out.println("please input student name");
                st.setName(sc.nextLine());
                System.out.println("please input chinese grade");
                st.setChinese(sc.nextInt());
                System.out.println("please input math grade");
                st.setMath(sc.nextInt());
                System.out.println("please input english grade");
                st.setEnglish(sc.nextInt());
                ts.add(st);
            }
            
            BufferedWriter bw = new BufferedWriter(new FileWriter("Student"));
            bw.write("学生成绩如下:");
            bw.newLine();
            bw.flush();
            bw.write("姓名,语文成绩,数学成绩,英语成绩");
            bw.newLine();
            bw.flush();
            for(Student s : ts){
                StringBuilder sb = new StringBuilder();
                sb.append(s.getName()).append(",").append(s.getChinese()).append(",").append(s.getMath()).append(",").append(s.getEnglish());
                bw.write(sb.toString());
                bw.newLine();
                bw.flush();
            }
            bw.close();
            System.out.println("学生信息存储完毕");
        }

    模拟BufferedReader 的readLine()功能

    public class MyBufferedReader {
        private Reader r;
        
        public MyBufferedReader(Reader r){
            this.r = r;
        }
        
        public String readLine() throws IOException{
            StringBuffer sb = new StringBuffer();
            int ch = 0;
            while((ch = r.read()) != -1){
                if(ch == '\r'){
                    continue;
                }else if(ch == '\n'){
                    return sb.toString();
                }else{
                    sb.append((char)ch);
                }
            }
            
            if(sb.length() > 0){
                return sb.toString();
            }
            
            return null;
        }
        
        public void close() throws IOException{
            this.r.close();
        }
    }

    3.4.7 LineNumberReader(BufferedReader的子类)

    int getLineNumber():获取行号

    void setLineNumber(int):设置行号

        public static void main(String[] args) throws IOException{
            LineNumberReader lnr = new LineNumberReader(new FileReader("s"));
            lnr.setLineNumber(10);
            String line = null;
            while((line = lnr.readLine()) != null){
                System.out.println(lnr.getLineNumber() + ":" + line);
            }
            lnr.close();
        }

    3.4.8 为了保证文件只创建一次,可以使用静态代码块

    private static File file = new File("文件名");
    static {
             try{
                 file.createNewFile();
             }catch(IOException e){
                 System.out.println("创建文件夹失败");
        } }

     3.5 操作基本数据类型的流

    3.5.1 DataInputStream:数据输出流允许应用程序将适当方式将基本Java数据类型输入流中,应用数据可以使用数据输入流将数据读入

    构造方法:DataOutputStream(OutputStream out):创建一个新的数据输入流,将数据写入指定基础输出流

    3.5.2 DataOutputStream:数据输出流使应用程序以便携式方式将原始Java数据类型写入输出流。 然后应用程序可以使用数据输入流来读取数据。

    构造方法:DataInputStream(InputStream input):创建一个新的数据输出流,将数据读出

    public static void main(String[] args) throws IOException{
            //write();
            read();
        }
        
        public static void write() throws IOException{
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("dos.txt"));
            dos.writeByte(10);
            dos.writeShort(100);
            dos.writeInt(1000);
            dos.writeChar('a');
            dos.writeFloat(23.878f);
            dos.writeDouble(343.38);
        }
        
        public static void read() throws IOException{
            DataInputStream dip = new DataInputStream(new FileInputStream("dos.txt"));
            byte b = dip.readByte();
            short s = dip.readShort();
            int i = dip.readInt();
            char c = dip.readChar();
            float f = dip.readFloat();
            double d = dip.readDouble();
            
            dip.close();
            
            System.out.println((int)c);
        }

    3.6 内存操作流

    操作字节数组:

    ByteArrayInputStream:包含了一个内部缓冲区,该缓冲器可以从流中读取字节,内部计数器跟踪read方法要提供的下一个字节,关闭ByteArrayInputStream无效,此类中的方法在关闭此流后仍可以被调用,而不会产生任何的IOException.

    ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个byte数组,缓冲区会随着数据的不断写入自动增长,可以使用toByteArray()和toString()获取数据

    操作字符数组:

    CharArrayReader

    CharArrayWrite

    操作字符串:

    StringReader

    StringWriter

        public static void main(String[] args) throws IOException{
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            
            for(int x = 0; x < 20; x++){
                baos.write(("hello" + x).getBytes());
            }
            
            byte[] bys = baos.toByteArray();
            
            System.out.println(Arrays.toString(bys));
            //不需要释放资源
            ByteArrayInputStream bais = new ByteArrayInputStream(bys);
            
            int by = 0;
            while((by = bais.read()) != -1){
                System.out.print((char)by);
            }
        }

    3.7 打印流:

    字节打印流:PrintStream

    字符打印流:PrintWriter:

    特点:

    1. 只能操作目的地,不能操作数据

    2. 可以操作任意类型的数据

    3. 如果启动了自动刷新,可以自动刷新

    4. 可以操作文件的流

    public static void main(String[] args) throws IOException{
            PrintWriter pw = new PrintWriter(new FileWriter("pw.txt"), true);//带true实现了自动刷新的功能,但是需要调用println方法才可以
            pw.write("hello");
            pw.write("world");
            pw.write("java");
            //pw.close();
            pw.print(true);
            pw.print(100);
            pw.print("heool");
            pw.print("wangjing");
            pw.println("xiaojingzi");    //实现了换行
            /*println相当于实现了
             *write();
             *newLine();
             *flush();
             *三种方法的操作
             */
            pw.close();
        }

    使用打印流实现复制文本文件

        public static void main(String[] args) throws IOException{
            /*BufferedWriter bw = new BufferedWriter(new FileWriter("copy.java"));
            BufferedReader br = new BufferedReader(new FileReader("Student"));
            String line = null;
            while((line = br.readLine()) != null){
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
            bw.close();
            br.close();*/
            BufferedReader br = new BufferedReader(new FileReader("Student"));
            PrintWriter pw = new PrintWriter(new FileWriter("copy.java"), true);
            String line = null;
            while((line = br.readLine()) != null){
                pw.println(line);
            }
            br.close();
            pw.close();
        }

     3.8 标准输入输出流

    System类中有两个成员变量:

    public static final InputStream in "标准"输入流

    public static final PrintStream out "标准"输出流

    InputStream is = System.in;

    PrintStream ps = System.out;

    public static void main(String[] args){
            //本质是把IO流输出到控制台(默认输出设备控制台,输入设备是键盘)
            System.out.println("helloworld");
            
            PrintStream ps = System.out;
            ps.println("xiaojignzi");
            //ps.print();    报错
            ps.println();
        }

    键盘录入数据:

    A:main方法的args接收数据

    B:Scanner(JDK5以后)

      Scanner sc = new Scanner(System.in)

      String s = sc.nextLine();

    注:Scanner容易出现的小问题

    先获取Int再获取字符串时,导致输入一个Int以后便不需要再输入,然后字符串读取的只是回车符。

     C:通过字符缓冲流包装标准的输入流实现:BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); /*上述的语句等价为
             * InputStream is = System.in;
             * InputStreamReader isr = new InputStreamReader(is);
             * BufferedReader br = new BufferedReader(isr);
             */
            System.out.println("请输入一个字符串");
            String line = br.readLine();
            System.out.println("您输入的字符串是:" + line);
            
            System.out.println("请输入一个整数");
            int i = Integer.parseInt(br.readLine());
            System.out.println("您输入的整数是:" + i);
        }

    输出数据到控制台

        public static void main(String[] args) throws IOException{
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
            /*
             * PrintStream ps = System.out;
             * OutputStream os = ps;        (OutputStream os = System.out;)   多态
             * OutputStreamWriter osw = new OutputStreamWriter(os)
             * BufferedWriter bw = new BufferedWriter(osw);
             */
            bw.write("hello");
            bw.newLine();
            bw.write("world");
            bw.newLine();
            bw.write("xiaojignzi");
            bw.flush();
        }

    3.9 RandomAccessFile

    RandomAccessFile类不属于任何流,是Object类的子类,融合了InputStream和OutputStream的功能,支持对随机访问文件的读取和写入

    有四种模式,常用是rw可以同时读写,文件不存在将尝试创建

        public static void main(String[] args) throws IOException {
            write();
            read();
        }
    
        public static void read() throws IOException {
            RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
            int i = raf.readInt();
            System.out.println(i);
            System.out.println("当前文件的指针是:" + raf.getFilePointer()); //4 int 类型数据占四个字节
            
            char ch = raf.readChar();
            System.out.println(ch);
            System.out.println("当前文件的指针位置是:" + raf.getFilePointer());  //6 char 类型数组占两个字节
            
            String s = raf.readUTF();
            System.out.println(s);
            System.out.println("当前文件的指针位置是:" + raf.getFilePointer()); //14 先读取两个字节,再读取后面的字节
            
            raf.seek(4);
            ch = raf.readChar();
            System.out.println(ch);    //a
            raf.close();
        }
    
        public static void write() throws IOException {
            RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
            raf.writeInt(100);
            raf.writeChar('a');
            raf.writeUTF("小哈");
            raf.close();
        }

    3.10 SequenceInputStream表示其它输入流的逻辑串联,它从输入流的有序集合开始,并从第一个输入流开始读取,直到文件的末尾,接着从第二个输入流读取,依次类推,直到最后一个输入流文件的末尾为止  

    合并流读取两个文件的内容复制到一个文件中

        public static void main(String[] args) throws IOException{
            InputStream is1 = new FileInputStream("dos.txt");
            InputStream is2 = new FileInputStream("pw.txt");
            SequenceInputStream sis = new SequenceInputStream(is1, is2);
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy"));
            
            byte[] bys = new byte[1024];
            int len = 0;
            while((len = sis.read(bys)) != -1){
                bos.write(bys, 0, len);
            }
            bos.close();
            sis.close();
        }

    合并多个文件:

        public static void main(String[] args) throws IOException{
            Vector<InputStream> v = new Vector<InputStream>();
            InputStream s1 = new FileInputStream("copy");
            InputStream s2 = new FileInputStream("dos.txt");
            InputStream s3 = new FileInputStream("copy.java");
            v.add(s1);
            v.add(s2);
            v.add(s3);
            Enumeration<InputStream> en = v.elements();
            SequenceInputStream sis = new SequenceInputStream(en);
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("xiaojigzi"));
            
            byte[] byt = new byte[1024];
            int len = 0;
            while((len = sis.read(byt)) != -1){
                bos.write(byt, 0, len);
            }
            
            sis.close();
            bos.close();
        }

     3.11 序列化与反序列化流

    序列化流:ObjectOutputStream:将JAVA对象的基本数据类型写入OutputStream,可以使用ObjectInputStream读取(重构对象),可以使用文件来实现对象的持久存储,如果流是网络套接字节流,可以再另一台主机或者另一个进程中重构对象

    反序列化流:ObjectInputStream

    NotSerializableException:未序列化异常

    类通过实现java.io.Serializable 接口以启用序列化功能,未实现此接口无法进行任何的序列化和反序列化。该接口中没有任何的方法需要实现。没有方法的接口被称为标记接口。

    private static final long serialVersionUID = 1087170578858793875L;产生序列化

        public static void main(String[] args) throws IOException, ClassNotFoundException{
            //write();
            read();
        }
        
        public static void write() throws IOException, IOException{
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("xiao"));
            Person p = new Person("wangjing", 20);
            oos.writeObject(p);
            oos.close();
        }
        
        public static void read() throws IOException, ClassNotFoundException{
            ObjectInputStream oos = new ObjectInputStream(new FileInputStream("xiao"));
            Object obj = oos.readObject();
            oos.close();
            System.out.println(obj);    // 多态调用的是子类的方法
        }

    如何不序列化对象的成员变量:使用transient修饰  private transient int age;

    3.12 Properties类:属性集合类,是一个可以和IIO流相结合的集合类

    表示一个持久的属性集,Properties可以保存在流中或者从流中加载,属性列表中每个键和对应的值都是一个字符串

    Properties作为map集合使用

        public static void main(String[] args){
            Properties prop = new Properties();
            prop.put("it001", "hello");
            prop.put("it002", "world");
            prop.put("it003", "java");
            
            
            Set<Object> set = prop.keySet();
            for(Object key : set){
                Object value = prop.get(key);
                System.out.println(key + "-----" + value);
            }
        }

    Properties的特殊功能使用

    public Object setProperty(String key, String value):添加元素

    public String getProperty(String key):获取元素

    public Set<String> stringPropertyNames():获取所有键的集合

        public static void main(String[] args){
            Properties prop = new Properties();
            prop.setProperty("张三", "30");
            prop.setProperty("李四", "40");
            prop.setProperty("王五", "30");
            
            Set<String> set = prop.stringPropertyNames();
            for(String key : set){
                String value = prop.getProperty(key);
                System.out.println(key + "----" + value);
            }
        }

    Properties与IO流结合使用

    public void load(Reader reader):把文件中的数据读取到集合中

    public void store(Writer writer, String comments):把集合中的数据存储到文件

        public static void main(String[] args) throws IOException{
            myStore();
        }
        
        public static void myLoad() throws IOException{
            Properties prop = new Properties();
            Reader r = new FileReader("prop.txt");
            prop.load(r);
            r.close();
            System.out.println("prop" + prop);
        }
        
        public static void myStore() throws IOException{
            Properties prop = new Properties();
            prop.setProperty("wangjing", "30");
            prop.setProperty("ixaoxiao", "10");
            prop.setProperty("wang", "30");
            Writer w = new FileWriter("wang.txt");
            prop.store(w, "heoolworld");    //"heoolworld"是注释
            w.close();
        }

    判断文件中是否有指定的键,如果有就修改值

        public static void main(String[] args) throws IOException{
            Properties prop = new Properties();
            Reader r = new FileReader("wang.txt");
            prop.load(r);
            r.close();
            
            Set<String> set = prop.stringPropertyNames();
            for(String key : set){
                if("wang".equals(key)){
                    prop.setProperty(key, "100");  // 替换
                    break;
                }
            }
            
            Writer w = new FileWriter("wang.txt");
            prop.store(w, null);
            w.close();
        }

    3.13 NIO包下的IO流

    JDK4出现NIO,新IO和传统的IO有相同的目的,都是用于进行输入输出的额,但新的IO使用了不同的方式来处理输入输出的,采用内存映射文件的方式。将文件或者文件的一段区域映射到内存中,就可以像访问内存一样的来访问文件了,这样的效率比旧的IO要高很多。

    Path:路径

    Paths:有一个静态方法返回一个路径

    public static Path get(URI uri)

    Files:提供了静态方法供我们使用

    public static long copy(Path source, OutputStream out)

    public static Path write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options)

        public static void main(String[] args) throws IOException, IOException{
            Files.copy(Paths.get("prop.txt"), new FileOutputStream("copy.java"));    // 复制文件
            ArrayList<String> array = new ArrayList<String>();
            array.add("hello");
            array.add("wrold");
            array.add("java");
            Files.write(Paths.get("array.txt"), array, Charset.forName("GBK"));
        }

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 12:57 , Processed in 0.066354 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表