普歌 - IO详解


前言

欢迎大佬荐临指导博主这一周的复习成果~~
什么是IO?它是这么分类的?它在java有哪些常用的类?它都有哪些具体的作用?那么就让我们围绕着几个问题来展开,希望大家可以通过这一篇博客认识IO,并且会简单的运用。


初识IO流

在学习IO的时候需要我们明白的几个基础的概念

文件与文件夹

我们都知道电脑中的东西都是已两种形式存在,一种是文件另外一种是文件夹的形式,如果我们需要找到它还需要一个路径

那么我们介绍几个基本的英语单词

  • file:文件

    是存储在某种长期储存设备或临时存储设备中的一段数据流

  • directory:文件夹/目录

    就是用来存放整理文件

  • path:路径

    路径在程序中的作用是操作对应的文件位置,所以我们在写路径时候的不能写死,以防出现错误
    比如:
    路径分隔符:在window中是分号,在linux中是冒号
    名称分隔符:在window中是反斜杠\,在linux中是正斜杆/
    下面看一个标准的路径写法的示例:读取的是c盘下的a.txt文件
    路径标准写法

IO流的原理及分类

什么是流呢?

在编程中每一门语言都有独特的操作文件的方式,而java就这种输入输出文件的方式称为流。
	而流是指一串特定的数据,通过一个特定的通道流向指定的位置。

它可以用来处理传输文件、图片、音频、视频之类的数据,也可以处理传输经过编码成字节的字符串文件。

下面就是它的分类:

  • 按照数据单位不同分为
    - 字节流
    - 输出流
  • 数据的流向
    - 输出
    - 输入
  • 按流的角色的不同分为
    - 字节流
    - 处理流/包装流

数据源

前面介绍了流的一些原理,那么我们把他比作一个水的传输过程,那么他就需要一个水箱,那么这个水箱就是数据源。

常见数据源有:数据库、磁盘文件、网络连接、IO设备。

字符和字节

先让我们看看百度百科中的定义

字符指类字形单位或符号,包括字母、数字、运算符号、标点符号和其他符号,以及一些功能性符号。
字节(Byte)是计算机信息技术用于计量存储容量的一种计量单位。

这里我在简单的说一下我的理解,字符就是我们人可以看到的一个一个单位,即使用输入法可以单独打出来的内容。而对于中文英文而言就是一个一个单独的字符。而字节它是计算机的单位由于底层的0和1组成的。1字节 = 8位

绝对路径/相对路径

FIle类

我们学习一个类首先从它的构造方法看起

构造方法

File通过将给定路径字符串转化为抽象路径来创建一个新File实例。

  • 构造方法一
    File(String pathname)

    参数:
    String pathname:字符串的路径名称
    路径可以是以文件结尾,也可以是以文件夹结尾
    路径可以是相对路径,也可以是绝对路径
    通过将给定的路径名字转化为抽象类路径来创建新的File实例

  • 构造方法二
    File(String parent ,String child)
    这个构造方法中参数可以传递两个一个父类的路径,一个子类的路径
    那么这样写有什么好处呢?

    父路径和子路径可以动态的变化

  • 构造方法三
    FIle(File parent, String child)
    父抽象路径名和子路径名字符串用以创建新的 File实例

file中的常用方法

这里就介绍几种常用的方法,详细介绍请到javaAPI中查看

获取功能的方法

  • file.getAbsolutePath( )
    获取file中的路径(如果传入的是绝对路径就返回绝对路径,反之亦然)

  • file.getPath( )
    获取的构造方法中传递的路径

  • file.getName( )
    获取文件传递路径的结尾部分

  • file.getLength( )
    获取文件打小,但是不能获取文件夹的大小(如果传入的是文件夹的路径,那么最后返回0)

判断功能的方法

  • file.exists( )
    这个功能使用的非常的频繁,它的主要作用就是用来判断传入的这个路径是否存在,返回一个布尔类型的字符

  • file.isFile( )
    判断构造方法中传入的这个路径是否以该文件结尾

  • file.isDrectory( )
    这个方法就是判断构造方法中传入的路径是否以文件夹的形式结尾,它与上面的方法互斥

创建删除的方法

  • file.createNewFile( )
    这个方法和它的名字一样,创建一个新的文件,这个也是一个很常用的方法
    需要注意的是:这个方法会产生异常,需要处理(路径不存在就会产生异常)
  • file.mkdirs( )
    这个方法是用来创建文件夹的,前面我们学习了mkdirs这个单词是文件夹的意思,那么这个加了s的意思就是创建多级的文件夹的意思,这个就算路径传入的不对也不会抛出异常,如果方法mkdirs没有加s意味着只能创建单级的文件夹
  • file.delete( )
    将构造函数中的指定的路径删除,下面两类不会删除
  1. 如果文件夹中有东西不会删除
  2. 路径不存在也不会删除

