黑马程序员——JAVASE-IO流(上)

来源:互联网 发布:输入字符串统计java 编辑:程序博客网 时间:2024/05/29 18:11

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! —
一、IO流概述
1、IO流概念
IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式,Java用于操作流的类都在IO包中
2、流的分类
(1) 流按流向分为两种:输入流,输出流。
(2) 流按操作类型分为两种:
字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
字符流 : 字符流只能操作纯字符数据,比较方便。
3、IO流常用基类
字节流的抽象父类:InputStream,OutputStream
字符流的抽象父类:Reader,Writer
注意:这四个类的的子类名称都是以父类名作为子类名的后缀。
4、IO程序书写
(1) 使用前,导入IO包中的类
(2) 使用时,进行IO异常处理
(3) 使用后,释放资源
二、字节流
1、常用方法
(1) InputStream
read() 读取一个字节
read(byte[]) 读取若干(数组长度)字节
available() 获取可读的字节数
close() 关闭流, 释放资源
(2) OutputStream
write(int) 写出一个字节
write(byte[]) 写出数组中的所有字节
write(byte[],start,len);写出数组中的部分字节
close() 关闭流, 释放资源
2、常用子类
(1) InputStream
FileInputStream:文件读取流
BufferedInputStream:缓冲输入流
(2) OutputStream
FileOutputStream:文件写入流
BufferedInputStream:缓冲输出流
3、缓冲流的原理
(1) BufferedInputStream
BufferedInputStream内置了一个缓冲区(数组)
从BufferedInputStream中读取一个字节时
BufferedInputStream会一次性从文件中读取多个字节, 存在缓冲区中, 返回给程序一个,程序再次读取时, 就不用找文件了, 直接从缓冲区中获取
直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个
(2) BufferedOutputStream
BufferedOutputStream也内置了一个缓冲区(数组),程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中,直到缓冲区写满时,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。
4、读取文件
(1)创建FileInputStream对象,指定一个文件,文件必须存在,不存在则会抛出FileNotFoundException异常
(2) 使用read()方法可以从文件中读取一个字节. 如果读取到文件末尾会读到-1
(3) 读取结束后需要释放资源, 调用close()方法关闭输入流

示例:FileInputStream fis = new FileInputStream("xxx.txt");       //创建流对象,关联xxx.txt文件int b;while((b = fis.read()) != -1) {    //将每次读到的结果赋值给b    System.out.println(b);}fis.close();//关闭流,释放资源

5、写出文件
(1 ) 创建FileOutputStream对象, 指定一个文件. 文件不存在会创建新文件, 存在则清空原内容. 如果需要追加, 在构造函数中传入true.
(2) 使用write()方法可以向文件写出一个字节.
(3) 写出结束后同样需要调用close()

示例:FileOutputStream fos = new FileOutputStream("aaa.txt"); //创建流对象,关联aaa.txtfos.write(100);                                         //写出数据的时候会将前面240去掉,写出的是一个字节fos.write(98);fos.write(99);fos.close();   //关闭流,释放资源

6、拷贝文件
(1) 拷贝1:从文件中逐个字节读取, 逐个字节写出, 但这样做效率非常低

 //创建输入流对象,关联1.mp3FileInputStream fis = new FileInputStream("1.mp3");     //创建输出流对象,关联copy.mp3FileOutputStream fos = new FileOutputStream("copy.mp3");  int b;while((b = fis.read()) != -1)//将每次读到的赋值给b {                                   fos.write(b); //将b中的字节写出去                                                } //关流,释放资源fis.close();                                              fos.close(); 

(2) 拷贝2:可以定义一个数组作为缓冲区, 一次读取多个字节装入数组, 然后再一次性把数组中的字节写出

//创建输入流对象,关联1.mp3FileInputStream fis = new FileInputStream("1.mp3");  //创建输出流对象,关联copy.mp3     FileOutputStream fos = new FileOutputStream("copy.mp3");    byte[] arr = new byte[1024 * 8];           //自定义数组int len;while((len = fis.read(arr)) != -1)  //将数据读到字节数组中{         fos.write(arr, 0, len);//从字节数组中将数据写到文件上                                    //fos.write(arr);}//关流,释放资源fis.close();                                                fos.close();

(3) 拷贝3:定义一个大数组拷贝,数组和文件的字节个数一样大,不会造成内存的浪费,但如果定义的数组过,大有可能会导致内存溢出。

//fis.available();一次获取读的文件的大小FileInputStream fis = new FileInputStream("1.mp3");FileOutputStream fos = new FileOutputStream("copy.mp3");//虽然可以拷贝,但是在开发时不建议,有可能会导致内存溢出byte[] arr = new byte[fis.available()];                         fis.read(arr);fos.write(arr);fis.close();

(4) 拷贝4:带缓冲区的拷贝

FileInputStream fis = new FileInputStream("致青春.mp3");         //创建输入流对象,关联致青春.mp3BufferedInputStream bis = new BufferedInputStream(fis);         //对fis进行包装,内置一个8192大小的字节数组      FileOutputStream fos = new FileOutputStream("copy.mp3");        //创建输出流对象,关联copy.mp3BufferedOutputStream bos = new BufferedOutputStream(fos);       //对fos进行包装,内置一个8192大小的字节数组int b;while((b = bis.read()) != -1) {                             //read一次会先将文件上的数据读到缓冲区中,再从缓冲区一个一个的赋值给b    bos.write(b);                                           //write一次,是将b中的字节数据写到缓冲区,缓冲区写满再一次写到文件上}bis.close();                                                    //只需要关掉包装后的即可bos.close();

7、为什么read方法返回是int而不是byte类型呢?
因为如果读取的是视频文件或音频文件或图片文件等,在读取过程中很有可能会遇到11111111,也就是byte类型的-1,那么遇到-1程序就会停止读取,会漏掉文件,为了防止这种情况出现,把byte类型提升为int类型,在这个字节前补上24个0,把遇到的-1变成255,这样可以保证将整个文件读完
8、读中文
字节流只读中文有弊端,可能会出现半个中文
解决办法:
1、用字符流去读
2、将文件上的所有的字节数据都读到缓冲区中,然后在转换成字符串

FileInputStream fis = new FileInputStream("bbb.txt");byte[] arr = new byte[4];int len;while((len = fis.read(arr)) != -1) {    System.out.println(new String(arr,0,len));}fis.close(); 

9、写中文
字节流是可以写字符串的
但是必须将字符串转换成字节数组写出去

FileOutputStream fos = new FileOutputStream("bbb.txt");fos.write("我要学习".getBytes());fos.close();

三、标准的异常处理代码
try
{
}
catch
{
}
finally
{
}

/*复制一个图片思路:1,用字节读取流对象和图片关联。2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。3,通过循环读写,完成数据的存储。4,关闭资源。*/import java.io.*;class  CopyPic{    public static void main(String[] args)     {        FileOutputStream fos = null;        FileInputStream fis = null;        try        {            fos = new FileOutputStream("c:\\2.bmp");            fis = new FileInputStream("c:\\1.bmp");            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("写入关闭失败");            }        }    }}
0 0
原创粉丝点击