一、IO流概述
1、定义:IO流用来处理设备之间的数据传输,java对数据的操作是通过流的方式,java用于操作流的对象都在IO包中。
2、IO程序的书写
(1)、导入IO包中的类。
(2)、进行IO异常处理。
(3)、在finally中对流进行关闭。
(2)、进行IO异常处理。
(3)、在finally中对流进行关闭。
3、流按操作数据分为两种:字节流和字符流
(1)、字节流:处理字节数据的流对象。设备上的数据无论是图片或者dvd,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据。
(2)、字符流:字符每个国家都不一样,涉及到了字符编码问题,那么GBK编码的中文用unicode编码解析是有问题的,所以需要获取中文字节数据的同时+指定的编码表才可以解析正确数据。为了方便于文字的解析,所以将字节流和编码表封装成对象,这个对象就是字符流。只要操作字符数据,优先考虑使用字符流体
(2)、字符流:字符每个国家都不一样,涉及到了字符编码问题,那么GBK编码的中文用unicode编码解析是有问题的,所以需要获取中文字节数据的同时+指定的编码表才可以解析正确数据。为了方便于文字的解析,所以将字节流和编码表封装成对象,这个对象就是字符流。只要操作字符数据,优先考虑使用字符流体
4、流按流向分为:输入流,输出流
流的操作只有两种:读和写。
流的体系因为功能不同,但是有共性内容,不断抽取,形成继承体系。该体系一共有四个基类,而且都是抽象类。
字节流的抽象基类: InputStream, OutputStream
字符流的抽象基类:Reader ,Writer
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。即子类名后缀都是父类名,前缀名都是这个子类的功能名称。
字符流和字节流
二、字符流
1、字符流——创建文件的过程:
(1)、创建流对象,建立数据存放文件
FileWriter fw = new FileWriter(“Test.txt”);
(2)、调用流对象的写入方法,将数据写入流
fw.write(“text”);
(3)、关闭流资源,并将流中的数据清空到文件中。
fw.close()。
FileWriter fw = new FileWriter(“Test.txt”);
(2)、调用流对象的写入方法,将数据写入流
fw.write(“text”);
(3)、关闭流资源,并将流中的数据清空到文件中。
fw.close()。
格式代码
FileWriter fw = null;
try{
fw = new FileWriter("Test.txt");
fw.write("text");
}
catch (IOException e){
System.out.println(e.toString());
}
finally{
If(fw!=null)
try{
fw.close();
}
catch (IOException e){
System.out.println(e.toString());
}
}
2、字符流——读取文件的过程
(1)、建立一个流对象,将已存在的一个文件加载进流。
FileReader fr = new FileReader(“Test.txt”);
(2)、创建一个临时存放数据的数组。
char[] ch = new char[1024];
(3)、调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch)。
FileReader fr = new FileReader(“Test.txt”);
(2)、创建一个临时存放数据的数组。
char[] ch = new char[1024];
(3)、调用流对象的读取方法将流中的数据读入到数组中。
fr.read(ch)。
格式代码:
FileReader fr = null;
try{
fr = new FileReader("c:\\test.txt");
char[] buf = new char[1024];
int len= 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
}
catch (IOException e){
System.out.println("read-Exception :"+e.toString());
}
finally{
if(fr!=null){
try{
fr.close();
}
catch (IOException e){
System.out.println("close-Exception :"+e.toString());
}
}
}
4、文件拷贝的经典案例
/*
步骤:
1、在e盘创建一个文件。用于存储c盘文件中的数据。
2、定义读取流和c盘文件关联。
3、通过不断的读写完成数据存储。
4、关闭资源。
*/
import java.io.*;
class ReaderWriterTest
{
publicstatic void main(String[] args)
{
//调用复制方法
//copy_1();
copy_2();
}
//用第一种读取方式进行复制
publicstatic void copy_1()
{
FileWriterfw=null;
FileReaderfr=null;
try
{
//关联读取和写入的文件
fw=newFileWriter("E:\\HelloWorld.java");
fr=newFileReader("C:\\HelloWorld.java");
for(int ch=0;(ch=fr.read())!=-1 ; )
{
fw.write(ch);//一个字符一个字符写入
}
}
catch(IOException e)
{
thrownew RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();//对读取流和写入流分别关闭
}
catch(IOException e)
{
}
if(fw!=null)
try
{
fw.close();
}
catch(IOException e)
{
}
}
}
//第二种读取方式进行复制
publicstatic void copy_2()
{
FileWriterfw=null;
FileReaderfr=null;
try
{
//关联读取和写入的文件
fw=newFileWriter("E:\\HelloWorld.java");
fr=newFileReader("C:\\HelloWorld.java");
char[]arr=new char[1024];
for(int len=0;(len=fr.read(arr))!=-1 ; )
{
fw.write(arr,0,len);//利用数组一次存入数组中的字符
}
}
catch(IOException e)
{
thrownew RuntimeException("读写失败");
}
finally
{
try
{
if(fr!=null)
fr.close();
}
catch(IOException e)
{
}
finally
{
if(fw!=null)
try
{
fw.close();
}
catch(IOException e)
{
}
}
}
}
}
三、字符流的缓冲区
1、缓冲区的出现提高了对数据的读写效率。缓冲区要结合流才可以使用。在流的基础上对流的功能进行了增强。
2、缓冲技术原理:此对象中封装了数组,将数据存入,再一次性取出。
3、
通过缓冲区复制一个文本文件
/*
需求:使用缓冲技术copy一个文本文件
*/
import java.io.*;
class BufferedCopyDemo
{
public static void main(String[] args)
{
BufferedWriter bfw=null;
BufferedReader bfr=null;
try
{
//创建写缓冲对象
bfw=new BufferedWriter(new FileWriter("ReaderWriterTest_copy.txt"));
//创建读缓冲对象
bfr=new BufferedReader(new FileReader("ReaderWriterTest.java"));
//利用BufferedReader提供的readLine方法获取整行的有效字符。直到全部获取
for (String line=null; (line=bfr.readLine())!=null; )
{
bfw.write(line);//写入指定文件中
bfw.newLine();//换行
bfw.flush();//将缓冲区数据刷到指定文件中
}
}
catch (IOException e)
{
throw new RuntimeException("文件copy失败");
}
finally
{
if(bfw!=null)
try
{
bfw.close();//关闭写入流
}
catch (IOException e)
{
throw new RuntimeException("写入流关闭失败");
}
if(bfr!=null)
try
{
bfr.close();//关闭读取流
}
catch (IOException e)
{
throw new RuntimeException("读取流关闭失败");
}
}
}
}
四、字节流
1、定义:字节流基本操作与字符流类相同。但它不仅可以操作字符,还可以操作其他媒体文件。
2、读写字节流:
InputStream 输入流(读)
OutputStream 输出流(写)
3、通过字节流复制一张图片
import java.io.*;
class CopyPic
{
public static void main(String[] args)
{
//常用方法复制
byteArrayCopy();
//利用输入流的available方法进行复制
availableCopy();
//利用available方法对复制文件大小有限制,慎用
}
//使用available方法进行复制
public static void availableCopy()
{
FileInputStream fis=null;
FileOutputStream fos=null;
try
{
//关联要复制的文件
fis=new FileInputStream("C:/Users/asus/Desktop/1.jpg");
//指定复制的路径
fos=new FileOutputStream("C:/Users/asus/Desktop/3.jpg");
//利用available方法指定数组长度
byte[] b=new byte[fis.available()];
fis.read(b);//复制关联文件数据
fos.write(b);//粘贴到指定路径
}
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("写入字节流关闭失败");
}
}
}
//使用读数组方式进行复制
public static void byteArrayCopy()
{
FileInputStream fis=null;
FileOutputStream fos=null;
try
{
//关联要复制的文件
fis=new FileInputStream("C:/Users/asus/Desktop/1.jpg");
//指定复制的路径
fos=new FileOutputStream("C:/Users/asus/Desktop/2.jpg");
//利用数组的读取方式
byte[] b=new byte[1024];
int len=0;
while ((len=fis.read(b))!=-1)//复制文件的全部数据
{
fos.write(b,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("写入字节流关闭失败");
}
}
}
}
五、字节流的缓冲区
1、 字节流的缓冲区同样是为了提高字节流的读写效率。
2、原理:将数据拷贝一部分,读取一部分,循环,直到数据全部读取完毕。
(1)、先从数据中抓取固定数组长度的字节,存入定义的数组中,再通过然后再通过read()方法读取数组中的元素,存入缓冲区。
(2)、循环这个动作,直到最后取出一组数据存入数组,可能数组并未填满,同样也取出包含的元素。
(3)、每次取出的时候,都有一个指针在移动,取到数组结尾就自动回到数组头部,这样指针在自增。
(4)、取出的时候,数组中的元素在减少,取出一个,就减少一个,直到减到0即元素取完。
(5)、当文件中的全部数据都被读取出时,read()方法就返回-1。
(1)、先从数据中抓取固定数组长度的字节,存入定义的数组中,再通过然后再通过read()方法读取数组中的元素,存入缓冲区。
(2)、循环这个动作,直到最后取出一组数据存入数组,可能数组并未填满,同样也取出包含的元素。
(3)、每次取出的时候,都有一个指针在移动,取到数组结尾就自动回到数组头部,这样指针在自增。
(4)、取出的时候,数组中的元素在减少,取出一个,就减少一个,直到减到0即元素取完。
(5)、当文件中的全部数据都被读取出时,read()方法就返回-1。
3、通过缓冲区演示对mp3的复制
import java.io.*;
class CopyMp3
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
copy_2();
long end = System.currentTimeMillis();
System.out.println((end-start)+"毫秒");
}
public static void copy_2()throws IOException
{
MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\9.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\3.mp3"));
int by = 0;
//System.out.println("第一个字节:"+bufis.myRead());
while((by=bufis.myRead())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.myClose();
}
//通过字节流的缓冲区完成复制。
public static void copy_1()throws IOException
{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\1.mp3"));
int by = 0;
while((by=bufis.read())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
}