黑马程序员-Java I/O流(一)-IO流概述、字符流、字节流、流操作规律
2015-11-05 04:24
821 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
1. 概述
流:可以理解数据的流动,就是一个数据流。Java中与IO相关的类有很多,都集中在java.io中,都是以流的形式操作的,它的本质是传输数据。
IO流分类:
(1)根据数据类型的不同可以分为字节流和字符流。
(2)根据流向的不同可以分为输入流和输出流。
Java 中所有IO流的关系如下图:
主要的操作流程如下:
1使用File类打开一个文件
2 通过字节流或字符流的子类,指定输出的位置
3 进行读/写操作
4 关闭输入/输出
2. 字符流 Reader Writer
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream 中写入信息。
Reader/Writer 为abstact类
Reader:以Unicode字符为导向的流,以Unicode字符为单位从流中读取,是一个抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。
Reader的常用读取操作:
1.int read() 读取单个字符。
2.int read(char[] cbuf) 将字符读入数组。
3.abstract int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
在使用Reader进行数据流的读入操作时是不会直接创建Reader对象的,一般都是使用其子类,如FileReader,示例代码如下:
读取的第二种形式是添加一个自定义缓冲区,这种方法比较高效。
上面代码需要注意是,不管是流的创建,打开,写入,读取,刷新,关闭等操作,一般都会抛出IOException,因为对磁盘进行操作(一般都是)都有可能产生错误,如磁盘满了,文件被占用等等,所以必须对其进行捕获,并处理。流的关闭一般放在try中的finally中,原因是为防止出错后无法及时释放资源。
Writer : 以Unicode字符为导向的流,以Unicode字符为单位往流中写入,是一个抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。
Writer的常用写入操作:
1.abstract void flush() 刷新该流的缓冲。
2.void write(char[] cbuf) 写入字符数组。
3.void write(int c) 写入单个字符。
4.void write(String str) 写入字符串。
5.void write(String str, int off, int len) 写入字符串的某一部分。
在使用Writer进行数据流的读入操作时是不会直接创建Writer对象的,一般都是使用其子类,如FileWriter,示例代码如下:
需要注意的是:流的关闭一般放在try中的finally中,原因是为防止出错后无法及时释放资源。在进行数据的写入时,当执行完write方法后,数据可能不会立即被写入到目的地,这时可以使用flush功能进行立即完成写入功能,也可以在close时自定完成内容的写入。
字符缓冲流BufferedWriter和BufferedReader:
为了提程序效率,java设置了Writer和Reader对应的类:BufferedReader和BufferedWriter,下面是一个示例:
3. 字节流 InputStream OutputStream
字符流操作的是纯文本内容,而字节流则是所有二进制文件都可以操作,如图片,视频,当然文件文件也是可以的。与字符流中读出和写入的类型为char型相对应,字节流读出和写入的是byte类型。字节流的两个基本输入输出流为InputStream和OutputStream,其功能与字符流的功能类似。对于文件的操作的流是相应的FileInputStream和FileOutputStream,下面通过一个图片拷贝功能作为字节流的一个示例代码:
我们注意到字节流不能直接写入,需要转化成字节数组进行写入和输出。
字节缓冲流BufferedInputStream和BufferedOutputStream:
未加入缓冲机制时候,每次read()都会调用系统底层读取磁盘的操作,读取一个字节,非常耗时;而加入缓冲机制后,系统会一次将很多内容读取到内存,而调用read()时,只需要从内存中返回数据内容即可,大大减少了系统底层访问磁盘的次数,所以速度会加快很多。
读取转换流和写入转换流 InputStreamReader和OutputStreamWriter:
为了方便了字符流与字节流之间的操作,当我们读取键盘(System.in)数据时,便可以使用InputStreamReader,当我们将数据输出到控制台(System.out),便可以使用OutputStreamWriter,示例代码如下:
4. 流操作规律 :
(1)明确源和目的。
数据源:就是需要读取,可以使用两个体系:InputStream、Reader;
数据汇:就是需要写入,可以使用两个体系:OutputStream、Writer;
(2)操作的数据是否是纯文本数据?
如果是:数据源:Reader
数据汇:Writer
如果不是:数据源:InputStream
数据汇:OutputStream
(3)虽然确定了一个体系,但是该体系中有太多的对象,到底用哪个呢?
明确操作的数据设备。
数据源对应的设备:硬盘(File),内存(数组),键盘(System.in)
数据汇对应的设备:硬盘(File),内存(数组),控制台(System.out)。
(4)需要在基本操作上附加其他功能吗?比如缓冲。
如果需要就进行装饰。
1. 概述
流:可以理解数据的流动,就是一个数据流。Java中与IO相关的类有很多,都集中在java.io中,都是以流的形式操作的,它的本质是传输数据。
IO流分类:
(1)根据数据类型的不同可以分为字节流和字符流。
(2)根据流向的不同可以分为输入流和输出流。
Java 中所有IO流的关系如下图:
主要的操作流程如下:
1使用File类打开一个文件
2 通过字节流或字符流的子类,指定输出的位置
3 进行读/写操作
4 关闭输入/输出
2. 字符流 Reader Writer
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream 中写入信息。
Reader/Writer 为abstact类
Reader:以Unicode字符为导向的流,以Unicode字符为单位从流中读取,是一个抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。
Reader的常用读取操作:
1.int read() 读取单个字符。
2.int read(char[] cbuf) 将字符读入数组。
3.abstract int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
在使用Reader进行数据流的读入操作时是不会直接创建Reader对象的,一般都是使用其子类,如FileReader,示例代码如下:
import java.io.*; class FileReaderDemo { public static void main(String[] args) throws IOException { //创建可以读取文本文件的流对象,FileReader让创建好的流对象和指定的文件相关联。 //读取demo.txt数据,一次读一个字符,返回字符的十进制形式。 FileReader fr = new FileReader("demo.txt"); int ch = 0; while((ch = fr.read())!= -1) { //条件是没有读到结尾 System.out.println((char)ch); //调用读取流的read方法,读取一个字符。 } fr.close(); } }
读取的第二种形式是添加一个自定义缓冲区,这种方法比较高效。
import java.io.*; class FileReaderDemo { public static void main(String[] args) throws IOException { //读取demo.txt数据。 FileReader fr = new FileReader("demo.txt"); //设定一个字符数组为缓冲区,使用read(char[])方法,将读取到字符存入数组,字符数组的长度都是1024的整数倍。 char[] buf = new char[1024];//缓冲区 int len = 0; while(( len=fr.read(buf)) != -1) { System.out.println(new String(buf,0,len)); } fr.close(); } }
上面代码需要注意是,不管是流的创建,打开,写入,读取,刷新,关闭等操作,一般都会抛出IOException,因为对磁盘进行操作(一般都是)都有可能产生错误,如磁盘满了,文件被占用等等,所以必须对其进行捕获,并处理。流的关闭一般放在try中的finally中,原因是为防止出错后无法及时释放资源。
Writer : 以Unicode字符为导向的流,以Unicode字符为单位往流中写入,是一个抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。
Writer的常用写入操作:
1.abstract void flush() 刷新该流的缓冲。
2.void write(char[] cbuf) 写入字符数组。
3.void write(int c) 写入单个字符。
4.void write(String str) 写入字符串。
5.void write(String str, int off, int len) 写入字符串的某一部分。
在使用Writer进行数据流的读入操作时是不会直接创建Writer对象的,一般都是使用其子类,如FileWriter,示例代码如下:
import java.io.*; class FileDWriterdemo { public static void main(String[] args) { /* 创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。 而且该文件会被创建到指定目下, 其实该步骤就是在明确数据要存放的目的地。 */ FileWriter fw = null; try { fw = new FileWriter("demo.txt",true);//传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写。 fw.write("aaa");//调用write()方法,将字符串写入到流中。 } catch (IOException e ){ System.out.println(e.toString()+"...."); } finally{ if(fw!=null) try{ fw.close(); } catch (IOException e){ System.out.println("close:"+e.toString()); } } }
需要注意的是:流的关闭一般放在try中的finally中,原因是为防止出错后无法及时释放资源。在进行数据的写入时,当执行完write方法后,数据可能不会立即被写入到目的地,这时可以使用flush功能进行立即完成写入功能,也可以在close时自定完成内容的写入。
字符缓冲流BufferedWriter和BufferedReader:
为了提程序效率,java设置了Writer和Reader对应的类:BufferedReader和BufferedWriter,下面是一个示例:
import java.io.*; class BufferedDemo { public static void main(String[] args) { BufferedWriter bw = null; try { //创建一个写入流对象,并且用缓冲流对象指定该写入流 bw = new BufferedWriter(new FileWriter("file.txt")); bw.write("Test");//将"test"写入 bw.newLine();//写入换行标志 bw.flush(); } catch (IOException e) { // IO异常在这里处理 } finally { try { // 在finally中关闭流,并判断是否为null if(bw != null) { bw.close(); } } catch (IOException e) {} } } }
3. 字节流 InputStream OutputStream
字符流操作的是纯文本内容,而字节流则是所有二进制文件都可以操作,如图片,视频,当然文件文件也是可以的。与字符流中读出和写入的类型为char型相对应,字节流读出和写入的是byte类型。字节流的两个基本输入输出流为InputStream和OutputStream,其功能与字符流的功能类似。对于文件的操作的流是相应的FileInputStream和FileOutputStream,下面通过一个图片拷贝功能作为字节流的一个示例代码:
import java.io.*; class putStreamDemo { public static void main(String[] args) throws IOException { FileInputStream fin = new FileInputStream("pic1.png"); FileOutputStream fout = new FileOutputStream("pic2.png"); // 与Reader不同的是这里使用的是byte类型 byte[] buf = new byte[1024]; int n = 0; while((n=fin.read(buf)) != -1) { fout.write(buf, 0, n);//字节流写入 } // 关闭流 fin.close(); fout.close(); } }
我们注意到字节流不能直接写入,需要转化成字节数组进行写入和输出。
字节缓冲流BufferedInputStream和BufferedOutputStream:
import java.io.*; class Demo { public static void main(String[] args) throws IOException { BufferedInputStream bi = new BufferedInputStream(new FileInputStream("pic1.png")); BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("pic2.png")); int data = 0; while((data = bi.read()) != -1) { bo.write(data); } bi.close(); bo.close(); } }
未加入缓冲机制时候,每次read()都会调用系统底层读取磁盘的操作,读取一个字节,非常耗时;而加入缓冲机制后,系统会一次将很多内容读取到内存,而调用read()时,只需要从内存中返回数据内容即可,大大减少了系统底层访问磁盘的次数,所以速度会加快很多。
读取转换流和写入转换流 InputStreamReader和OutputStreamWriter:
为了方便了字符流与字节流之间的操作,当我们读取键盘(System.in)数据时,便可以使用InputStreamReader,当我们将数据输出到控制台(System.out),便可以使用OutputStreamWriter,示例代码如下:
import java.io.*; class Demo { public static void main(String[] args) throws IOException { // 键盘的最常见写法。 BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in)); // 使用字符输出方式到控制台 BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(System.out)); String line = null; while((line=bfr.readLine()) != null) { bfw.write(line.toUpperCase());//将输入的字符转成大写字符输出 bfw.newLine(); bfw.flush(); } bfr.close(); bfw.close(); } }
4. 流操作规律 :
(1)明确源和目的。
数据源:就是需要读取,可以使用两个体系:InputStream、Reader;
数据汇:就是需要写入,可以使用两个体系:OutputStream、Writer;
(2)操作的数据是否是纯文本数据?
如果是:数据源:Reader
数据汇:Writer
如果不是:数据源:InputStream
数据汇:OutputStream
(3)虽然确定了一个体系,但是该体系中有太多的对象,到底用哪个呢?
明确操作的数据设备。
数据源对应的设备:硬盘(File),内存(数组),键盘(System.in)
数据汇对应的设备:硬盘(File),内存(数组),控制台(System.out)。
(4)需要在基本操作上附加其他功能吗?比如缓冲。
如果需要就进行装饰。
相关文章推荐
- 黑马程序员—Java基础—多线程2
- JAVA面试题——编程题
- 黑马程序员——java基础---多线程
- JAVA面试题——简答题
- 安卓程序员的自我修养
- 优秀程序员所具备的7个好习惯
- 程序员的那些事儿 -- 皆大欢喜的加薪
- 这些幽默只有程序员才懂
- 【面试】---网上面试题整理
- 【面试】---网上面试题整理
- [非凡程序员]协议,代理
- [非凡程序员]OC设计模式:代理模式以及协议
- 黑马程序员——JAVA基础----常见对象
- 黑马程序员——JAVA基础----多态、抽象类和接口
- Java 面试编程题
- 二叉树 面试题
- JAVA面试题
- 黑马程序员—Java基础—多线程1
- 黑马程序员——JAVA基础----面向对象
- 程序员的职业发展