黑马程序员——java基础拾遗之IO流(一) 常用类及方法

------- android培训java培训、期待与您交流! ----------


       IO流是java很重要的知识点,在这里总结一下IO的一些知识点,常用的类以及用法。

       按照操作的数据类型分,IO流分成两种:字节流和字符流。
       字节流抽象基类:InputStream,OutputStream;
       字符流抽象基类:Reader,Writer;
       IO流有很多衍生的类,但是大多以基类名称结尾,可以根据类名是以什么结尾的来区分是那种IO流;
缓冲区:提高数据读写效率。java对文件的读写效率相对比较低,次数越多,程序执行速度越低下,用缓冲区技术目的是减少对文件的读写次数,以此提高IO性能。缓冲区是针对流进行操作的,因此是和流结合使用的。以Buffered开头。

一.字符流常用类

(1)FileWriter类使用示例

<span style="font-size:14px;">     /**
       FileWriter类使用示例
       @param args
     */
    public static void main(String[] args) {
        FileWriter fw = null;
        try {
       	    // 此处会抛出异常,D盘下output.txt会被创建,此处true表示不覆盖之前同名的文件,新数据追加在后面
            fw = new FileWriter("D:\\output.txt", true);
            // 此处会抛出异常,写入流中,不会直接写入文件
            fw.write("\n123abc");
        } catch (IOException e) {
            System.err.println(e.toString());
        } finally {
            try {
            		// 为了防止初始化失败(第10行)使此处fw为null出现空指针异常,需要进行空判断
                if (null != fw) {
                    fw.close();//刷新并关闭
                }
            } catch (IOException e) {
                System.err.println(e.toString());
            }

        }
    }</span>


FileWriter 常用方法write()写字符,flush()刷新流程,close()先刷后关。

    
(2)FileReader类使用示例
    
文本文件读取示例,读取D盘下一个名字叫Input.txt的文本文件,不用担心换行,换行符会读取到并原样打印出来


<span style="font-size:14px;">/**
     FileReader类使用示例
     @param args
     */
	public static void main(String[] args) {
        FileReader fr = null;
        char[] ch = new char[1024];
        try {
            // 读取D盘下的Input.txt文件,不存在抛出文件找不到异常
            fr = new FileReader("D:\\Input.txt");
            int num = 0;
            while ((num = fr.read(ch)) != -1) {// 文件结尾时返回为-1,read(char[] ch)返回读取到的字符数
                System.out.println(new String(ch));
            }
        } catch (IOException e) {
            System.err.println("error info:" + e);
        } finally {
            try {
                fr.close();
            } catch (IOException e) {
                System.err.println("error info" + e);
            }


        }
    }</span>

FileReader 常用方法read:

可以读一个字符,也可以读一个数据,一般都是读数组,如上面的例;

 read(char[] ch)返回读取的字符的个数,read()返回读取字符的ASCII码。


字符流通过读取一个数组的方式复制一个文件(比较常用,推荐)
    
<span style="font-size:14px;">public static void main(String[] args) {
        FileWriter fw = null;
        FileReader fr = null;
        try {
            fw = new FileWriter("D:\\MyWorkSpace\\java\\IoDemoTest.txt");
            fr = new FileReader("Exception.java");
            char[] ch = new char[1024];
            int len = 0;
            while ((len = fr.read(ch)) != -1) {
                fw.write(ch, 0, len);
            }
        } catch (IOException e) {
            throw new RuntimeException("读写失败");
        } finally {
            if (null != fw) {
                try {
                    fw.close();
                } catch (IOException e) {
                    throw new RuntimeException("流关闭失败");
                }
            }
            if (null != fr) {
                try {
                    fr.close();
                } catch (IOException e) {
                    throw new RuntimeException("流关闭失败");
                }
            }
        }
    }
    </span>


(3)字符流缓冲区


字符流缓冲区示例,通过字符流缓冲区来复制一个文件
    
<span style="font-size:14px;">public static void main(String[] args) {
        FileWriter fw = null;
        FileReader fr = null;
        BufferedWriter bufw = null;
        BufferedReader bufr = null;
        try {
            fw = new FileWriter("D:\\BufferedReaderTest.txt");
            fr = new FileReader("Exception.java");
            bufw = new BufferedWriter(fw);
            bufr = new BufferedReader(fr);
            String strReadLine = "";
            while ((strReadLine = bufr.readLine()) != null) {
                bufw.write(strReadLine);
                bufw.newLine();
                bufw.flush();
            }
        } catch (IOException e) {
            System.err.println("error info:" + e);
        } finally {
            try {
                bufw.close();// 应该分别关这里图省事
                bufr.close();
            } catch (IOException e) {
                System.err.println("error info" + e);
            }
        }
    }</span>
    

二.字节流常用类


(1)FileInputStream,FileOutputStream类

使用示例,用字节流复制图片

