详解Java 流(Stream)、文件(File)和IO(一)

来源:互联网 发布:mac可以用excel吗 编辑:程序博客网 时间:2024/05/09 03:45

一、关于Java I/O

Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。
Java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。
一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。

如前所述,一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
下图是一个描述输入流和输出流的类层次图。
点击查看高清图
Java IO类图

二、详解Java 流(Stream)

1、认识流的概念

首先需要明白的是:流是干什么的?(为了永久性的保存数据)
直观地讲,流就像水一样,不存在大小问题,也避免了完整性问题。非流的数据传输,比如你下载一张图片,需要整幅图片下载完之后才能使用,而流则不同,就像水,你取一杯也可以用,取一桶也可以用。所以说,流是一种数据传输的模式。
Java中对文件的操作是以流的方式进行的。流是Java内存中的一组有序数据序列。Java将数据从源(文件、内存、键盘、网络)读入到内存中,形成了流,然后将这些流还可以写到另外的目的地(文件、内存、控制台、网络),之所以称为流,是因为这个数据序列在不同时刻所操作的是源的不同部分。流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
流的好处是接收方可以提前处理,缩短等待时间,提高速度。比如你上youku看视频,并不是整个视频下载好了才播放的,而是下一点播一点。

2、流的分类

根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流

1)字符流和字节流

在JAVA语言中,byte类型是8位的,char类型是16位的:1byte = 8bits、1char = 16bits。
Java字符流是处理字符(Char)对象用的,字节流是处理字节(Byte)对象用的。处理的目标对象不同,处理方法也就不一样。
字符流处理的基本单位是字符(Java中的字符是16位的),输入流以Reader为基础,输出流以Writer为基础;
字节流的基本单位是字节(Java中的字节是8位的),输入流以 InputStream为基础,输出流以 OutputStream为基础;
字符流在输入时可以按字符读取,也可以按行读取,会去掉回车换行,常用于读取字符数据;
而字节流按字节读取,不作任何处理,常用于读取二进制数据。
Java中的字符在内部都是使用Unicode进行表示的,因此,要正确读取字符数据,需要知道字符的编码字符集,字符流提供编码字符集的指定,如果不指定使用系统默认的方式对字符数据进行编码转换,这个编码字符集不正确,会造成读进来的地字符出现乱码。
字节流虽然是读取二进制数据用的,但也可以读取字符文件,按字节进行处理,读进来之后可以根据编码字符集进行转换,也可以变成字符串。
字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的
但实际中很多的数据是文本,所以提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化,实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。

2)输入流和输出流

输入流和输出流,差别在于出和入,输入是程序得到外部数据,输出是程序向外部传输数据,比如你从一个文本文件中读出内容,这个操作就对应一个输出流,是程序对外部输出数据,而你把一段文字写入一耳光文本文件,这个操作就对应一个输入流,把外部的数据输入到程序中。
输入流和输出流二者没有必然的联系,都是流,差别是方向不同,也就是说,程序可以只有输入流而没有输出流,或者只有输出流而没有输入流。

3、流的实例(对控制台数据的读写操作)

1)输入

读取控制台输入并实时响应控制台显示,Java 的控制台输入由 System.in 完成。为了获得一个绑定到控制台的字符流,你可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流。

从 BufferedReader 对象读取一个字符要使用 read() 方法,每次调用 read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。
下面的程序示范了用 read() 方法从控制台不断读取字符直到用户输入 “q”。

// 使用 BufferedReader 在控制台读取字符import java.io.*;public class BuffRead {  public static void main(String args[]) throws IOException  {    char c;    // 使用 System.in 创建 BufferedReader     BufferedReader br = new BufferedReader(new                        InputStreamReader(System.in));    System.out.println("输入字符, 按下 'q' 键退出。");    // 读取字符    do {       c = (char) br.read();//read()读取字符,reallines()读取字符串       System.out.println(c);    } while(c != 'q');  }}

2)输出

在此前已经介绍过,控制台的输出由 print( ) 和 println() 完成。这些方法都由类 PrintStream 定义,System.out 是该类对象的一个引用。
PrintStream 继承了 OutputStream类,并且实现了方法 write()。这样,write() 也可以用来往控制台写操作。
下面的例子用 write() 把字符 “A” 和紧跟着的换行符输出到屏幕:

import java.io.*;// 演示 System.out.write().public class WriteDemo {   public static void main(String args[]) {      int b;       b = 'A';      System.out.write(b);      System.out.write('\n');   }}//运行结果:A//write() 方法不经常使用,因为 print() 和 println() 方法用起来更为方便。



未完待续