Java I/O流学习笔记

1.文件的定义

  文件就是保存数据的地方,有各种不同的类型比如pdf、mp4等

  文件在程序中是以流的方式来操作:java程序(内存)读取磁盘文件叫输入流,java程序写入文件到磁盘叫输出流。

  流:数据在数据源和程序之间经历的路程

  java常用文件操作:

  -new File(String , pathname) //根据路径构建一个File对象

  -new File(File parent , String child)//根据父目录文件+子路径构建

  -new File(String parent , String child)//根据父目录+子路径构建

   等等

 例子1:

 例子2:

  这里如果没有file.creatNewFile(),只有new的话File只是作为创建对象在内存中创建,并不会真正在磁盘中创建该文件。

例子3:

 常用获取文件信息操作方法:

  -file.getName()//得到文件名字

  -file.getAbsolutePath()//得到文件绝对路径

  -file.getParaent()//得到文件的父级目录

  -file.length()//得到文件大小 ps:不同的文件编码方式会导致不同文件大小,比如UTF-8下英文字母占一个字节,中文占三个字节

  -file.exists() //文件是否存在  file.isFile()//是不是一个文件  file.isDirectory()//是不是一个目录

 常用目录操作以及文件删除

  -file.delete()//删除file文件(或者目录) 返回布尔值 反应文件删除是否成功

  -file.mkdir()//在file目录下创建一个目录    file.mkdirs()//创建一个多级目录

2. IO流原理及流的分类

  I/O是Input/Output缩写,I/O技术是非常使用的技术,用于处理文件传输。如读/写文件,网络通讯等。

  Java程序中对于数据的输入/输出操作以“流(stream)”的方式进行。

  java.io包下提供了各种“流”类和接口,用于获取不同种类的数据,并通过方法输入输出数据。

  输入input:读取外部数据(磁盘、数据库等)到程序(内存)中

  输出output:将程序数据写入外部设备中

 

    流的分类:

 -字节流(8bit)二进制文件(视频、图片等)

 -字符流(根据文件编码,一个字符等于多个字节,一般用于文本文件)

流的角色分类:

 -节点流 ;-处理流/包装流

   这里InputSream、Reader……四个类都是抽象类,不能直接创建,必须创建其子类。

    

 

IO流体系中常用的类:

1)字节流InputStream抽象类中常用的子类:

     -FileInputStream:文件输入流

     -BufferedInputStream : 缓冲字节输入流

     -ObjectInputStream:对象字节输入流

 文件流读取文件(输入流)例子:

  

       

 

   这里注意:例子1使用流操作了之后一般需要在finally中关闭流。读取的异常一般是IO异常,这样可以兼容更多的异常。这段代码不能读取中文,因为中文是3个字节,这里的操作只能一个字节一个字节的读取,读取中文需要优化

优化使之能读中文:(说明:这里使用readLen使转String时读取正常)

      读取结果:

 

    这里第一次读了前8个字节,后面读了3个字节

  字节流OutputStream抽象类中常用的子类:

     -FileOutputStream:文件输出流

     -BufferedOutputputStream : 缓冲字节输出流

     -ObjectOutputStream:对象字节输出流

  输出流例子:(outputStream对象的write方法) 

 

   写入字符串也可以这样:

   说明:如果像上面这样创建,写入内容时会覆盖原来的内容,如果是要追加内容的话,输出流创建方式后面加一个参数即可:  

    字节输入输出流综合运用例子:图片文件的拷贝

    操作完成后关闭流对象: 

    这里注意:程序访问C盘可能会出现权限错误,操作时改为其它磁盘即可

 2)字符流:FileReader和FileWriter(使用时必须关闭(close)或者刷新(flush),不然无法写入)

 

   例子 FileReader的使用-单个字符读取(结构与字节型的流差不多)

使用字符数组读取文件:

 

  字符输出流FileWriter例子: 

  这里注意:finally里面没有关闭流或者刷新流,文件里面不会写入任何内容

  字符数组写入:

 