<span style="font-size:14px;">public static void main(String[] args) {
        FileOutputStream fos = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("D:\\1.bmp");
            fos = new FileOutputStream("D:\\2.bmp");
            int len = 0;
            byte[] b = new byte[1024];
            while ((len = fis.read(b)) != -1) {
                fos.write(b, 0, len);
            }
        } catch (IOException e) {
            System.err.println("error info:" + e);
        } finally {
            if (null != fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    throw new RuntimeException("文件输入流关闭失败");
                }
            }
            if (null != fos) {
                try {
                    fos.close();
                } catch (IOException e) {
                    throw new RuntimeException("文件输出流关闭失败");
                }
            }
        }
    }</span>


FileInputStream 常用方法read(byte[] b)读取字节数组,close()关闭;

FileOutputStream 常用方法write(byte[] b, int off, int len),将字节数组中的固定起始的内容写入文件输出流,close关闭;

区别:FileOutputStream的flush继承自OutputStream,而OutputStream的flush不执行任何操作。因此FileOutputStream不需要执行flush。

(2)用字节流缓冲区复制Mp3

用法同之前的FileInputStream和FileOutputStream

<span style="font-size:14px;"><span style="font-size:12px;">public static void main(String[] args) {
        BufferedInputStream bufIS = null;
        BufferedOutputStream bufOS = null;
        try {
            bufIS = new BufferedInputStream(new FileInputStream("1.mp3"));
            bufOS = new BufferedOutputStream(new FileOutputStream("2.mp3"));
            int by = 0;
            long start = System.currentTimeMillis();
            while ((by = bufIS.read()) != -1) {
                bufOS.write(by);
            }
            long end = System.currentTimeMillis();
            System.out.println(end - start + "毫秒");
        } catch (IOException e) {
            throw new RuntimeException("error info" + e);
        } finally {
            try {
                bufIS.close();
            } catch (IOException e) {
                throw new RuntimeException("error info" + e);
            }
            try {
                bufOS.close();
            } catch (IOException e) {
                throw new RuntimeException("error info" + e);
            }
        }
    }</span></span>


(3)读取键盘输入流


System.in返回的的是键盘的输入字节流

<span style="font-size:14px;">public static void main(String[] args) {
        InputStream in = System.in;
        int x = 0;
        try {
            while ((x = in.read()) != -1) {
                System.out.println((char) (x + 1));
            }
        } catch (IOException e) {
            throw new RuntimeException("键盘流读取失败啦");
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                throw new RuntimeException("键盘流读取失败啦");
            }
        }
    }</span>

上面这种方法已经过时,在java 5以后 已经有新的类可以使用Scanner,Scanner的用法后面继续总结。

    

三.转换流


用来将字节流转换为字符流,方便使用字符流的readLine()等方法操作数据


(1)InputStreamReader,写入转换流


使用示例

<span style="font-size:14px;">/**
     * 读取转换流示例
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        InputStream in = System.in;
        // InputStreamReader将字节流转化为了字符流;
        InputStreamReader inr = new InputStreamReader(in);
        BufferedReader bufr = new BufferedReader(inr);
        String str = "";
        while ((str = bufr.readLine()) != null) {
            if ("over".equals(str)) {
                break;
            }
            System.out.println(str.toUpperCase());
        }
    }</span>

    
转化后,可以应用字符流缓冲区的readLine()方法来操作输入流;


(2) OutputStreamWriter,输出转换流


使用示例


<span style="font-size:14px;">    /**
     * 输出转换流
     * @param args
     */
    public static void main(String[] args) {
        BufferedReader bufr = new BufferedReader(new InputStreamReader(
            System.in));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(
            System.out));
        String str = "";
        try {
            while ((str = bufr.readLine()) != null) {
                if ("over".equals(str)) {
                    break;
                }
                bufw.write(str);
                bufw.newLine();// 相当于输出换行符
                bufw.flush();
            }
        } catch (IOException e) {
            throw new RuntimeException("转换流失败");
        } finally {
            try {
                bufr.close();
            } catch (IOException e) {
                throw new RuntimeException("字符读取缓冲区关闭失败");
            }
            try {
                bufw.close();
            } catch (IOException e) {
                throw new RuntimeException("字符输出缓冲区关闭失败");
            }
        }
    }</span>


上例中展示的是转化后,可以应用字符流缓冲区的newLine()方法来输出跨平台的换行;

注意:OutputStreamWriter可以指定编码表,当涉及编码格式转化时也需要转换流。



注意要点:

1.IO异常的处理,需要格外注意,IO的new方法,读写,流的刷新关闭都会抛出IO异常,
2.流使用以后必须关闭,因此常把流的关闭放在finally代码块中。
3.流的建立遵循先建立引用,后建立对象,目的是将对象建立时候会抛出的异常放在try中捕获,同时不影响finally代码块中针对流对象的关闭。
4.流关闭的时候也会抛出异常,因此在finally中对流的关闭再次捕获异常。
5.对象初始化异常后,finally代码块就不需要再关闭,因此需要对流对象进行空判断。
(是不是很麻烦,习惯就好,这样最保险,养成好习惯最重要)
6.文件路径\\的问题,\表示转义,两个\才能表示\,例如:D:\\java\\1.txt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值