黑马程序员—Java基础—IO

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

目录:一、其他对象API  二、IO流

一、     其他对象API

System类

System类中的字段和方法都是静态的。

    常见方法:
    long currentTimeMillis();获取当前时间的毫秒值,可以通过此方法检测程序的执行时间。

Properties getProperties();确定当前的系统属性。
    Properties集合中存储的都是String类型的键和值。
    最好使用它自己的存储和取出的方法来完成元素的操作。

 P.S.
    给属性设置一些属性信息,这些信息是全局的,其他程序都可以使用。例:System.setPeroperty("myclasspath","c:\myclass");。

Runtime类

    每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。应用程序不能创建自己的 Runtime 类实例。

    P.S.
    Runtime:没有构造方法摘要,说明该类不可以创建对象。又发现还有非静态的方法,说明该类应该提供静态的返回该类对象的方法。而且只有一个,说明Runtime类使用了单例设计模式。

Math类


    Math:提供了操作数学运算的方法,都是静态的。

    常用方法:
    ceil():返回大于参数的最小整数。
    floor():返回小于参数的最大整数。
    round():返回四舍五入的整数。
    pow(a,b):a的b次方。

Date、DateFormat类

 日期对象和毫秒值之间的转换
    毫秒值-->日期对象:
    1. 通过Date对象的构造方法 new Date(timeMillis);
    2. 还可以通过setTime设置。
    因为可以通过Date对象的方法对该日期中的各个字段(年月日等)进行操作。

    日期对象-->毫秒值:
    1. getTime方法。
    因为可以通过具体的数值进行运算。

    对日期对象进行格式化:
    将日期对象-->日期格式的字符串。
    使用的是DateFormat类中的format方法。

将日期格式的字符串-->日期对象。
    使用的是DateFormat类中的prase方法。

Calendar类

    Calendar 类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

二、 IO流


    IO流用来处理设备之间的数据传输。Java对数据的操作是通过流的方式。Java用于操作流的对象都在IO包中。
    输入流和输出流相对于内存设备而言。

    将外设中的数据读取到内存中:输入。
    将内存的数写入到外设中:输出。

    流按操作数据分为两种:字节流与字符流。

    字符流的由来:
    其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。再对这个文字进行操作。简单说:字节流+编码表。

 IO流常用基类-字符流

    字节流的抽象基类:InputStream,OutputStream。

    字符流的抽象基类:Reader,Writer。

    P.S.
    由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
    如:InputStream的子类FileInputStream。
    如:Reader的子类FileReader。

    需求:将一些文字存储到硬盘一个文件中。
    记住:如果要操作文字数据,建议优先考虑字符流。
    而且要将数据从内存写到硬盘上,要使用字符流中的输出流:Writer。
    硬盘的数据基本体现是文件,希望找到一个可以操作文件的Writer:FileWriter。

  P.S.

    1. close方法只能用一次。
    2. 流关闭以后不能,不能再调用write方法,否则会报如下异常错误:

 

IO流的异常处理方式:为防止代码异常导致流无法关闭,因此在finally中对流进行关闭。

需求:读取一个文文件,将读取到的字符打印到控制台。(使用FileReader)
第一种读取方式:使用read()方法读取文本文件数据。

 第二种读取方式:使用read(char[])方法读取文本文件数据。

字符流的缓冲区
    缓冲区的出现提高了对数据的读写效率。

    对应类:
   BufferedWriter
   BufferedReader

    P.S.
    缓冲区要结合流才可以使用。

    作用:在流的基础上对流的功能进行了增强。

字符流缓冲区:

    写入换行使用BufferedWriter类中的newLine()方法。
    读取一行数据使用BufferedReader类中的readLine()方法。

    bufr.read():这个read方法是从缓冲区中读取字符数据,所以覆盖了父类中的read方法。
    bufr.readLine():另外开辟了一个缓冲区,存储的是原缓冲区一行的数据,不包含换行符。

    原理:使用了读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前的缓冲数据变成字符串返回。

 LineNumberReader
    跟踪行号的缓冲字符输入流。此类定义了方法setLineNumber(int) 和getLineNumber(),它们可分别用于设置和获取当前行号。


