java I/O流(一)——FileWriter,BufferedWriter,inputStream,BufferedInputStream,InputStreamReader

来源:互联网 发布:历年粮食进出口数据 编辑:程序博客网 时间:2024/05/21 09:19

I/O全名:Input Output,输入输出的意思

•IO流用来处理设备之间的数据传输
•流操作分两种:字节流,字符流
•流按流向分为:输入流,输出流

IO

•字节流的抽象积累

◦InputStream
◦OutputStream

•字符流的抽象基类

◦Reader
◦Writer

FileWriter

•需求:在硬盘上创建一个文件,并且写入数据
那我们怎么去做?他构造函数比较多的,我们看例子

public class HelloJJAVA {    public static void main(String[] args) {        /**         * 需求:在硬盘上创建一个文件,并且写入数据         */        // 一被初始化就必须要有被操作的文件        // 如果不指定位置,就创建在同目录下        // 如果目录下存在同名文件,覆盖        try {            FileWriter fileWriter = new FileWriter("test.txt");            // 写入数据到内存            fileWriter.write("abcde");            // 刷新该流的缓冲            // fileWriter.flush();            // 关闭流 关闭之前会刷新,和flush的区别在于flush刷新后流可以继续工作            fileWriter.close();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

这样在我们的项目根目录下就可以看到生成的文件了

文件续写
我们知道,文件存在的话就会覆盖,但是我们不想这样,我们想在原有的数据中续写,这该去怎么做?

public class HelloJJAVA {    public static void main(String[] args) {        try {            //参数2代表不覆盖已有的文件,支持续写            FileWriter fileWriter = new FileWriter("demo.txt",true);            fileWriter.write("你好");            fileWriter.close();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

构造传参的时候设置为true就可以续写文件了

FileReader
既然写已经会了,那我们就来读取了

public class HelloJJAVA {    public static void main(String[] args) {        try {            // 创建一个文件读取流对象,和指定名称的文件关联,保证文件存在,            // 如果不存在,异常            FileReader fileReader = new FileReader("demo.txt");            // 读取单个字符,自动往下读            int cd = fileReader.read();            System.out.println((char) cd);            //全部打印            int ch = 0;            while ((ch = fileReader.read()) != -1) {                System.out.println(ch);            }            fileReader.close();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

这样就可以按照字节读取了,我们也可以把读到的字符存储在数组中

import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;public class HelloJJAVA {    public static void main(String[] args) {        try {            FileReader fileReader = new FileReader("demo.txt");            char[] buf = new char[3];            int num = fileReader.read(buf);            System.out.println("num:" + num + new String(buf));        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

文本复制
读写都说了,我们来看下其他的操作,我们首先来看复制

•复制原理:其实就是将C盘下的文件数据存储到D盘的一个文件中
实现的步骤:
1.在D盘创建一个文件,用于存储文件中的数据
2.定义读取流和文件关联
3.通过不断的读写完成数据的存储
关闭资源

import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class HelloJJAVA {    public static void main(String[] args) {        copy_1();        copy_2();    }    // 从c盘读一个字符,就往D盘写一个字符    public static void copy_1() {        try {            // 创建目的地            FileWriter fw = new FileWriter("copy_1.txt");            // 与已有文件关联            FileReader fr = new FileReader("copy_1.txt");            int ch = 0;            while ((ch = fr.read()) != -1) {                // 读一个 写一个                fw.write(ch);            }            fw.close();            fr.close();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public static void copy_2() {        FileWriter fw = null;        FileReader fr = null;        try {            fw = new FileWriter("copy_2.txt");            fr = new FileReader("copy_2.txt");            char[] buf = new char[1024];            int len = 0;            while ((len = fr.read(buf)) != -1) {                fw.write(buf, 0, len);            }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } finally {            if (fr != null) {                try {                    fr.close();                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            if (fw != null) {                try {                    fw.close();                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }    }}

这里做了两种方式的拷贝方式,其实都是整理好思路,读和写的一个过程罢了!

字符流的缓冲区,提高了对数据的读写效率,他有两个子类
•BufferedWriter
•BufferedReader

我们还是复制文件这个问题,现在我们有缓冲区,我们要怎么样复制文件?

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class HelloJJAVA {    public static void main(String[] args) {        /**         * 缓冲区文件复制         */        BufferedReader bufr = null;        BufferedWriter bufw = null;        try {            bufr = new BufferedReader(new FileReader("buffer.txt"));            bufw = new BufferedWriter(new FileWriter("buffercopy.txt"));            String line = null;            while((line = bufr.readLine()) != null){                bufw.write(line);            }            //关闭流            bufr.close();            bufw.close();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

字节流读取操作
字符流我们讲的差不多了,我们接着说字节,其实他们类似的,知识他操作的是字节而已

•inputStream:读
•outputStream:写
我们还是从例子开始

import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class HelloJJAVA {    public static void main(String[] args) {        writeFile();    }    // 写文件    public static void writeFile() {        try {            FileOutputStream fo = new FileOutputStream("demo.txt");            fo.write("test".getBytes());            fo.close();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

专门处理的字节流

public static void readFile2() {        try {            FileInputStream fs = new FileInputStream("demo.txt");            int num = fs.available();            System.out.println(num);            fs.close();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

我们发现直接用available就可以拿到字节了,原理其实是这段代码

public static void readFile2() {        try {            FileInputStream fs = new FileInputStream("demo.txt");            byte[] buf = new byte[fs.available()];            fs.read(buf);            System.out.println(new String(buf));            fs.close();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

字节流的缓冲区

这个,和我们的字符流基本上没有什么差别,我们来拷贝mp3,看例子// 通过字节流的缓冲区拷贝图片    public static void copyMp3() {        try {            FileInputStream fi = new FileInputStream("audio.mp3");            BufferedInputStream buf = new BufferedInputStream(fi);            FileOutputStream fio = new FileOutputStream("audioCapy.mp3");            BufferedOutputStream buo = new BufferedOutputStream(fio);            int ch = 0;            while ((ch = buf.read()) != -1) {                buo.write(ch);            }            buf.close();            buo.close();        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }//这样,就直接拷贝了

转换流InputStreamReader

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;public class HelloJJAVA {    public static void main(String[] args) throws IOException {        //获取键盘录入对象        InputStream in = System.in;        //转换        InputStreamReader isr = new InputStreamReader(in);        //提高效率        BufferedReader bur = new BufferedReader(isr);        String line = null;        while((line = bur.readLine()) != null){            if(line.equals("over"))                break;            System.out.println(line.toString());        }    }}

写入转换流

import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;public class HelloJJAVA {    public static void main(String[] args) throws IOException {        //获取键盘录入对象        InputStream in = System.in;        //转换        InputStreamReader isr = new InputStreamReader(in);        //提高效率        BufferedReader bur = new BufferedReader(isr);        OutputStream os = System.out;        OutputStreamWriter osw = new OutputStreamWriter(os);        BufferedWriter bufw = new BufferedWriter(osw);        String line = null;        while((line = bur.readLine()) != null){            if(line.equals("over"))                break;            bufw.write(line.toString());            bufw.newLine();            bufw.flush();        }    }}

如何选择流?
◦1.明确源和目的

■源:输入流 InputStream Reader
■目的:输出流 OutputStream writer
◦2.明确操作的数据是否是纯文本

■是:字符流
■不是:字节流

0 0