Java基础——IO

一、Java IO的体系结构

Java I/O主要包括如下几个层次,包含三个部分:

  1.流式部分――IO的主体部分,字节流和字符流

  2.非流式部分――主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类;

  3.其他类--文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类

https://www.cnblogs.com/ylspace/p/8128112.html

二、IO流

1. 流的概念和作用

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在设备间传输称之为流

流的本质数据传输,根据数据传输的特性将流区分为各种类,方便更直观的进行数据操作。

2. 流的分类

(1)根据处理数据类型的不同分为:字符流和字节流

        1)  字节流:数据流中最小的数据单元是字节

        2)  字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

             字符流的由来:Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。

(2) 根据数据流向不同分为:输入流和输出流

    1) 输入流

     程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道

     2) 输出流

   程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

     3)特性

  相对于程序来说,输出流是往存储介质或数据通道写入数据,而输入流是从存储介质或数据通道中读取数据,一般来说关于流的特性有下面几点:

1、先进先出,最先写入输出流的数据最先被输入流读取到。

2、顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile可以从文件的任意位置进行存取(输入输出)操作

3、只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

(3) 按数据来源(去向)分类

        1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter

        2、byte[]:ByteArrayInputStream, ByteArrayOutputStream

        3、Char[]: CharArrayReader,CharArrayWriter

        4、String:StringBufferInputStream, StringReader, StringWriter

        5、网络数据流:InputStream,OutputStream, Reader, Writer

3. 字节流

https://zhuanlan.zhihu.com/p/25418336

(1)输入字节流 InputStream

        从IO中输入字节流的继承图中可以看出。

        1)InputStream是所有数据字节流的父类,它是一个抽象类。

        2)ByteArrayInputStream、StringBufferInputStream、FileInputStream是三种基本的介质流,它们分别从Byte数组、StringBuffer、和本地文件中读取数据,PipedInputStream是从与其他线程共用的管道中读取数据。

        3)ObjectInputStream和所有FileInputStream 的子类都是装饰流(装饰器模式的主角)。

        InputStream中的三个基本的读方法

        abstract int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。

        intread(byte[] b) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。

        intread(byte[]?b, int off, int len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。

        流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。

        其它方法

         long skip(long?n):在输入流中跳过n个字节,并返回实际跳过的字节数。

      int available() :返回在不发生阻塞的情况下,可读取的字节数。

      void close() :关闭输入流,释放和这个流相关的系统资源。

      voidmark(int?readlimit) :在输入流的当前位置放置一个标记,如果读取的字节数多于readlimit设置的值,则流忽略这个标记。

      void reset() :返回到上一个标记。

      booleanmarkSupported() :测试当前流是否支持mark和reset方法。如果支持,返回true,否则返回false。

  (2)输出字节流 OutputStream

        从IO中输入字节流的继承图中可以看出。

        1)OutputStream是所有输出字节流的父类,它是一个抽象类。

        2)ByteArrayOutputStream、FIleOutputStream是两种基本的介质,它们分别向Byte 数组,和本地文件中写入数据。PipedOutputStream是从与其他线程共用的管道中写入数据。

        3)ObjectOutputStream和所有FileOutputStream的子类都是装饰流。

        outputStream中的三个基本的写方法

        abstract void write(int?b):往输出流中写入一个字节。

        void write(byte[]?b) :往输出流中写入数组b中的所有字节。

        void write(byte[]?b, int?off, int?len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。

        其它方法

        void flush() :刷新输出流,强制缓冲区中的输出字节被写出。

        void close() :关闭输出流,释放和这个流相关的系统资源。

4. 字符流

https://zhuanlan.zhihu.com/p/25418336

(1)字符输入流Reader

        在上面的继承关系图中可以看出:

        1、Reader是所有的输入字符流的父类,它是一个抽象类。

        2、CharReader、StringReader 是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedInputReader 是从与其他线程共用的管道中读取数据。

        3、BuffereReader 很明显的是一个装饰器,它和其子类复制装饰其他Reader对象。

        4、FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,回增加一个行号。

        5、InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。

    主要方法:

         (1) public int read() throws IOException; //读取一个字符,返回值为读取的字符 

        (2) public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/

        (3) public abstract int read(char cbuf[],int off,int len) throws IOException;

/*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/

(2)字符输出流Writer

        在上面的关系图中可以看出:

        1、Writer 是所有输出字符流的父类,它是一个抽象类。

        2、CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedInputWriter 是从与其他线程共用的管道中读取数据。

        3、BuffereWriter 很明显是一个装饰器,他和其子类复制装饰其他Reader对象。

        4、FilterWriter 和PrintStream 及其类似,功能和使用也非常相似。

        5、OutputStreamWriter 是OutputStream 到Writer 转换到桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一下SourceCode)。功能和使用OutputStream极其类似。

    主要方法:

        (1)  public void write(int c) throws IOException; //将整型值c的低16位写入输出流

        (2)  public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流

        (3)  public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流

        (4)  public void write(String str) throws IOException; //将字符串str中的字符写入输出流

        (5)  public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流

5、字符流与字节流的转换

转换流的特点:

1、其是字符流和字节流之间的桥梁。

2、可对读取到的字节数据经过指定编码转换成字符。

3、可对读取到的字符数据经过指定编码转换成字节。

何时使用转换流?

1、当字节和字符之间有转换动作时。

2、流操作的数据需要编码或解码时。

具体的对象体现:

1、InputStreamReader:字节到字符的桥梁。

2、OutputStreamWriter:字符到字节的桥梁。

这两个流对象时字符体系中的成员,它们有转换的作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。

三、非流式

1、File类

File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。File类保存文件或目录的各种数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名、判断文件是否存在、获取当前目录中的文件列表、创建、删除文件和目录等方法。

2、RandomAccessFile类

该对象不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组),通过内部的指针来操作字符数组中的数据。该对象特点:

1、该对象只能操作文件,所以构造函数接受两种数据类型的参数:

· 字符串文件路径

· File对象

2、该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r , rw)。

注意:该对象在实例化时,如果要操作的文件不存在,会自动创建;如果文件存在,写数据未指定位置,会从头开始写,即覆盖原有的内容。可以用于多线程下载或多个线程同时写数据到文件。

参考文献:

https://zhuanlan.zhihu.com/p/25418336

https://www.cnblogs.com/ylspace/p/8128112.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 6.IO流 6.1 File 系统中我们一眼看到的就是文件或者文件夹本质是一个路径(字符串);用字符串来表示这个路...
    ADMAS阅读 376评论 0 0
  • I/O类库中使用“流”这个抽象概念。Java对设备中数据的操作是通过流的方式。表示任何有能力产出数据的数据源对象,...
    千淘萬漉阅读 7,304评论 0 2
  • 什么是IO流?  IO是指应用程序对设备数据的输入输出操作。流的本质是数据传输。例如:键盘是输入设备,而显示器则是...
    小任务大梦想阅读 780评论 0 0
  • 1. 流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中,管道是一条不间断的字节...
    JackChen1024阅读 817评论 0 10
  • Java I/O流 Java的IO通过Java.io包下的类和接口来支持,在Java.io包下主要输入、输出两种I...
    So_ProbuING阅读 425评论 0 4