装饰设计模式


    对原有类进行了功能的改变,增强。

 装饰和继承都能实现一样的特点:进行功能的扩展增强。有什么区别呢?

    首先有一个继承体系:
    Writer
         |--TextWriter:用于操作文本
         |--MediaWriter:用于操作媒体
    如果想要对操作的动作进行效率的提高,按照面向对象,可以通过继承的方式对具体的对象进行功能的扩展,那么就需要加入缓冲技术。
    Writer
          |--TextWriter:用于操作文本
              |--BufferTextWriter:加入了缓冲技术的操作文本的对象
         |--MediaWriter:用于操作媒体
              |--BufferMediaWriter:加入了缓冲技术的操作媒体的对象
    以上方式并不理想,如果这个体系需要再进行功能扩展,又多了更多流对象。
    这样就会发现只为提高功能,导致继承体系越来越臃肿,不够灵活。

 

重新思考问题:


    既然加入的都是同一种技术--缓冲。
    前一种是让缓冲和自己的流对象相结合。
    可不可以将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。

 Writer
        |--TextWriter:用于操作文本
        |--MediaWriter:用于操作媒体
        |--BufferedWriter:用于提高效率

    可见:装饰比继承灵活。
    特点:装饰类和被装饰类都必须所属同一个接口或者父类。

缓冲的原理:
    其实就是从源中获取一批数据到缓冲区中,再从缓冲区中不断地取出一个一个数据。
    在此次取完后,再从源中继续取一批数据进缓冲区,当源中的数据取完时,用-1作为结束标记。

IO流常用基类-字节流


    基本操作与字符流类相同。但它不仅可以操作字符,还可以操作其他媒体文件。

 P.S.
    FileOutputStream、FileInputStream的flush方法内容为空,没有任何实现,调用没有意义。

    字节流的缓冲区:同样是提高了字节流的读写效率。

 

    键盘本身就是一个标准的输入设备。对于java而言,对于这种输入设备都有对应的对象。

 P.S.
    1、获取键盘录入数据,然后将数据流向显示器,那么显示器就是目的地。
    通过System类的setIn,setOut方法可以对默认设备进行改变。
    System.setIn(new FileInputStream(“1.txt”));//将源改成文件1.txt。
    System.setOut(new PrintStream(“2.txt”));//将目的改成文件2.txt
    因为是字节流处理的是文本数据,可以转换成字符流,操作更方便。
    BfferedReader bufr =
               newBufferedReader(new InputStreamReader(System.in));
    BufferedWriter bufw =
               newBufferedWriter(new OutputStreamWriter(System.out));
    2、默认的输入和输出系统不需要关,它会随着系统的结束而消失。

 

转换流


    转换流的由来:
    字符流与字节流之间的桥梁
    方便了字符流与字节流之间的操作

    转换流的应用:
    字节流中的数据都是字符时,转成字符流操作更高效。

    转换流:
    InputStreamReader:字节到字符的桥梁,解码。
    OutputStreamWriter:字符到字节的桥梁,编码。

    InputStreamReader是字节流通向字符流的桥梁。

 P.S.
    使用字节流读取一个中文字符需要读取两次,因为一个中文字符由两个字节组成,而使用字符流只需读取一次。
    System.out的类型是PrintStream,属于OutputStream类别。

    OutputStreamReader是字符流通向字节流的桥梁。

流的操作规律

    之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。
    想要知道对象的开发时用到哪些对象,只要通过四个明确即可。

    1、明确源和目的
         源:InputStream Reader
         目的:OutputStream Writer

    2、明确数据是否是纯文本数据
         源:是纯文本:Reader
                否:InputStream
         目的:是纯文本:Writer
                否:OutputStream 
         到这里,就可以明确需求中具体要使用哪个体系。

    3、明确具体的设备
         源设备:
         硬盘:File
         键盘:System.in
         内存:数组
         网络:Socket流
         目的设备:
         硬盘:File
         控制台:System.out
         内存:数组
         网络:Socket流

    4、是否需要其他额外功能
         是否需要高效(缓冲区):
         是,就加上buffer

 任何Java识别的字符数据使用的都是Unicode码表,但是FileWriter写入本地文件使用的是本地编码,也就是GBK码表。
    而OutputStreamWriter可使用指定的编码将要写入流中的字符编码成字节。

