黑马程序员 IO流
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
1.概述
(1)IO流用来处理设备之间的数据传输
(2)Java对数据的操作是通过流的方法
(3)Java用于操作流的对象都在IO包中
(4)流按操作数据分为两种:字节流与字符流
(5)流按流向分为:输入流,输出流
2.IO流常用基类
(1)字节流的抽象基类:InputStream ,OutputStream
(2)字符流的抽象基类:Reader,Writer。
(3)注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如InputStream的子类FileinputStream。
如Reader的子类FileReader。
3.IO流操作数据的演示
FileWriter fw=new FileWriter(“demo.txt”);
创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件,而且该文件会被创建到指定目录下,如果该目录下已有同名文件,将被覆盖。
fw.write(“abcde”);
调用write方法,将字符串写入到流中。
fw.flush();
刷新流对象中的缓冲中的数据。将数据刷到目的地中。
fw.close();
关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。将数据刷到目的地中。和flush的区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭。
4.IO异常处理方式
//IO异常处理方式
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args)
{//在try外建立引用,在try内进行初始化。这样fw变量就作用于整个函数
FileWriter fw=null;
try
{
fw=new FileWriter("demo.txt");
fw.write("abcdefg");
}
catch (IOException e)
{
System.out.println("catch:"+e.toString());
}
finally
{
try
{/*fw.close()是一定执行的语句,所以要放在finally中,但fw.close
存在异常,所以要单独try一下。要是在对象初始化时发生异常,
fw就为空,就不能执行close方法所以要进行判断。*/
if(fw!=null)
fw.close();
}
catch (IOException e)
{
System.out.println("catch:"+e.toString());
}
}
}
}
5.IO文件续写
传送一个true参数,代表不覆盖已有文件,并在已有文件的末尾处进行数据续写
FileWriter fw=new FileWriter(“demo.txt”,true);
fw.write(“haha\r\nxiexie”);
6.文本文件读取方式一
创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException。
调用读取流对象的read方法,read():一次读一个字符,而且会自动往下读,如果读到流的末尾,则返回-1(结束标识)
FileReader fr=new FileReader(“demo.txt”);
int ch=0;
While(ch=fr,read()!=-1)
{
System.out.println((char)ch);
}
7.文本文件读取方式二
定义一个字符数组,用于存储读到字符,该read(char[])返回的是读到字符个数。
FileReader fr=new FileReader(“demo.txt”);
char[] buf=new char[1024];
int num=0;
While((num=fr.read(buf))!=-1)
{
System.out.println(new String(buf,0,num));
}
8.拷贝文本文件
/*将一个文本文件复制到另一个文本文件中*/
import java.io.*;
class CopyTest
{
public static void main(String[] args)
{
copy();
}
public static void copy()
{
FileWriter fw=null;
FileReader fr=null;
try
{
fw=new FileWriter("Demo_copy.java");//创建一个存储文件
fr=new FileReader("Demo.java");//创建已有文件关联
char[] buf=new char[1024];//创建一个数组
int len=0;
while((len=fr.read(buf))!=-1)//读取Demo文件内容返回字符个数
{
fw.write(buf,0,len);//写出数组中已存储的内容
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fw!=null)
try
{
fw.close();//关闭流资源
}
catch (IOException e)
{
}
if(fr!=null)
try
{
fr.close();
}
catch (IOException e)
{
}
}
}
}
9.字符流的缓冲区
(1)缓冲区的出现提高了对数据的读写效率。
(2)对应类:BufferedWriter,BufferedReader
(3)缓冲区要结合流才可以使用。
(4)在流的基础上对流的功能进行了增强。
10.BufferedWriter的使用
//创建一个字符写入流对象
FileWriter fw=new FileWriter(“buf.txt”);
//将要被提高效率的流对象作为参数传递给缓冲区的构造函数
BufferedWriter bufw=new BufferedWriter(fw);
for(int x=1;x<5;x++)
{
bufw.writer(“abcd”+x);
bufw.newLine();//换行
bufw.flush();//只要用到缓冲区,就要刷新
}
bufw.close();//关闭缓冲区就是在关闭缓冲区中的流对象
11.BufferedReader
//创建一个读取流对象和文件相关联
FileReader fr=new FileReader(“buf.txt”);
/*为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲区对象的构造函数。*/
BufferedReader bufr=new BufferedReader(fr);
String line=null;
/*readLine方法读取一个文本行,返回的时候只返回回车符之前的数据内容,并不返回回车符。如果已到达流末尾则返回null*/
While((line=bufr.readLine())!=null)
{
System.out.println(line);
}
bufr.close//关闭缓冲区
12.通过缓冲区复制一个java文件
//通过缓冲区复制一个java文件
import java.io.*;
class CopyTestByBuf
{
public static void main(String[] args)
{
BufferedWriter bufw=null;
BufferedReader bufr=null;
try
{
//创建目的地,并使用缓冲技术
bufw=new BufferedWriter(new FileWriter("bufWriter_copy.java"));
//与已有文件关联,并使用缓冲技术
bufr=new BufferedReader(new FileReader("Demo.java"));
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);//写出一行的数据
bufw.newLine();//换行
bufw.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
try
{
if(bufr!=null)
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(bufw!=null)
bufw.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
13.装饰设计模式
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
14.字节流:InputStream,OutputStream
available()可以获取字节数。利用这个方法可以定义一个刚刚好的缓冲区,这样可以省略循环。
FileInputStream fis=new FileInputStream(“fos,txt”)
byte[] buf=new byte[fis.available()];//只适用于内存较小的文件
fis.read(buf);
System.out.println(new String(buf));
Fis.close
通过练习来了解InputStream,OutputStream的使用。
//复制一个图片
import java.io.*;
class CopyPic
{
public static void main(String[] args)
{
FileInputStream fis=null;
FileOutputStream fos=null;
try
{
fis=new FileInputStream("e:\\1.gif");//字节读取流对象和图片关联
fos=new FileOutputStream("e:\\2.gif");//字节写入流对象创建一个图片文件
byte[] buf=new byte[1024];//创建数组用于存储图片数据
int len=0;
while((len=fis.read(buf))!=-1)//返回的是读取字节的个数
{
fos.write(buf,0,len);//通过循环写出数组中的图片数据
}
}
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("写入关闭失败");
}
}
}
}
15.字节流的缓冲区
//通过字节流缓冲区,演示mp3文件复制
import java.io.*;
class BufCopyMp3
{
public static void main(String[] args)
{
BufferedInputStream bufis=null;
BufferedOutputStream bufos=null;
try
{
//创建输入流,并使用缓冲技术
bufis=new BufferedInputStream(new FileInputStream("e:\\0.mp3"));
//创建输出流,并使用缓冲技术
bufos=new BufferedOutputStream(new FileOutputStream("e:\\1.mp3"));
int by=0;
while((by=bufis.read())!=-1)
{
bufos.write(by);
}
}
catch (IOException e)
{
throw new RuntimeException("复制失败");
}
finally
{
try
{
if(bufis!=null)
bufis.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(bufos!=null)
bufos.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
}
}
}
16.读取键盘输入
System.out:对应的是标准输出设备,控制台。
System.in:对应的标准输入设备,键盘。
InputStream in=System.in;//键盘输入
in.read();//读取键盘输入
17.读取转换流(InputStreamReader)
通过readLine方法完成键盘录入的一行数据,readLine方法是字符流BufferedReader类中的方法,而键盘录入的read方法是字节流InputStream的方法,所以需要将字节流转成字符流再使用字符流缓冲区的readLine方法
import java.io.*;
class TransStreamDemo
{
public static void main(String[] args) throws IOException
{
//获取键盘录入对象
InputStream in=System.in;
//将字节流对象转成字符流对象,使用转换流,InputStreamReader
InputStreamReader isr=new InputStreamReader(in);
//将字符串进行缓冲区技术高效操作,使用BufferedReader
BufferedReader bufr=new BufferedReader(isr);
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))//输入over时,跳出录入
break;
System.out.println(line.toUpperCase());//转成大写
}
bufr.close();
}
}
18.写入转换流(OutputStreamReader)
import java.io.*;
class TransStreamDemo2
{
public static void main(String[] args) throws IOException
{
//获取键盘录入对象
InputStream in=System.in;
//将字节流对象转成字符流对象,使用转换流,InputStreamReader
InputStreamReader isr=new InputStreamReader(in);
//将字符串进行缓冲区技术高效操作,使用BufferedReader
BufferedReader bufr=new BufferedReader(isr);
//将字符流转换成字节流,同时进行缓冲区技术高效操作
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))//输入over时,跳出录入
break;
bufw.write(line.toUpperCase());
bufw.newLine();//跨平台的换行
bufw.flush();
}
bufr.close();
}
}
19.流操作规律
(1)
源:键盘录入
目的:控制台
(2)需求:想把键盘录入的数据存储到一个文件中
源:键盘
目的:文件
(3)需求:想要一个文件中的数据打印在控制台上
源:文件
目的:控制台
流操作的基本规律:
通过三个明确来确定流对象的使用
(1)明确源和目的
源:输入流,InputStream, Reader
目的:输出流,OutputStream, writer
(2)操作的数据是否是纯文本。
是:字符流
否:字节流
(3)当体系明确后,再明确要使用哪个具体的对象
通过设备来进行区分
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,控制台
再判断是否需要提高效率
是:加入对应体系中的缓冲区
20.扩展
想把录入的数据按照指定的编码表(utf-8),将数据存到文件中
存储时,需要加入指定编码表(utf-8),而指定的编码表只有转换流可以指定,所以要使用的对象是OutputStreamWriter
OutputStreamWriter osw=
New OutputStreamWriter(new FileOutputStream(“d.txt”),”UTF-8”)
21.改变标准输入输出设备
System.setIn(new FileInputStream(“PersonDemo”.java))
System.setOut(new PrintStream(“ZZZ”.txt))