一、流的概念和作用

流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。

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

作用:为数据源和目的地建立一个输送通道。

从传输的内容的不同,总体上可以分为两大类,即字节流和字符流。

二、IO的分类

字节流

1、输入流

这里又区分为节点流和处理流,由于处理流都是装饰器流,所以都会迭代在节点流之上工作。

2、输出流

输出流当然与输入流类似,节点流可以单独使用,但是处理流需要迭代节点流来使用。

字符流

我们都知道计算机其实只能存储0和1,或者说字节,这里之所以还有个字符流,只是为了方便使用,底层与终端真正交互肯定还是用的字节流。

1、输入流

2、输出流

一般建议使用处理流包装之后的节点流来处理数据,比较提供了更多的功能和灵活性。

字符流的由来

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

字符流和字节流的使用范围

字节流一般用来处理图像,视频,以及PPT,Word类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,字节流可以用来处理纯文本文件,但是字符流不能用于处理图像视频等非文本类型的文件。

字节流和字符流的区别

子节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。

读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。

装饰者模式

Java的IO模型设计非常优秀,它使用Decorator(装饰者)模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。

例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

三、IO流的特性

  • 先进先出,最先写入输出流的数据最先被输入流读取到。
  • 顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile可以从文件的任意位置进行存取(输入输出)操作)。
  • 只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

四、IO流常用到的五类一接口

在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable。

主要类如下:

  • File(文件特征与管理):File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。
  • InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
  • OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
  • Reader(文件格式操作):抽象类,基于字符的输入操作。
  • Writer(文件格式操作):抽象类,基于字符的输出操作。
  • RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。

五、Scanner类

Java 5添加了java.util.Scanner类,这是一个用于扫描输入文本的新的实用程序。它是以前的StringTokenizer和Matcher类之间的某种结合。由于任何数据都必须通过同一模式的捕获组检索或通过使用一个索引来检索文本的各个部分。于是可以结合使用正则表达式和从输入流中检索特定类型数据项的方法。这样,除了能使用正则表达式之外,Scanner类还可以任意地对字符串和基本类型(如int和double)的数据进行分析。借助于Scanner,可以针对任何要处理的文本内容编写自定义的语法分析器。

import java.io.*;
public class ScannerDemo {public static void main(String args[]) {Scanner scan = new Scanner(System.in);    // 从键盘接收数据int i = 0;float f = 0.0f;System.out.print("输入整数:");if (scan.hasNextInt()) {    // 判断输入的是否是整数i = scan.nextInt();    // 接收整数System.out.println("整数数据:" + i);} else {System.out.println("输入的不是整数!");}System.out.print("输入小数:");if (scan.hasNextFloat()) {    // 判断输入的是否是小数f = scan.nextFloat();    // 接收小数System.out.println("小数数据:" + f);} else {System.out.println("输入的不是小数!");}Date date = null;String str = null;System.out.print("输入日期(yyyy-MM-dd):");if (scan.hasNext("^\\d{4}-\\d{2}-\\d{2}$")) {    // 判断str = scan.next("^\\d{4}-\\d{2}-\\d{2}$");    // 接收try {date = new SimpleDateFormat("yyyy-MM-dd").parse(str);} catch (Exception e) {}} else {System.out.println("输入的日期格式错误!");}System.out.println(date);}
}

六、系统标准IO

System表示系统类,它有3个与 Java IO 有关的常量。