P.S.
    UTF-8编码,一个中文三个字节。

 什么时候使用转换流呢?
    1、源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁,提高对文本操作的便捷。
    2、一旦操作文本涉及到具体的指定编码表时,必须使用转换流。

 File类


    File类用来将文件或者文件夹封装成对象,方便对文件与文件夹的属性信息进行操作。
    File对象可以作为参数传递给流的构造函数。

    P.S.
    流只能操作数据,不能操作文件。

 P.S
    File.separator是与系统有关的默认名称分隔符。在UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\\'。 

    File对象的常用方法:

    1、获取
         获取文件名称
         获取文件路径
         获取文件大小
         获取文件修改时间

2、创建和删除

   3、判断

  4、重命名

 5、系统根目录和容量获取

P.S.
    由于搜索后缀为“.java”便直接将“.java”写死到代码中,不便于修改。

 

递归  

    函数自身直接或者间接的调用到了自身。
    一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关。这时可以用递归来解决问题。

    P.S.
    1、递归一定明确条件,否则容易栈溢出。
    2、注意一下递归的次数。

 

Properties集合

    Map
          |--Hashtable
               |--Properties

    特点:
    1. 该集合中的键和值都是字符串类型。
    2. 集合中的数据可以保存到流中,或者从流中获取。

    3. 通常该集合用于操作以键值对形式存在的配置文件。

    Properties集合的存和取。

 

IO包中的其他类

    打印流

    PrintWriter与PrintStream:可以直接操作输入流和文件。

    PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
    与其他输出流不同,PrintStream永远不会抛出IOException。
    PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。
    在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类。

    PrintStream:
    1. 提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式
    2. 它不抛IOException

    构造函数,接收三种类型的值:
    1. 字符串路径
    2. File对象
    3. 字节输出流

 PrintWriter:字符打印流

    构造函数参数:
    1. 字符串路径
    2. File对象
    3. 字节输出流
    4. 字符输出流

序列流
    SequenceInputStream:对多个流进行合并。

使用ArrayList比Vector效率更高。

操作对象
    ObjectInputStream与ObjectOutputStream

    P.S.
    被操作的对象需要实现Serializable。

    类通过实现java.io.Serializable接口以启用序列化功能,Serializable只是一个标记接口。

RandomAccessFile

    随机访问文件,自身具备读写的方法。
    通过skipBytes(intx),seek(int x)等方法来达到随机访问。

    特点:
    1. 该对象即能读,又能写。
    2. 该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素。
    3. 可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置。
    4. 其实该对象就是将字节输入流和输出流进行了封装。
    5. 该对象的源或者目的只能是文件。通过构造函数就可以看出。

    P.S.
    RandomAccessFile不是io体系中的子类。

管道流
    PipedInputStream和PipedOutputStream:输入输出可以直接进行连接,通过结合线程使用。

操作基本数据类型
    DataInputStream与DataOutputStream

 操作字节数组
    ByteArrayInputStream与ByteArrayOutputStream

    P.S.
    关闭字节数组输出输出流无效,因为它们没有调用底层资源,所有的操作都是在内存中完成的。

编码表


    编码表的由来
    计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。
    就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表。

    常见的编码表
    ASCII:美国标准信息交换码,用一个字节的7位可以表示。
    ISO8859-1:拉丁码表。欧洲码表,用一个字节的8位表示。
    GB2312:中国的中文编码表。
    GBK:中国的中文编码表升级,融合了更多的中文文字符号。
    Unicode:国际标准码,融合了多种文字。
    所有文字都用两个字节来表示,Java语言使用的就是unicode
    UTF-8:最多用三个字节来表示一个字符。

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值