zoukankan      html  css  js  c++  java
  • Java中的I/O

    1、Java中的I/O分类

    I/O分类:

    • 输入流,输出流,或者字节流,字符流

    I/O中的四个抽象基类:

    • InputStream,OutputStream:两者属于字节流,前者输入,后者输出。一般后缀名为这两个的都属于字节流家族。
    • Reader,Writer:两者属于字符流,前者输入,后者输出。一般后缀名为这两个的都属于字符流家族。

    2、File常用方法

    常用方法:

    • mkdir()创建一个文件夹,mkdirs()创建一个文件夹以及它的上级文件夹。
    • createNewFile()创建一个文件。
    • isDirectory()判断文件是否存在以及是否是一个目录,exists()判断文件路径是否存在。
    • delete()删除文件或者目录。
    • 示例代码如下
     1 package com.spring.test.service;
     2 
     3 import java.io.File;
     4 import java.io.IOException;
     5 
     6 /**
     7  * @Author: philosopherZB
     8  * @Date: 2019/9/29
     9  */
    10 public class Test {
    11     public static void main(String[] args){
    12         //File.separator返回本系统的名称分隔符,方便代码跨系统移植,比如windows下文件分隔符是,而其他系统可能就不是。
    13         //创建一个文件夹
    14         String path1 = "D:" + File.separator + "Test";
    15         File file1 = new File(path1);
    16         file1.mkdir();
    17 
    18         //创建一个文件夹以及他的上级文件夹
    19         String path2 = "D:" + File.separator + "Test" + File.separator + "Temp" + File.separator + "demo";
    20         File file2 = new File(path2);
    21         file2.mkdirs();
    22 
    23         //创建一个文件
    24         String path3 = "D:" + File.separator + "Test" + File.separator + "Test.txt";
    25         File file3 = new File(path3);
    26         try {
    27             file3.createNewFile();
    28         } catch (IOException e) {
    29             e.printStackTrace();
    30         }
    31 
    32         //读取文件夹以及文件
    33         String path4 = "D:" + File.separator  + "Test";  //指定读取目录
    34         File file4 = new File(path4);
    35         //判断目录是否存在
    36         if(file4.isDirectory()){
    37 //            String[] str = file4.list();
    38 //            for(int i=0;i<str.length;i++){
    39 //                File f = new File("D:" + File.separator + "Test" + File.separator + str[i]);
    40 //                if(f.isDirectory()) {
    41 //                    System.out.println(str[i] + "是一个目录");
    42 //                }else{
    43 //                    System.out.println(str[i] + "是一个文件");
    44 //                    f.delete();//删除该文件
    45 //                }
    46 //            }
    47             //如果需要获取全路径可以使用listFiles,这个方法的返回时File。
    48             File[] files = file4.listFiles();
    49             if(files.length!=0) {
    50                for(File file : files){
    51                    if(file.isDirectory()) {
    52                     System.out.println(file + "是一个目录");
    53                    }else{
    54                     System.out.println(file + "是一个文件");
    55                     file.delete();//删除该文件
    56                   }
    57                }
    58             }
    59         }else{
    60             System.out.println("目录不存在");
    61         }
    62     }
    63 }
    View Code

    3、对文件进行写入,读出

    分别使用字符流,字节流写入读出:

    • 字节流使用的是:BufferedOutputStream(写入),BufferedInputStream(读出)
    • 字符流使用的是:BufferedWriter(写入),BufferedReader(读出)
    • 其中字符流是线程安全的(源码中对应的方法加了sychronized),字节流不是线程安全的。
    • 其中使用的try-with-resource是一个Java的语法糖,如果是实现了Closeable接口的类,可以免去自己写finally块进行资源关闭的操作
    • 示例代码如下:
     1 package com.spring.test.service;
     2 
     3 import java.io.*;
     4 
     5 /**
     6  * @Author: philosopherZB
     7  * @Date: 2019/9/29
     8  */
     9 public class Test {
    10     public static void main(String[] args){
    11         String path = "D:" + File.separator + "Test" + File.separator + "Test.txt";
    12         String str = "文件测试内容";
    13         //字节流
    14         writeFile(path,str);
    15         System.out.println("字节流:" + readFile(path));
    16         //字符流
    17         writeFileByStr(path,str);
    18         System.out.println("字符流:" + readFileByStr(path));
    19     }
    20 
    21     //写入字符串到指定文件中----字节流,字节流线程不安全,可以通过synchronized来使其成为一个静态同步方法
    22     public static synchronized void writeFile(String fileName,String content){
    23         //此处使用的是try-with-resource,实现了Closeable接口的类,可以免去自己写finally块进行资源关闭的操作,是一个java的语法糖
    24         try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(fileName)))){
    25             byte[] b = content.getBytes();
    26             bos.write(b);  //写入
    27             bos.flush();   //刷新缓存,及时将缓存中的数据刷到文件中
    28         }catch (IOException e){
    29             throw new RuntimeException(e.getMessage(), e);
    30         }
    31     }
    32 
    33     //从指定文件中读取字符串-----字节流,字节流线程不安全,可以通过synchronized来使其成为一个静态同步方法
    34     public static synchronized String readFile(String fileName){
    35         try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(fileName)))){
    36             byte[] b = new byte[256];
    37             int count = 0;
    38             int temp = 0;
    39             //不确定文件内容有多大,循环读取
    40             //读到文件末尾的时候才会返回-1
    41             while((temp = bis.read()) != -1){
    42                 b[count++] = (byte) temp;
    43             }
    44             return new String(b);
    45         }catch (IOException e){
    46             throw new RuntimeException(e.getMessage(), e);
    47         }
    48     }
    49 
    50     //写入字符串到指定文件中----字符流,字符流的write方法是线程安全的
    51     public static void writeFileByStr(String fileName,String content){
    52         try(BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)))){
    53             bw.write(content);
    54             bw.flush();
    55         }catch (IOException e){
    56             throw new RuntimeException(e.getMessage(), e);
    57         }
    58     }
    59 
    60     //从指定文件中读取字符串-----字符流
    61     public static String readFileByStr(String fileName){
    62         try(BufferedReader br = new BufferedReader(new FileReader(new File(fileName)))){
    63             char[] c = new char[256];
    64             int count = 0;
    65             int temp = 0;
    66             //不确定文件内容有多大,循环读取
    67             //读到文件末尾的时候才会返回-1
    68             while((temp = br.read()) != -1){
    69                 c[count++] = (char) temp;
    70             }
    71             return new String(c);
    72         }catch (IOException e){
    73             throw new RuntimeException(e.getMessage(), e);
    74         }
    75     }
    76 
    77 }
    View Code

    4、BIO,NIO,AIO

    BIO(Block IO):

    • 同步阻塞式IO,一般指平常所用的IO类。
    • 一个请求对应一个响应,为了合理的利用资源,可以使用多线程(线程池)。
    • 此IO一般针对并发量较小的场景(<1000)。
    • BIO操作的对象是流(Stream)。
    • 比如:在ATM机上取钱,只能一个一个的取,前面有人的时候,需要等待;取钱的时候,需要本人进行相关取钱操作(取出之后拿到钱才走)。

    NIO(NewIO):

    • 同步非阻塞式IO。
    • 利用Channel(通道)通讯,实现了多路复用。
    • 核心组件:Buffer(缓冲区),Channel(通道),Selector(选择器)
    • NIO操作的对象是缓存区(Buffer)。
    • 基本运行流程:当Channel发生新连接、就绪读,就绪写的时候,首先会在Selector上注册相应的事件,生成一个与Channel绑定的selectKey;其次由一个线程轮询selectKey集合,利用操作系统底层的函数select() 或者 epoll(Linux 2.6之前是select、poll,2.6之后是epoll,Windows是iocp)去操作系统查询IO是否就绪,如果就绪则执行相应的事件处理器(通过selectKey找到Channel,然后利用与Channel绑定的buffer进行实际读写)。
    • 比如:在银行大厅取钱,对于前面是否有人等候,只需要隔一段时间去问一下大堂经理是否可以取钱就可以了,不需要一直去排队(这段时间可以做其他事);取钱的时候,需要柜员进行相关操作,同时也需要保证你也在柜员面前(不能离开,不然柜员可能会找不到你,然后钱就没有实际拿到手里了)。

    AIO(Asynchronous IO):

    • 异步非阻塞式IO。
    • 其实现是基于事件以及回调机制。
    • AIO与NIO有点相似,不过对于实际读写而言,AIO是交给操作系统底层自己去完成的,完成之后会返回一个IO完成的回调消息。
    • 比如:同样是去银行取钱,不过这次你是让朋友去帮忙取的,你朋友会帮你排队,然后取钱,接着把钱给你,并告诉你已经取好了。

    IO阶段:

    • IO中对于读写一般分为两个阶段:就绪读写(准备数据)以及实际读写(真正读写数据)。
    • 对应上面取钱例子而言,就绪读写指的是排队,实际读写指的是取钱操作。

    同步,异步:

    • 同步指的是操作的时候,需要等待当前任务返回结果;异步则相反,它不需要等待当前任务返回,通常情况下是依赖于事件,回调机制来实现任务间的次序关系。
    • 同步,异步对于IO而言指的是实际读写阶段;对应取钱例子而言,就是真正取钱操作(同步,自己取钱;异步,朋友帮忙取钱)。

    阻塞,非阻塞:

    • 阻塞指的是如果任务在执行,当前线程会阻塞,需要等待任务执行完,这期间该线程不能执行其他任务;非阻塞则是说在一个任务执行期间,线程不会阻塞,可以执行其他任务。
    • 阻塞,非阻塞对于IO而言指的是就绪读写阶段;对应取钱例子而言,就是排队等候(阻塞,排队没带手机,只能干等着;非阻塞,排队带了手机,可以一边玩手机一边排队)。

    BIO,NIO,AIO示例代码参考:

    (以上所有内容皆为个人笔记,如有错误之处还望指正。)

  • 相关阅读:
    在Ubuntu下安装TensorFlow-gpu版本
    ubuntu安装和卸载软件命令
    Window7通过Anaconda安装Tensorflow
    Kaggle Titanic Data Science Solutions
    CNN、RNN和DNN的区别
    卷积神经网络介绍
    大数据随想
    golang omitempty 总结
    LeetCode 856 递归思路详解
    安装Nginx的各种报错的解决
  • 原文地址:https://www.cnblogs.com/xihuantingfeng/p/11613820.html
Copyright © 2011-2022 走看看