  • System.out——系统标准输出
  • System.in——系统标准输入
  • System.err——错误信息输出

1、System.out

System.out 是 PrintStream 的对象,在 PrintStream 中定义了一些了的 print() 和 println() 方法。

所以,常见的 System.out.print() 或 System.out.println() 语句调用的实际上是 PrintStream 类的方法。

import java.io.OutputStream;
import java.io.IOException;public class SystemDemo01 {public static void main(String args[]) {OutputStream out = System.out; // 此时的输出流是向屏幕上输出try {out.write("hello world!!!".getBytes()); // 向屏幕上输出} catch (IOException e) {e.printStackTrace(); // 打印异常}try {out.close(); // 关闭输出流} catch (IOException e) {e.printStackTrace();}}
};

2、System.in

System.in 是 InputStream 类型的对象,可以利用它完成从键盘读取数据的功能。

import java.io.InputStream;public class SystemInDemo {public static void main(String args[]) throws Exception {InputStream input = System.in;byte b[] = new byte[5]; // 开辟空间,接收数据System.out.print("请输入内容:");int len = input.read(b); // 接收数据System.out.println("输入的内容为:" + new String(b, 0, len));input.close(); // 关闭输入流}
};

七、序列化

将保存在内存中的对象数据转化为二进制数据流进行传输,任何对象都可以序列化。

实现方法:实现java.io.Serializable接口。

作用:把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流。对于这种通用的操作,我们为什么不使用统一的格式呢?没错,这里就出现了java的序列化的概念。在Java的OutputStream类下面的子类ObjectOutputStream类就有对应的writeObject(Object object) ,其中要求对应的object实现了java的序列化的接口。

transient关键字(一个类某些属性不需要序列化)

如果需要将某些内容排除在序列化之外,可以使用transient关键字来定义。

private transient string title;

此时title属性无法被序列化,

八、IO流方法介绍

InputStream

字节输入流基类,抽象类是表示字节输入流的所有类的超类。

常用方法:

// 从输入流中读取数据的下一个字节
abstract int read()
// 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b中
int read(byte[] b)
// 将输入流中最多 len 个数据字节读入 byte 数组
int read(byte[] b, int off, int len)
// 跳过和丢弃此输入流中数据的 n个字节
long skip(long n)
// 关闭此输入流并释放与该流关联的所有系统资源
void close()

OutputStream

字节输出流基类,抽象类是表示输出字节流的所有类的超类。

常用方法:

// 将 b.length 个字节从指定的 byte 数组写入此输出流
void write(byte[] b)
// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
void write(byte[] b, int off, int len)
// 将指定的字节写入此输出流
abstract void write(int b)
// 关闭此输出流并释放与此流有关的所有系统资源
void close()
// 刷新此输出流并强制写出所有缓冲的输出字节
void flush()

FileInputStream

字节文件输入流,从文件系统中的某个文件中获得输入字节,用于读取诸如图像数据之类的原始字节流。

构造方法:

// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定
FileInputStream(File file)
// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径name指定
FileInputStream(String name)

常用方法:覆盖和重写了父类的常用方法。

FileOutputStream

字节文件输出流是用于将数据写入到File,从程序中写入到其他位置。

构造方法:

// 创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutputStream(File file)
// 创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutputStream(File file, boolean append)
// 创建一个向具有指定名称的文件中写入数据的输出文件流
FileOutputStream(String name)
// 创建一个向具有指定name的文件中写入数据的输出文件流
FileOutputStream(String name, boolean append)

常用方法:覆盖和重写了父类的常用方法。

BufferedInputStream

字节缓冲输入流,提高了读取效率。

构造方法:

// 创建一个 BufferedInputStream并保存其参数,即输入流in,以便将来使用。
BufferedInputStream(InputStream in)
// 创建具有指定缓冲区大小的 BufferedInputStream并保存其参数,即输入流in以便将来使用
BufferedInputStream(InputStream in, int size)

BufferedOutputStream

字节缓冲输出流,提高了写出效率。

构造方法:

// 创建一个新的缓冲输出流,以将数据写入指定的底层输出流
BufferedOutputStream(OutputStream out)
// 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
BufferedOutputStream(OutputStream out, int size)

常用方法:

// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流
void write(byte[] b, int off, int len)
// 将指定的字节写入此缓冲的输出流
void write(int b)
// 刷新此缓冲的输出流
void flush()

Reader

读取字符流的抽象类。

常用方法:

// 读取单个字符
int read()
// 将字符读入数组
int read(char[] cbuf)
// 将字符读入数组的某一部分
abstract int read(char[] cbuf, int off, int len)
// 跳过字符
long skip(long n)
// 关闭该流并释放与之关联的所有资源
abstract void close()

Writer

写入字符流的抽象类。

常用方法:

// 写入字符数组
void write(char[] cbuf)
// 写入字符数组的某一部分
abstract void write(char[] cbuf, int off, int len)
// 写入单个字符
void write(int c)
// 写入字符串
void write(String str)
// 写入字符串的某一部分
void write(String str, int off, int len)
// 将指定字符添加到此 writer
Writer append(char c)
// 将指定字符序列添加到此 writer
Writer append(CharSequence csq)
// 将指定字符序列的子序列添加到此 writer.Appendable
Writer append(CharSequence csq, int start, int end)
// 关闭此流,但要先刷新它
abstract void close()
abstract void flush()

InputStreamReader

字节流转字符流,它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

构造方法:

// 创建一个使用默认字符集的 InputStreamReader
InputStreamReader(InputStream in)
// 创建使用给定字符集的 InputStreamReader
InputStreamReader(InputStream in, Charset cs)
// 创建使用给定字符集解码器的 InputStreamReader
InputStreamReader(InputStream in, CharsetDecoder dec)
// 创建使用指定字符集的 InputStreamReader
InputStreamReader(InputStream in, String charsetName)

特有方法:

//返回此流使用的字符编码的名称
String getEncoding() 

OutputStreamWriter

字节流转字符流。

构造方法:

// 创建使用默认字符编码的 OutputStreamWriter
OutputStreamWriter(OutputStream out)
// 创建使用给定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs)
// 创建使用给定字符集编码器的 OutputStreamWriter
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
// 创建使用指定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, String charsetName)

特有方法:

//返回此流使用的字符编码的名称
String getEncoding() 

BufferedReader

字符缓冲流,从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

构造方法:

// 创建一个使用默认大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader in)
// 创建一个使用指定大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader in, int sz)

特有方法:

// 读取一个文本行
String readLine()

BufferedWriter

字符缓冲流,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

构造方法:

// 创建一个使用默认大小输出缓冲区的缓冲字符输出流
BufferedWriter(Writer out)
// 创建一个使用给定大小输出缓冲区的新缓冲字符输出流
BufferedWriter(Writer out, int sz)

特有方法:

// 写入一个行分隔符
void newLine() 

FileReader、FileWriter

FileReader:InputStreamReader类的直接子类,用来读取字符文件的便捷类,使用默认字符编码。
FileWriter:OutputStreamWriter类的直接子类,用来写入字符文件的便捷类,使用默认字符编码。

九、参考

https://www.cnblogs.com/029zz010buct/p/12182101.html

https://www.cnblogs.com/hujunjie123/articles/12874315.html

Java IO(BIO)相关推荐

  1. 【转】深入分析JAVA IO(BIO、NIO、AIO)

    IO的基本常识 1.同步 用户进程触发IO操作并等待或者轮询的去查看IO操作是否完成 2.异步 用户触发IO操作以后,可以干别的事,IO操作完成以后再通知当前线程继续处理 3.阻塞 当一个线程调用 r ...

  2. IO(BIO),NIO,AIO的深度解析和区别

    IO(BIO),NIO,AIO的深度解析和区别    IO    概念: Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

  3. Java基础(二十七)Java IO(4)字符流(Character Stream)

    字符流用于处理字符数据的读取和写入,它以字符为单位. 一.Reader类与Writer类 1.Reader类是所有字符输入流的父类,它定义了操作字符输入流的各种方法. 2.Writer类是所有字符输出 ...

  4. Java IO(一)

    [例1]创建一个新文件 import java.io.*; class hello{public static void main(String[] args) {File f=new File(&q ...

  5. Java IO(五)——字符流进阶及BufferedWriter、BufferedReader

    一.字符流和字节流的区别 拿一下上一篇文章的例子: 复制代码 复制代码 1 package com.demo.io; 2 3 import java.io.File; 4 import java.io ...

  6. Java IO(二)Java IO简介及FileInput/FileOutputStream

    JAVA IO Java IO可以让我们用标准的读写操作来完成对不同设备的读写数据工作. Java将IO按照方向划分为输入与输出,参照点是我们写的程序. 输入:用来读取数据的,是从外界到程序的方向,用 ...

  7. Java IO(输入输出)

    1. System.out.System.in System 内部: public final static InputStream in = null; public final static Pr ...

  8. java IO(二)—— 字符输入输出流

    javo. io. Reader:字符输入流 是字符输入流的最顶层的父类,定义了-些共性的成员方法,是一个抽象类 共性的成员方法: int read() 读取单个字符并返回. int read(cha ...

  9. Java IO(二)——RandomAccessFile

    一.RandomAccessFile RandomAccessFile类可以说是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法.RandomAccessFile类支持"随 ...

最新文章

  1. 10个工程师,9个不合格!
  2. hdu 1022 Train Problem I(栈)
  3. python进程和线程中的两个锁
  4. 随笔-546 评论-829 文章-21 2015年第15本:天才在左,疯子在右
  5. Springboot 集成 Swagger
  6. 在asp中使用js的encodeURIComponent方法
  7. Linux中yum不能用的原因
  8. VB.net WinForm如何写一个分线程进度条
  9. beetl模板使用场景_Beetl使用指南
  10. 415错误及解决方法
  11. 5G承载网,从入门到……放弃?
  12. mysql too long_mysql中data too long for column错误的一种解决办法
  13. 批量识别PDF/OFD/PNG/JPG电子发票到EXCEL
  14. CGAN(conditional GANs)
  15. [ENVI]练习过程中遇到的一些问题
  16. matlab实现kuan滤波,用Matlab设计一个0.5-20HZ的带通滤波器! - 程序语言 - 小木虫 - 学术 科研 互动社区...
  17. python_安居客区域房源均价工具(matplotlib)
  18. Java内存溢出与栈溢出
  19. [转]mysql的sql优化工具
  20. 排班所需表结构--排班(二)

热门文章

  1. Codeforces Round #809 (Div. 2)
  2. Android OpenCV(五十八):SURF特征点检测
  3. Coursera | Andrew Ng (02-week-3-3.3)—超参数训练的实践:Pandas VS Caviar
  4. 1128d_日式迷宫探索DRPG《灵魂潮汐》预计11月28日开测
  5. Cyan Worlds开源《Myst Online: Uru Live》
  6. 翻译英文文献----利用MAP-MRF模型改进三维网格分割算法
  7. 【python 走进NLP】英文敏感词过滤算法改进版本
  8. 全国计算机等级考试一级上机WORD题,全国计算机等级考试一级上机WORD题库
  9. CTF——一次源码审计【O泡易支付】
  10. 每个JavaScript工程师都应懂的33个概念