文件字节流(FileInputStream/FileOutputStream)

IO流操作分为四步核心步骤:

        1.创建源

        2.选择流

        3.具体操作

        4.释放资源(系统资源)

一.文件字节输入流(FileInputStream)

        文件输入流(FileInputStream),顾名思义就是以程序为中心将文件中的内容以字节为单位读取到程序中(文件-->程序)。主要方法为:

        1.close():释放资源。

        2.read():读取文件到程序。

        构造方法如下:InputStream is = new FileInputStream("文件名")或InputStream is = new FileInputStream("文件路径");

文件字节流(FileInputStream/FileOutputStream)_第1张图片

         close()方法:

         read()方法:

文件字节流(FileInputStream/FileOutputStream)_第2张图片

         具体代码如下:

import java.io.*;

/**
 * IO流操作步骤
 * 一.创建源
 * 二.选择流
 * 三.操作
 * 四.释放资源
 */
public class TestFileInputStream {
    public static void main(String[] args) {
        //一.创建源
        File file = new File("abc.txt");
        //二.选择流
        try {
            InputStream inPut = new BufferedInputStream(new FileInputStream(file));
            //三.操作(读取)
            int data1 = inPut.read();     //读取第一个字节
            int data2 = inPut.read();     //读取第二个字节
            int data3 = inPut.read();     //读取第三个字节
            int data4 = inPut.read();     //读取第四个字节
            System.out.println((char) data1);
            System.out.println((char) data2);
            System.out.println((char) data3);
            System.out.println(data4);   //没有字节,输出-1
            //四.释放资源
            inPut.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();      //从外界读取数据,与外界存在联系,需要抛出异常
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

       abc.txt中的内容为abc,则输出结果为:a(\n)b(\n)c(\n)-1。InputStrem是字节文件输入流,以字节为单位读取(UTF-8:英文1个字节,数字1个字节,汉字3个字节)。因此读取字母不会出现乱码情况,但是若换成汉字则会出现乱码(因为此处是一个字节一个字节的读,导致字节数不够出现乱码),此处要特别注意。对于没有字节的情况,则返回-1。

System.out.println((char) data1);
System.out.println((char) data2);
System.out.println((char) data3);

       我们需要对输出结果进行强转(字节数组-->字符:解码),否则输出的是字符在UTF-8中的代号。    

      上面的代码并不标准,下面我们进行改进。

     改进版一:增加循环,增加异常处理机制

**
 * 创建IO流的标准步骤
 * 一.创建源
 * 二.选择流
 * 三.操作
 * 四.释放资源
 */

public class TestFileInputStream01 {
    public static void main(String[] args){
        //1.创建源
        File file = new File("abc.txt");  //相对路径
        //2.选择流
        InputStream inputStream = null;  //扩大inputStream的作用范围,以适应inputStream.close()
        try {        //需要和外界数据源打交道,所以抛出异常
            inputStream = new BufferedInputStream(new FileInputStream("abc.txt")); //或(file);
            //3.操作
            int temp;
            try {
                while ((temp = inputStream.read())!=-1){
                    System.out.println((char)temp);
                }
//                释放资源
//                inputStream.close();   如果在操作遍历打印时出现异常,则直接转到catch,不会执行释放内存操作,因此需要将其转入finally
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if (inputStream != null){
                    inputStream.close(); //如果inputStream没有被成功创建,则不释放资源,否则才释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

        改进过后,可以处理异常,并且可以读取多字节(以单字节为单位)的文件。

      改进版二:一段一段的读,添加接收长度与缓冲容器,读取效率更高。JDK如下:

        改进代码如下: 

import java.io.*;

/**
 * 测试InputStream中的read(byte[] b)(每次读取多个字节):文件字节输入流(对字节进行操作)(针对文件)
 * 字节数组-->字符串(解码)
 * InputStream:read()方法
 */
public class TestFileInputStream02 {
    public static void main(String[] args) {
        //创建源
        File file = new File("abc.txt");
        InputStream inputStream = null;
        //选择流
        try {
            //操作
            inputStream = new BufferedInputStream(new FileInputStream(file));
            //创建一个字节数组(flush)作为缓冲容器用来存储abc.txt中的内容。定义一个字节数组(abc,txt中的内容),每次读取1024个字节,将其存储在flush(缓冲容器)中
            byte[] flush = new byte[1024];             //容器的大小为每次读取1024个字节(1K)
            int len = -1;        //接收长度:用来接收flush的长度
            //读取字节数组(长度)
            try {
                while ((len = inputStream.read(flush))!=-1){   //将读取的长度赋给len,当读取不到内容时返回-1
                    //调用read()方法将读取到的字节数组
                    //字节数组-->字符串(解码)  构造方法:String(byte[] bytes, int offset, int length)
                    //通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。
                    String datas = new String(flush,0,len);  //将字节数组转化为字符串再输出,从flush中读取,从第一位开始读取,读取len个长度
                    System.out.println(datas);                 //InputStream:先读取字节数组,再转化为字符串(解码)
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if (inputStream!=null){
                inputStream.close();  //释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

          添加接收长度与缓冲容器后可以读取以任意字节的文件。        

         文件字节输入流可以将任何形式的文件读取到程序中,包括文件,音频,视频,图片等等。



二.文件字节输出流

         文件字节输出流将数据以程序为中心将以字符为单位的内容写出到文件中(程序-->文件)。四大步骤不变。操作略有变化。主要方法为:

        1.close():释放资源。

        2.write():读取文件到程序。

        3.flush():刷新资源,防止数据驻留到内存中。

        构造方法如下:OutputStream os = new FileOnputStream("文件名")或OutputStream os = new FileOutputStream("文件路径");

         

文件字节流(FileInputStream/FileOutputStream)_第3张图片

文件字节流(FileInputStream/FileOutputStream)_第4张图片

        write()方法:

文件字节流(FileInputStream/FileOutputStream)_第5张图片

        flush()方法:

        具体代码如下: 

import java.io.*;

/**
 * 测试OutputStream中的write(byte[] b, int off, int len):文件字节输出流(对字节进行操作)
 * write(byte[] b, int off, int len)
 * 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
 * OutputStream:write()方法
 * 字符串-->字节数组(编码)
 */
public class TestFileOutputStream {
    public static void main(String[] args) {
        //创建源
        File file = new File("abc.txt");
        //选择流
        OutputStream outputStream = null;
        try {
            outputStream = new BufferedOutputStream(new FileOutputStream(file,true)); //true:在后面追加内容,false:覆盖原来所有内容重新写入
            //操作
            //定义一个str字符串,表示要写出的内容
            String str = " I am going to China\n";
            //调用String类的getBytes()方法,将字符串转化为字节数组
            //字符串-->字节数组(编码)
            byte[] datas = str.getBytes();
            //调用OutputStream中的write()方法写出字节数组
            try {
                outputStream.write(datas,0,datas.length);   //从字节数组中写出,从第一个开始写,写字节数组的长度
                outputStream.flush(); //防止未资源完全释放,刷新一下
                //OutputStream:先转换成字节数组(编码),再写出
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            //释放资源
            try {
                if (outputStream!=null){
                outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

        使用getBytes()方法将字符串转成字节数组(编码),再使用write(byte[] b, int off, int len)写出到文件中。OutputStream的目标文件可以不存在,不存在会自动创建。而InputStream的源文件必须存在。

        运行结果如下:

I am going to China

       FileOutputStream可以追加,通过boolean append进行追加:  

       当append为true时,表示在目标文件已有内容的基础上继续追加(接着往后写入)。

       当append为false时,表示将目标文件里的内容清空然后重新写入。

     欢迎批评指正

你可能感兴趣的:(JAVA,JavaSE,IO流,JavaSE,IO流,文件字节流,适合爱技术的小白,良心干货)