3.节点流、处理流

  节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter

   处理流(包装流)是“连接”已存在的流之上(不直接接触数据源),为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter

    --为什么要有处理流:因为节点流一般操作直接操作数据,比较底层,效率可能没那么高,这时候java设计者就设计了处理流

    处理流处理数据:在BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的只要是Readerd的子类即可,这样就会使其功能比较强大。同理BufferedWriter类中也有属性Writer,可以利用处理流对不同的节点流文件类型进行操作,灵活方便

 

   包装流的这种设计模式叫修饰器设计模式 

   总结节点流和处理流的区别和联系:

     -节点流是底层流,直接和数据打交道

     -处理流是包装节点流,可以消除不同节点流的实现差异,也可以提供更加方便的方法来完成输入输出

     -处理流对节点流进行包装,使用了修饰器设计模式,不会直接与数据原相连

   处理流的功能主要体现在:

     -性能的提高:主要以增加缓冲的方式来提高输入输出效率

     -操作便捷:处理流可以提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

   这里用BufferedReader以及BufferedWriter作为例子使用:

   BufferedReader以及BufferedWriter属于字符流,是按照字符来读取数据的,不能去操作视频等二进制文件。

   关闭时处理流,只需要关闭外层流(包装流)即可,因为实际在操作文件的还是处理流

   BufferedReader的使用:

    BufferedWriter的使用:

    利用BufferedReader和BufferedWriter进行文件拷贝 :

   字节处理流- BufferedInputStream、BufferedOutputStream

   利用这两个处理流拷贝一个图片文件(视频文件也可):

 

 

   对象流-ObjectInputStream、ObjectOutputStream

   这个流看需求使用(能对数据类型和对象进行序列化和反序列化操作)

    -将int num = 100 这个数据保存在文件中而非100数字,并且要求能恢复成int 100

    -将一些对象保存在文件中并且能够从文件恢复

   简单的保存值的操作不能称为序列化

 

   序列化和反序列化:

   -序列化就是在保存数据时,保存数据的值和数据类型

   -反序列化就是在恢复数据时,恢复数据的值和数据类型

   -需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现Serializable Externalizable接口

   -序列化的类一般选择实现Serializable接口因为这是一个标记接口,标记接口-里面没有任何需要重新实现的方法

   ObjectInputStream、ObjectOutputStream的各类接口关系:

 

   使用案例:使用ObjectOutputStream完成一个对象的序列化

    注意:这里的.dat是任取的,保存序列化文件打开一般都是乱码

   使用ObjectInputStream对一个对象的反序列化恢复数据:

 

   注意读写文件细节说明:

    -读写顺序要一致

    -要求序列化或反序列化对象,需要实现Serializable

  -序列化的类建议添加SerialVersionUID为了提高版本兼容性(就是在类里添加一个private static final SerialVersionUID的值,这样的化如果序列化的类进行了普通属性的修改,则java不会认为这是一个新类,而是只认为其进行了一个版本的变更)。

    -序列化对象时,默认将对象的所有属性都序列化,但除了static或transient修饰的成员

    -序列化对象时,要求里面的属性(其它类)的类型也需要实现序列化接口

    -序列化具备可继承性,也就是如果某某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

4. 输入流、输出流

标准输入输出流 InputAndOutput.java

System.in    InputStream类型     默认设备是键盘

System.out   PrintStream类型     默认设备是显示器

   标准输入

   System类的public final static InputStream in = null

   System.in的编译类型是InputStream 运行类型是BufferedInputStream

   标准输出

   System类的public final static PrintStream out = null

   System.out的编译类型是PrintStream,运行类型是PrintStream

  System.out.println就是调用out对象将数据输出到显示器

  Scanner扫描器对象里面就是标准输入流System.in

  转换流transformation – InputStreamReader和OutputStreamWriter

    -默认情况下是按UTF-8编码进行读取写入字符,如果编码格式不一致,读取或写入的操作很有可能就会是乱码。我们应该在字节流转换成字节流的时候定义好编码,这里就要用到转换流。

   输入转换流里有一个最重要的初始化方法,传入 一个字节流 和 一个编码方式 

   应用案例:将字节流转换成字符流,对文件进行读取,进而包装成BufferedReader

 

   应用案例:输出转换流 

 

   打印流 – PrintStream和PrintWriter 只有输出流 没有输入流 

   根据PrintStream的几种初始化方法,可以选择将内容打印到屏幕也可以输出到文件 

5. Properties类

 

   配置文件:mysql.properties 

  1.传统方式 

 

小修改一下: 

 

   假如以后项目中IP这样的信息非常多,那么传统方式就会非常繁琐

 2.使用properties类实现

   Properties类介绍:

    -专门用于读写配置文件的集合类

      配置未见格式:

   键=值

         键=值

    -键值对不需要有空格,值不需要用引号括起来,默认类型是String

   常用方法:

 

   读取:

   修改与创建:

   Ps:

   -这里setProperties如果有这个key就是修改,没有就是创建

   -这里“汤姆”会被存为unicode码

   -这里store第二个参数null代表没有注释,有注释直接加字符串即可

   -Properties的父类是HashTable 核心代码就是HashTable

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值