第20天 FileInputStream、FileOutStream、异常、输入输出字节流、缓冲输入输出字节流

来源:互联网 发布:东方不败 知乎 编辑:程序博客网 时间:2024/06/06 13:24

1.FileInputStream读取完整数据

File类用于描述一个文件或者文件夹的
通过File对象我们可以读取文件或者文件夹的属性数据,如果我们需要读取文件的内容数据,那么我们需要使用IO流技术。
IO流(Input Output)
IO流解决问题: 解决设备与设备之间的数据传输问题。  内存--->硬盘   硬盘--->内存
IO流的分类
如果是按照数据的流向划分:
输入流
输出流
如果按照处理的单位划分:
字节流: 字节流读取得都是文件中二进制数据,读取到二进制数据不会经过任何的处理。
字符流: 字符流读取的数据是以字符为单位的 。 字符流也是读取文件中的二进制数据,不过会把这些二进制数据转换成我们能 识别的字符。  
判断使用输入流还是输出流的依据:以当前程序作为参照物,观察数据是流入还是流出,如果流出则使用输出流,如果数据是流入则使用输入流。
输入字节流:
-| InputStream 所有输入字节流的基类  抽象类
-| FileInputStream  读取文件数据的输入字节流
使用FileInputStream读取文件数据的步骤:
1) 找到目标文件
2) 建立数据的输入通道。
3) 读取文件中的数据。
4) 关闭 资源.
import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class Demo1 {public static void main(String[] args) throws IOException {readTest4();}//方式4:使用缓冲数组配合循环一起读取。28public static void readTest4() throws IOException{long startTime = System.currentTimeMillis();//找到目标文件File file = new File("F:\\美女\\1.jpg");//建立数据的输入通道FileInputStream fileInputStream = new FileInputStream(file);//建立缓冲数组配合循环读取文件的数据。int length = 0; //保存每次读取到的字节个数。byte[] buf = new byte[1024]; //存储读取到的数据    缓冲数组 的长度一般是1024的倍数,因为与计算机的处理单位。  理论上缓冲数组越大,效率越高while((length = fileInputStream.read(buf))!=-1){ // read方法如果读取到了文件的末尾,那么会返回-1表示。System.out.print(new String(buf,0,length));}//关闭资源fileInputStream.close();long endTime = System.currentTimeMillis();System.out.println("读取的时间是:"+ (endTime-startTime)); //446}//方式3:使用缓冲 数组 读取。    缺点: 无法读取完整一个文件的数据。     12Gpublic static void readTest3() throws IOException{//找到目标文件File file = new File("F:\\a.txt");//建立数据的输入通道FileInputStream fileInputStream = new FileInputStream(file);//建立缓冲字节数组,读取文件的数据。byte[] buf = new byte[1024];  //相当于超市里面的购物车。int length = fileInputStream.read(buf); // 如果使用read读取数据传入字节数组,那么数据是存储到字节数组中的,而这时候read方法的返回值是表示的是本次读取了几个字节数据到字节数组中。System.out.println("length:"+ length);//使用字节数组构建字符串String content = new String(buf,0,length);System.out.println("内容:"+ content);//关闭资源fileInputStream.close();}//方式2 : 使用循环读取文件的数据public static void readTest2() throws IOException{long startTime = System.currentTimeMillis();//找到目标文件File file = new File("F:\\美女\\1.jpg");//建立数据的输入通道FileInputStream fileInputStream = new FileInputStream(file);//读取文件的数据int content = 0; //声明该变量用于存储读取到的数据while((content = fileInputStream.read())!=-1){System.out.print((char)content);}//关闭资源fileInputStream.close();long endTime = System.currentTimeMillis();System.out.println("读取的时间是:"+ (endTime-startTime)); //446}//读取的方式一缺陷: 无法读取完整一个文件 的数据.public static void readTest1() throws IOException{//1. 找到目标文件File file = new File("F:\\a.txt");//建立数据的输入通道。FileInputStream fileInputStream = new FileInputStream(file);//读取文件中的数据int content = fileInputStream.read(); // read() 读取一个字节的数据,把读取的数据返回。System.out.println("读到的内容是:"+ (char)content);//关闭资源    实际上就是释放资源。  fileInputStream.close();}}

2.FileInputStream读取文件方式的选择

通过System.currentTimeMillis()来判断执行代码之前和执行代码时候的时间差来判断执行效率,执行效率高,所花费的时间少的为最佳读取方式,具体代码参考上面的代码。

3.FileInputStream读取要 注意的细节

读取玩一个文件的数据的时候,我不关闭资源有什么影响

答案:资源文件一旦 使用完毕应该马上释放,否则其他的程序无法对该资源文件进行其他 的操作。

import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.util.Arrays;public class Demo2 {public static void main(String[] args) throws IOException {//找到目标文件File file = new File("F:\\day18-day21.IO.doc");//建立数据的输入通道FileInputStream fileInputStream = new FileInputStream(file);//建立缓冲字节数组读取文件byte[] buf = new byte[8];int length = 0 ;while((length = fileInputStream.read(buf))!=-1){System.out.print(new String(buf));  // aaaa   bbba  bbb' '//System.out.println(Arrays.toString(buf));}//释放文件资源fileInputStream.close();}}
4.FileOutStream写数据
1)输出字节流
案例:
1,写代码实现把"Hello World!"写到"c:/a.txt"文件中。
a, c:/a.txt不存在时,测试一下。
b, c:/a.txt存在时,也测试一下。
要写两个版本:
a, 使用write(int b) 实现。
b, 使用write(byte[] b) 实现。
2,在已存在的c:/a.txt文本文件中追加内容:“Java IO”。
显然此时需要向指定文件中写入数据。
使用的就是可以操作文件的字节流对象。OutputStream。该类是抽象类,需要使用具体的实现类来创建对象查看API文档,找到了OutputStream的实现类FileOutputStream 创建FileOutputStream 流对象,必须指定数据要存放的目的地。通过构造函数的形式。创建流对象时,调用了系统底层的资源。在指定位置建立了数据存放的目的文件。
流程:
1:打开文件输出流,流的目的地是指定的文件
2:通过流向文件写数据
3: 用完流后关闭流
2)FileOutStream向文件输出数据的输出字节流
FileOutputStream如何使用呢?
1. 找到目标文件
2. 建立数据的输出通道。
3. 把数据转换成字节数组写出。
4. 关闭资源
FileOutputStream要注意的细节:
1. 使用FileOutputStream 的时候,如果目标文件不存在,那么会自动创建目标文件对象。 
2. 使用FileOutputStream写数据的时候,如果目标文件已经存在,那么会先清空目标文件中的数据,然后再写入数据。
3.使用FileOutputStream写数据的时候, 如果目标文件已经存在,需要在原来数据基础上追加数据的时候应该使用new FileOutputStream(file,true)构造函数,第二参数为true。
import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class Demo1 {public static void main(String[] args) throws IOException {writeTest3();}//使用字节数组把数据写出。public static void writeTest3() throws IOException{//找到目标文件File file = new File("F:\\b.txt");//建立数据输出通道FileOutputStream fileOutputStream = new FileOutputStream(file);//把数据写出。String data = "abc";byte[] buf = data.getBytes();fileOutputStream.write(buf, 0, 3); // 0 从字节数组的指定索引值开始写, 2:写出两个字节。//关闭资源fileOutputStream.close();}//使用字节数组把数据写出。public static void writeTest2() throws IOException{//找到目标文件File file = new File("F:\\b.txt");//建立数据输出通道FileOutputStream fileOutputStream = new FileOutputStream(file,true);//把数据写出。String data = "\r\nhello world";fileOutputStream.write(data.getBytes());//关闭资源fileOutputStream.close();}//每次只能写一个字节的数据出去。public static void writeTest1() throws IOException{//找到目标文件File file = new File("F:\\b.txt");//建立数据的输出通道FileOutputStream fileOutputStream = new FileOutputStream(file);//把数据写出fileOutputStream.write('h');fileOutputStream.write('e');fileOutputStream.write('l');fileOutputStream.write('l');fileOutputStream.write('o');//关闭资源fileOutputStream.close();}}

4.使用FileOutputStream的write方法写数据的时候,虽然接收的是一个int类型的数据,但是真正写出的只是一个字节的数据,只是把低八位的二进制数据写出,其他二十四位数据全部丢弃。

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.Arrays;public class Demo2 {public static void main(String[] args) throws IOException {readTest();}public static void readTest() throws IOException{//找到目标文件File file = new File("F:\\c.txt");//建立数据的输入通道FileInputStream fileInputStream = new FileInputStream(file);//建立缓冲输入读取文件数据byte[] buf = new byte[4];//读取文件数据int length = fileInputStream.read(buf);System.out.println("字节数组的内容:"+ Arrays.toString(buf));//关闭资源fileInputStream.close();}public static void writeTest() throws FileNotFoundException, IOException {//找到目标文件File file = new File("F:\\c.txt");//建立数据的输出通道FileOutputStream fileOutputStream = new FileOutputStream(file);//把数据写出fileOutputStream.write(511);//关闭资源fileOutputStream.close();}}

5.异常的处理

拷贝一张图片import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class CopyImage {public static void main(String[] args) throws IOException {//找到目标文件File inFile = new File("F:\\美女\\1.jpg");File destFile = new File("E:\\1.jpg");//建立数据的输入输出通道FileInputStream fileInputStream = new  FileInputStream(inFile);FileOutputStream fileOutputStream = new FileOutputStream(destFile); //追加数据....//每新创建一个FileOutputStream的时候,默认情况下FileOutputStream 的指针是指向了文件的开始的位置。 每写出一次,指向都会出现相应移动。//建立缓冲数据,边读边写byte[] buf = new byte[1024]; int length = 0 ; while((length = fileInputStream.read(buf))!=-1){ //最后一次只剩下了824个字节fileOutputStream.write(buf,0,length); //写出很多次数据,所以就必须要追加。}//关闭资源 原则: 先开后关,后开先关。fileOutputStream.close();fileInputStream.close();}}

IO异常的处理

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import javax.management.RuntimeErrorException;public class Demo1 {    public static void main(String[] args) {        //readTest();        copyImage();    }    // 拷贝图片    public static void copyImage() {        FileInputStream fileInputStream = null;        FileOutputStream fileOutputStream = null;        try {            // 找到目标文件            File inFile = new File("F:\\美女\\1.jpg");            File outFile = new File("E:\\1.jpg");            // 建立输入输出通道            fileInputStream = new FileInputStream(inFile);            fileOutputStream = new FileOutputStream(outFile);            // 建立缓冲数组,边读边写            byte[] buf = new byte[1024];            int length = 0;            while ((length = fileInputStream.read(buf)) != -1) {                fileOutputStream.write(buf, 0, length);            }        } catch (IOException e) {            System.out.println("拷贝图片出错...");            throw new RuntimeException(e);        } finally {            // 关闭资源            try {                if (fileOutputStream != null) {                    fileOutputStream.close();                    System.out.println("关闭输出流对象成功...");                }            } catch (IOException e) {                System.out.println("关闭输出流资源失败...");                throw new RuntimeException(e);            } finally {                if (fileInputStream != null) {                    try {                        fileInputStream.close();                        System.out.println("关闭输入流对象成功...");                    } catch (IOException e) {                        System.out.println("关闭输入流对象失败...");                        throw new RuntimeException(e);                    }                }            }        }    }    public static void readTest() {        FileInputStream fileInputStream = null;        try {            // 找到目标文件            File file = new File("F:\\aaaaa.txt");            // 建立数据输入通道            fileInputStream = new FileInputStream(file);            // 建立缓冲数组读取数据            byte[] buf = new byte[1024];            int length = 0;            while ((length = fileInputStream.read(buf)) != -1) {                System.out.print(new String(buf, 0, length));            }        } catch (IOException e) {            /*             * //处理的代码... 首先你要阻止后面的代码执行,而且要需要通知调用者这里出错了... throw new             * RuntimeException(e);             * //把IOException传递给RuntimeException包装一层,然后再抛出,这样子做的目的是             * 为了让调用者使用变得更加灵活。             */            System.out.println("读取文件资源出错....");            throw new RuntimeException(e);        } finally {            try {                if (fileInputStream != null) {                    fileInputStream.close();                    System.out.println("关闭资源成功...");                }            } catch (IOException e) {                System.out.println("关闭资源失败...");                throw new RuntimeException(e);            }        }    }}

6.缓冲输入字节流

我们清楚读取文件数据使用缓冲数组读取效率更高,sun也知道使用缓冲数组读取效率更高,那么

 这时候sun给我们提供了一个------缓冲输入字节流对象,让我们可以更高效率读取文件。

输入字节流体系:

----| InputStream  输入字节流的基类。 抽象

----------| FileInputStream 读取文件数据的输入字节流

----------| BufferedInputStream 缓冲输入字节流    缓冲输入字节流的出现主要是为了提高读取文件数据的效率。   

其实该类内部只不过是维护了一个8kb的字节数组而已。

 

注意: 凡是缓冲流都不具备读写文件的能力。

 

使用BufferedInputStream的步骤 :

   1. 找到目标文件。

   2. 建立数据 的输入通道

   3. 建立缓冲 输入字节流流

   4. 关闭资源

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo1 {    public static void main(String[] args) throws IOException {        readTest2();    }    public static void readTest2() throws IOException {        //找到目标文件        File file = new File("F:\\a.txt");        FileInputStream fileInputStream = new FileInputStream(file);        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);        bufferedInputStream.read();        FileOutputStream fileOutputStream = new FileOutputStream(file);        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);        fileOutputStream.write(null);        //读取文件数据        int content = 0;        //疑问二:BufferedInputStream出现 的目的是了提高读取文件的效率,但是BufferedInputStream的read方法每次读取一个字节的数据        //而FileInputStreram每次也是读取一个字节的数据,那么BufferedInputStream效率高从何而来?        while ((content = fileInputStream.read()) != -1) {            System.out.print((char) content);        }        //关闭资源        bufferedInputStream.close(); //调用BufferedInputStream的close方法实际上关闭的是FileinputStream.    }    //读取文件的时候我们都是使用缓冲数组读取。效率会更加高    public static void readTest() throws IOException {        File file = new File("F:\\a.txt");        //建立数组通道        FileInputStream fileInputStream = new FileInputStream(file);        //建立缓冲数组读取数据        byte[] buf = new byte[1024 * 8];        int length = 0;        while ((length = fileInputStream.read(buf)) != -1) {            System.out.print(new String(buf, 0, length));        }        //关闭资源        fileInputStream.close();    }}

7.缓冲输出字节流

输出字节流

--------| OutputStream  所有输出字节流的基类  抽象类

------------|FileOutputStream 向文件 输出数据 的输出字节流

------------|Bufferedoutputstream  缓冲输出字节流    BufferedOutputStream出现的目的是为了提高写数据的效率。

                       内部也是维护了一个8kb的字节数组而已。

 

 使用BufferedOutputStream的步骤:

   1. 找到目标文件

   2. 建立数据的输出通道

BufferedOutputStream 要注意的细节

   1. 使用BufferedOutStream写数据的时候,它的write方法是是先把数据写到它内部维护的字节数组中。

   2. 使用BufferedOutStream写数据的时候,它的write方法是是先把数据写到它内部维护的字节数组中,如果需要把数据真正的写到硬盘上面,需要

   调用flush方法或者是close方法、 或者是内部维护的字节数组已经填满数据的时候。

import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class Demo2 {    public static void main(String[] args) throws IOException {        //找到目标文件        File file = new File("F:\\a.txt");        //建立数据的输出通道        FileOutputStream fileOutputStream = new FileOutputStream(file);        //建立缓冲输出字节流对象        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);        //把数据写出        bufferedOutputStream.write("hello world".getBytes());        //把缓冲数组中内部的数据写到硬盘上面。        //bufferedOutputStream.flush();        bufferedOutputStream.close();    }}

8.缓冲输入输出字节流拷贝图片

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class CopyImage {    public static void main(String[] args) throws IOException {        //找到目标文件        File inFile = new File("F:\\美女\\1.jpg");        File outFile = new File("E:\\1.jpg");        //建立数据输入输出通道        FileInputStream fileInputStream = new FileInputStream(inFile);        FileOutputStream fileOutputStream = new FileOutputStream(outFile);        //建立缓冲输入输出流        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);        //边读边写        int content = 0;        // int length = bufferedInputStream.read(buf);   如果传入了缓冲数组,内容是存储到缓冲数组中,返回值是存储到缓冲数组中的字节个数。        while ((content = bufferedInputStream.read()) != -1) { // 如果使用read方法没有传入缓冲数组,那么返回值是读取到的内容。            bufferedOutputStream.write(content);            //bufferedOutputStream.flush();        }        //关闭资源        bufferedInputStream.close();        bufferedOutputStream.close();    }}







0 0
原创粉丝点击