注意:删除在磁盘中直接删除,谨慎使用

在java中常用的方法

  1. 输入流(I)
  • inputStream(字节输入流)
    inputStrem字节输入流抽象类,他是所有类字节输入流的超类
    下面我们用一段代码来介绍它的使用
 @Test
    public void fillIn() {
    //定义文件路径
        String insrc = "/Users/liudemac/Desktop/word/test.txt";
     //初始化
        FileInputStream fileInputStream = null;
        try {
        //定义数组接受这些内容
            byte[] b = new byte[1024];
            //这里定义整形数来获取遍历过程中的参数
            int i;
            fileInputStream = new FileInputStream(insrc);
            //需要注意的是:如果他返回-1那么代表已经取出所有的字符
            while ((i = fileInputStream.read(b)) != -1) {
            //我们使用迭代器遍历得到最终的结果
                for (byte b1 : b) {
                    System.out.print((char) b1);
                }
      }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        //不要忘了最后的关闭资源
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) 
                    e.printStackTrace();
                }
            }
        }
    }
            

在使用中我已用代码详细的解释了字节输出流inputeStream的用法,还需要注意的是为了提高读的效率,read方法我传入的是一个数组。

InputStream读取流有三个方法,分别为read(),read(byte[] b),read(byte[] b, int off, int len)
  • Reader(字符输出流)
    用法与上字节输入流类似,这里我就不多赘述。
    直接上代码
  @Test
    public void fillIn() {
        String insrc = "/Users/liudemac/Desktop/word/test.txt";
        FileReader fileReader = null;
        try {
            char[] b = new char[1024];
            fileReader = new FileReader(insrc);
            fileReader.read(b);
            for (char b1 : b) {
                System.out.print( b1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  1. 输出流(O)
  • outputStream
    这个与上边字节输入流相同
    调用方法与上方一致,我这里就直接讲它的实现方法writer
 @Test
    public void fillOut() {
        String outsrc = "/Users/liudemac/Desktop/word/test.txt";
        FileOutputStream fileOutputStream = null;
        try {
        //注意这个ture,他代表的意思是是否覆盖之前写的,如果没有加这个就会将之前文件中的内容覆盖
            fileOutputStream = new FileOutputStream(outsrc,true);
            String str = "hello";
            //括号中的第二第三参数表示从哪里开始,到哪里结束
            fileOutputStream.write(str.getBytes(), 0, str.length());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

节点流引出的包装流(Buffered)

节点流?

节点流比较好理解,就是咱们在上边java中常用的方法中举出的例子,它们通常只针对特定的数据源(上面已经解释)的读写资源。
即调用的各种抽象类的实现子类。
列如在上方我们调用的

节点流知道了,那什么是包装流呢?让我们看一段比较官方的解释

可以消除节点流的实现差异,也可以提供方便的的方法进行输入输出。

这句话听起来很迷糊,但是熟悉java特性的人就知道这是一种装饰器模式

修饰器模式

可以在不影响其他对象的前提下,以动态,透明的方法来获取对象
这种模式下创建了一个装饰类,用来包装原有的类,并在保持类方法完整性的前提下,提供了额外的功能。
需要注意的是,这个过程是通过调用包裹之后的对象完成功能添加的,而不是直接修改对象的行为,相当于添加了中间层。

那么包装流中的Buffer就是实现了子类中的方法,然后我们通过实现类去调用方法直接传入参数。

文件拷贝

最后让我们看一个IO的实际应用讲一个文件中的东西复制一份放到另外一个和文件中,简称拷贝。
有了前面的经验我相信小伙伴们一定能很快的写出来吧,我这里就放代码了

@Test
    public void fileCopy() {
        String insrc = "/Users/liudemac/Desktop/word/text.txt";
        String putsrc = "/Users/liudemac/Desktop/word/text1.txt";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            byte[] b = new byte[1024];
            int i;
            fileOutputStream = new FileOutputStream(insrc);
            fileInputStream = new FileInputStream(putsrc);
            while ((i = fileInputStream.read(b)) != -1) {
            //这个输出是用来将读取到的数据打印到控制台中,来看
                System.out.printf(new String(b, 0, i));
                fileOutputStream.write(b, 0, b.length);
            }
        } catch (
                IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileOutputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远归的雁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值