黑马程序员—java基础学习--IO ( Input Output )流(一)
2014-11-19 10:04
543 查看
IO流是Javase中比较重要的一部分,也是我们所编写的代码和文件相关联的一种体现,能够熟练的理解和运用IO流技术,可以让我们的编程能力有质一般的飞跃。今天,一起走进IO流的世界,体验一下IO的神奇色彩。
*IO流
Java对数据的操作是通过流的方式,而IO流是用来处理设备之间的数据传输,java用于操作流对象都在IO包中,流对象操作数据分为两种:字节流和字符流,而流按照流向分为输入流和输出流。
一、IO流常用的基类:
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。如InputStream的子类FileInputStream,Reader的子类FileReader。
二、字符流:
既然IO流是用于操作数据的,那么数据的最常见的体现形式是文件。那么先一文件演示为主。
字符流的几个常用类:
FileReader FileWriter
BufferedReader BufferedWriter
需求:在硬盘上,创建一个文件并写入一些文字数据。
思路:找到一个专门用于操作文件的Writer子类对象,FileWriter,后缀名是父类名,前缀名是该流对象的功能。
示例代码如下:
三、IO异常的处理:
IO异常的处理并非是我们日常中的throws抛出方法,因为IO有专业的try catch处理方式,其方式如下:
四、FileReader的两种读取方式及原理:
五、字符流的缓冲区
缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要现有流对象。
BufferedReader该缓冲区中提供了一个跨平台的换行符,就是newLine( ) 方法
BufferedWriter 该缓冲区提供了一次读取一行的方法,方便于对文本数据的获取。 readLine ( ) 方法,当返回nul时,表示读到文件末尾。需要注意的是,readLine方法返回的是回车符之前的数据内容,并不返回回车符,需要自行加入回车符。
使用字符流缓冲区进行字符文件的复制代码:
六、装饰设计模式
当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能,那么可以自定义的类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰对象的功能提供更强的功能。
装饰设计模式的通俗理解代码如下:
装饰模式的特点:
装饰模式比继承更为灵活,避免了体系的臃肿。而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的相同,只不过提供了增强功能,所以装饰类和被装饰类通常是都属于一个体系中的。
七:字节流
基类: InputStream OutputStream
缓冲区: BufferedInputStream BufferedOutputStream
使用字节流对图片的复制代码如下:
和字符流一样,字节流也有相应的缓冲区,使用缓冲区使得效率更为高效,下为使用字节流缓冲区复制mp3,并计算出复制mp3所使用的时间的代码:
八、转换流:
转换流:
InputStreamReader:字节到字符的桥梁,解码
OutputStreamWriter:字符到字节的桥梁,编码
例题:通过转换流将键盘的录入数据进行在控制台上的打印动作,代码如下:
九、流的操作规律:
开发中最痛苦的事情莫过于流对象很多,但是不知道用哪一个。
通过两个明确来完成
1,明确源和目的
源:输入流。 InputStream Reader
目的:输出流。OutputStream Writer
2,操作的数据是否为纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,再明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:socket流
目的设备:
硬盘:File
控制台:System.out
内存:数组
网络:Socket流
4,是否需要其他额外功能。
1,需要高效:
是,添加缓冲区Buffered
2,需要转换
是,使用转换流
实际需求:
1,将一个文本文件中数据存储到另一个文件中,复制文件。
源:因为是源,所以使用读取流,InputStream Reader
是不是操作文本文件
是,这时就可以选择Reader
这样体系就明确了
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。
Reader体系中可以操作文件的对象是 FileReader。
是否需要提高效率:
是,加入Reader体系中的缓冲区BufferedReader
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
目的: OutputStream Writer
是否为纯文本
是:Writer。
设备:硬盘,一个文件
Writer体系中可以操作文件的对象FileWriter
是否需要提高效率,是,加入Writer体系中的缓冲区,BufferedWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);
2,将键盘录入的数据保存到一个文件中
源:InputStream Reader
是不是纯文本: 是,Reader
设备:键盘。对应的对象是System.in
为了操作键盘的文本数据方便,需要将字节流转成字符流,按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转成字符流。用到了Reader体系中的转换流。InputStreamReader
InputStreamReader isr = new InputStream(System.in);
需要提高效率么?需要,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是否为纯文本? 是,使用Writer
设备:硬盘,一个文件 。 使用FileWriter
FileWriter fw = new FileWriter("c.txt");
FileWriter使用的是默认的编码表,GBK,不满足下述要求
*扩展:想要把录入的数据按照指定的编码表(UTF-8)将数据存入到文件中。
存储时,需要加入指定的编码表,而指定的编码表只有转换流可以指定,所以需要使用OutputStreamWriter
而该转换流需要接受一个字节输出流,而且还可以操作文件的字节输出流。 FileOutputStream,所以代码应如下:
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要提高效率么?需要
BufferedWriter bufw = new BufferedWriter(osw);
所以,需要注意的是:转换流什么时候使用,字符和字节之间的桥梁,通常涉及到字符编码转换时,需要用到转换流。
十、异常信息及日志文件的建立
如何将异常信息写入到相应的日志文件中呢?要注意的细节很多,同时也运用到了IO流技术。那么异常信息的书写方式如下:
import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo
{
public static void main(String[] args)
{
try
{
int[] arr = new int[2];
System.out.println(arr[3]);
}
catch (Exception e)
{
try
{
//为日志文件信息创建添加时间
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String s = sdf.format(d);
PrintStream ps = new PrintStream("exception.log");
//将时间信息添加到日志文件中
ps.println(s);
//将目的设置为日志文件中
System.setOut(ps);
}
catch (Exception ee)
{
//此处抛出日志创建未成功异常
throw new RuntimeException("日志文件创建失败");
}
finally
{
//关流动作
ps.close();
}
//将异常信息写入到日志文件中
e.printStackTrace();
}
}
}
*IO流
Java对数据的操作是通过流的方式,而IO流是用来处理设备之间的数据传输,java用于操作流对象都在IO包中,流对象操作数据分为两种:字节流和字符流,而流按照流向分为输入流和输出流。
一、IO流常用的基类:
字节流的抽象基类:InputStream,OutputStream
字符流的抽象基类:Reader,Writer
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。如InputStream的子类FileInputStream,Reader的子类FileReader。
二、字符流:
既然IO流是用于操作数据的,那么数据的最常见的体现形式是文件。那么先一文件演示为主。
字符流的几个常用类:
FileReader FileWriter
BufferedReader BufferedWriter
需求:在硬盘上,创建一个文件并写入一些文字数据。
思路:找到一个专门用于操作文件的Writer子类对象,FileWriter,后缀名是父类名,前缀名是该流对象的功能。
示例代码如下:
import java.io.*; class FileWriterDemo { public static void main(String[] args) throws IOException { //创建一个FileWriter对象,该对象一被初始化就必须要有被操作的文件。 //而且该文件会被创建下指定的目录下。如果该目录下已有同名文件,将覆盖原文件。 //其实该布就是在明确数据要存放的目的地。 FileWriter fw = new FileWriter("d:\\1.txt"); //调用write方法将字符串写入到流中。 fw.write("abcde"); //刷新流对象中的缓冲中的数据,将数据刷到目的地中。 // fw.flush(); //关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷到目的地中。 //和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。 fw.close(); // fw.write("fghijk"); //流关闭以后将不再能够写入,但是刷新之后还可以写入。 } }
三、IO异常的处理:
IO异常的处理并非是我们日常中的throws抛出方法,因为IO有专业的try catch处理方式,其方式如下:
import java.io.*; class FileWriterDemo { public static void main(String[] args) throws IOException { FileWriter fw = null; //此处创建引用为null是为让finally代码块中使用到fw对象 try { fw = new FileWriter("k:\\demo.txt"); //将fw进行文件的关联 fw.write("abcdefg"); //写入相应的数据 } catch (IOException e) { System.out.println(e.toString()); } finally //关流是必要的操作 所以定义在finally代码块中 { try { if(fw!=null) //判断是否为null是为了增强程序的健壮性。 fw.close(); //关流动作是会发生异常的,所以需要处理 } catch (IOException e) { System.out.println(e.toString()); } } } }
四、FileReader的两种读取方式及原理:
import java.io.*; class FileReaderDemo { public static void main(String[] args) throws IOException { //创建一个文件读取流对象,和指定名称的文件相关联。 //要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException FileReader fr = new FileReader("d:\\a.txt"); /* 第一种方式,通过字符读取 //调用读取流对象的read方法,read方法一次读一个字符,并且自动往下读 int i = 0; while((i = fr.read())!=-1){ System.out.println((char)i); } */ //第二种方式:通过字符数组进行读取 //该read ( char [ ] )返回的是读到字符的个数 char[] buf = new char[1024]; int num = 0; while((num = fr.read(buf))!=-1){ System.out.println(buf,0,num); } //关闭流 fr.close(); } }
五、字符流的缓冲区
缓冲区的出现是为了提高流的操作效率而出现的,所以在创建缓冲区之前,必须要现有流对象。
BufferedReader该缓冲区中提供了一个跨平台的换行符,就是newLine( ) 方法
BufferedWriter 该缓冲区提供了一次读取一行的方法,方便于对文本数据的获取。 readLine ( ) 方法,当返回nul时,表示读到文件末尾。需要注意的是,readLine方法返回的是回车符之前的数据内容,并不返回回车符,需要自行加入回车符。
使用字符流缓冲区进行字符文件的复制代码:
import java.io.*; class CopyTextByBuf { public static void main(String[] args) { BufferedReader bufr = null; BufferedWriter bufw = null; try { //将字符读取流对象作为参数传递给缓冲对象的构造函数。 bufr = new BufferedReader(new FileReader("a.txt")); bufw = new BufferedWriter(new FileWriter("b.txt")); //使用缓冲区特有的读取一行的方法 String line = null; while((line = bufr.readLine())!=null){ //此时写上的为读取到的有效数据 bufw.write(line); //此处应加上换行 bufw.newLine(); bufw.flush(); } } catch (IOException e) { throw new RuntimeException("读写失败"); } finally { //关闭流动作是必须执行的 if(bufr!=null) try { bufr.close(); } catch (IOException e) { throw new RuntimeException("关流失败"); } if(bufw!=null) try { bufw.close(); } catch (IOException e) { throw new RuntimeException("关流失败"); } } } }
六、装饰设计模式
当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能,那么可以自定义的类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰对象的功能提供更强的功能。
装饰设计模式的通俗理解代码如下:
class Person { private void eat() { System.out.println("something eat"); } } //没有使得Person和SuperPerson产生相应的关系,降低耦合性 class SuperPerson { private Person p; SuperPerson(Person p){ this.p = p; } public void superEat() { System.out.println("something drink"); p.eat(); System.out.println("something somke"); } } class PersonDemo { public static void main(String[] args) { Person p = new Person(); //p.eat(); SuperPerson sp = new SuperPerson(p); sp.supereat(); } }
装饰模式的特点:
装饰模式比继承更为灵活,避免了体系的臃肿。而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的相同,只不过提供了增强功能,所以装饰类和被装饰类通常是都属于一个体系中的。
七:字节流
基类: InputStream OutputStream
缓冲区: BufferedInputStream BufferedOutputStream
使用字节流对图片的复制代码如下:
import java.io.*; class CopyPicTest { public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; try { //用字节读取流对象和图片文件关联 fis = new FileInputStream("c:\\a.jpg"); //用字节读取流对象创建一个图片文件,用于存储获取到的图片数据 fos = new FileOutputStream("c:\\b.jpg"); //通过循环读写,完成数据的存储 byte[] buf = new byte[1024]; int len = 0; while((len = fis.read(buf))!=-1){ fos.write(buf); } } catch (IOException e) { throw new RuntimeException("复制文件失败"); } finally { try { //关闭资源 if(fis != null) fis.close(); } catch (IOException e) { throw new RuntimeException("资源关闭失败"); } try { //关闭资源 if(fos != null) fos.close(); } catch (IOException e) { throw new RuntimeException("资源关闭失败"); } } } }字节流缓冲区:
和字符流一样,字节流也有相应的缓冲区,使用缓冲区使得效率更为高效,下为使用字节流缓冲区复制mp3,并计算出复制mp3所使用的时间的代码:
import java.io.*; class CopyMP3Test { public static void main(String[] args) { long start = System.curr 4000 entTimeMillis(); copy_1(); long end = System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); } public static void copy_1(){ BufferedInputStream bis = null; BufferedOutputStream bos = null; try { //建立缓冲区对象并关联相关的mp3文件 bis = new BufferedInputStream(new FileInputStream("c:\\a.mp3")); bos = new BufferedOutputStream(new FileOutputStream("c:\\b.mp3")); //进行高效的读写动作 int by = 0; while((by = bis.read())!=-1){ bos.write(by); } } catch (IOException e) { throw new RuntimeException("复制失败"); } finally { //关闭流的动作 if(bis!=null) try { bis.close(); } catch (IOException e) { throw new RuntimeException("关闭失败"); } if(bos!=null) try { bos.close(); } catch (IOException e) { throw new RuntimeException("关闭失败"); } } } }
八、转换流:
转换流:
InputStreamReader:字节到字符的桥梁,解码
OutputStreamWriter:字符到字节的桥梁,编码
例题:通过转换流将键盘的录入数据进行在控制台上的打印动作,代码如下:
import java.io.*; class TransStreamDemo { public static void main(String[] args) throws IOException { //获取键盘录入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //关联输出为控制台 BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); //对源和目的进行读写操作 String line = null; while((line = bufr.readLine())!=null){ if("over".equals(line)){ break; } bufw.write(line.toUpperCase()); bufw.newLine(); bufw.flush(); } //关闭流资源 bufr.close(); bufw.close(); } }上述例子中,只要控制好源和目的,就能将数据进行相应的操作,如果控制目的为文件,即为将键盘录入写入到文件中去。
九、流的操作规律:
开发中最痛苦的事情莫过于流对象很多,但是不知道用哪一个。
通过两个明确来完成
1,明确源和目的
源:输入流。 InputStream Reader
目的:输出流。OutputStream Writer
2,操作的数据是否为纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,再明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:socket流
目的设备:
硬盘:File
控制台:System.out
内存:数组
网络:Socket流
4,是否需要其他额外功能。
1,需要高效:
是,添加缓冲区Buffered
2,需要转换
是,使用转换流
实际需求:
1,将一个文本文件中数据存储到另一个文件中,复制文件。
源:因为是源,所以使用读取流,InputStream Reader
是不是操作文本文件
是,这时就可以选择Reader
这样体系就明确了
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。
Reader体系中可以操作文件的对象是 FileReader。
是否需要提高效率:
是,加入Reader体系中的缓冲区BufferedReader
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
目的: OutputStream Writer
是否为纯文本
是:Writer。
设备:硬盘,一个文件
Writer体系中可以操作文件的对象FileWriter
是否需要提高效率,是,加入Writer体系中的缓冲区,BufferedWriter
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);
2,将键盘录入的数据保存到一个文件中
源:InputStream Reader
是不是纯文本: 是,Reader
设备:键盘。对应的对象是System.in
为了操作键盘的文本数据方便,需要将字节流转成字符流,按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转成字符流。用到了Reader体系中的转换流。InputStreamReader
InputStreamReader isr = new InputStream(System.in);
需要提高效率么?需要,使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是否为纯文本? 是,使用Writer
设备:硬盘,一个文件 。 使用FileWriter
FileWriter fw = new FileWriter("c.txt");
FileWriter使用的是默认的编码表,GBK,不满足下述要求
*扩展:想要把录入的数据按照指定的编码表(UTF-8)将数据存入到文件中。
存储时,需要加入指定的编码表,而指定的编码表只有转换流可以指定,所以需要使用OutputStreamWriter
而该转换流需要接受一个字节输出流,而且还可以操作文件的字节输出流。 FileOutputStream,所以代码应如下:
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要提高效率么?需要
BufferedWriter bufw = new BufferedWriter(osw);
所以,需要注意的是:转换流什么时候使用,字符和字节之间的桥梁,通常涉及到字符编码转换时,需要用到转换流。
十、异常信息及日志文件的建立
如何将异常信息写入到相应的日志文件中呢?要注意的细节很多,同时也运用到了IO流技术。那么异常信息的书写方式如下:
import java.io.*;
import java.util.*;
import java.text.*;
class ExceptionInfo
{
public static void main(String[] args)
{
try
{
int[] arr = new int[2];
System.out.println(arr[3]);
}
catch (Exception e)
{
try
{
//为日志文件信息创建添加时间
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String s = sdf.format(d);
PrintStream ps = new PrintStream("exception.log");
//将时间信息添加到日志文件中
ps.println(s);
//将目的设置为日志文件中
System.setOut(ps);
}
catch (Exception ee)
{
//此处抛出日志创建未成功异常
throw new RuntimeException("日志文件创建失败");
}
finally
{
//关流动作
ps.close();
}
//将异常信息写入到日志文件中
e.printStackTrace();
}
}
}
相关文章推荐
- 黑马程序员—java基础学习--IO ( Input Output )流(二)
- 黑马程序员---Java基础学习笔记(IO-前篇)
- 黑马程序员---Java基础学习笔记IO
- 黑马程序员——java基础---IO(input output)流字符流
- 黑马程序员-java基础-IO学习笔 4000 记
- 黑马程序员---Java基础学习笔记IO-2
- 黑马程序员:Java基础总结----IO(Input Output)流概述
- 黑马程序员学习log第六篇基础知识:JAVA的面向对象之IO总结
- 黑马程序员——java基础——IO的学习总结
- 黑马程序员——学习Java基础之 io LineNumberReader 之装饰设计模式
- 黑马程序员——java基础学习(IO)
- 黑马程序员---Java基础学习笔记IO-1
- 黑马程序员---Java基础学习笔记(IO-后篇)
- 黑马程序员-------学习日记Java基础 第五天
- 黑马程序员Java基础加强33-40学习日记
- 黑马程序员-------学习日记Java基础 第二天
- 黑马程序员-javaIO学习笔记
- 黑马程序员_java基础学习1
- 黑马程序员-------学习日记Java基础 第四天
- 黑马程序员Java基础加强49-56学习日记