java IO体系

IO流

Java中IO流分为两种,字节流字符流,顾名思义字节流就是按照字节来读取和写入的,字符刘是按照字符来存取的;常用的文件读取用的就是字符流,在网络通信里面用的就是字节流 下面这张图是Java中IO流的总体框架:

字节流

Java中字节流一般都是以stream结尾的,输入的字节流叫InputStream,输出字节流叫OutputStream; InputStreamOutputStream是表示自己输入/输出的所有类的超类,是抽象类(abstract) 常用的字节流有:

  1. FileInputStream/FileOutputStream
  2. BufferedInputStream/BufferedOutputStream
  3. SequenceInputStream(序列流)
  4. ObjectInputStream/ObjectOutputStream(对象的输入输出流)
  5. PrintStream(打印流)

字符流

Java中输入字符流是以Reader结尾的,输出字符流是以Writer结尾的,比如我们常见的FileReaderFileWriter就是个字符流,ReaderWiter是输入/输出字符流的超类,也是抽象类 常用的字符流有:

  1. FileReader/FileWriter
  2. BufferedReader/BufferedWriter
  3. InputStremReader/OutputStreamWriter(转换流)

转换流

转换流就是将字节流转换为字符流的类,有两种:

  • InputStreamReader
  • OutputStreamWriter

InputStreamReader是个字符流(Reader),需要包装一个字节流(InputStream); OutputStreamWriter是个字符流(Writer),需要包装一个字节流(OutputStream)

包装(decorate)

包装的作用的就是在原始的对象的基础上增加新的功能,比如BufferedReader包装一个Reader,实际就是对Reader功能的增强;原始的Reader只能按照一个字符一个字符的读取,经过包装之后形成的BufferedReader就具有了新的功能: 直接读取一行(readLine)的功能,直观上说这就是所谓的Decorate. 在设计模式上这就是典型的装饰模式,其特点是:

  1. 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互
  2. 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能

对应到我们上来就是,BufferedReader和Reader都是个Reader,通过包装之后BufferedReader功能增强,但是依然可以当做Reader来用(OO的父类引用可以指向子类)

例子

字节流的例子

将mp3文件切割成多份数,然后重新组合起来

package cn.xdian.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class Demo2 {

    public static void main(String[] args) throws IOException {
        cutFile(); //切割MP3文件
        mergeFlile(); //合并MP3文件
    }

    //合并MP3
    public static void mergeFlile() throws IOException{
        File dir = new File("/home/gavinzhou/music_test");
        //找到文件夹下所有的MP3文件
        Vector<FileInputStream> vector = new Vector<FileInputStream>();
        File[] files = dir.listFiles();
        for(File file : files){
            if(file.getName().endsWith(".mp3")){
                vector.add(new FileInputStream(file));
            }
        }
        //通过Vector获取迭代器
        Enumeration<FileInputStream> e = vector.elements();
        //创建序列流
        SequenceInputStream inputStream = new SequenceInputStream(e);
        //输出流
        FileOutputStream fileOutputStream = new FileOutputStream("/home/gavinzhou/conbine.mp3");
        //读取分割的MP3文件
        byte[] buf = new byte[1024];
        int length = 0 ; 
        while((length =  inputStream.read(buf))!=-1){
            fileOutputStream.write(buf,0,length);
        }
        //关闭流
        fileOutputStream.close();
        inputStream.close();

    }


    //切割MP3
    public static void cutFile() throws IOException{
        File file = new File("/home/gavinzhou/test.mp3");
        File dir = new File("/home/gavinzhou/music_test");
        //输入字节流
        FileInputStream fileInputStream = new FileInputStream(file);
        //读取文件
        byte[] buf = new byte[1024*1024];
        int length = 0;
        for(int i = 0 ;  (length = fileInputStream.read(buf))!=-1 ; i++){
            FileOutputStream fileOutputStream = new FileOutputStream(new File(dir,"part"+i+".mp3"));
            fileOutputStream.write(buf,0,length);
            fileOutputStream.close();
        }
        //关闭流
        fileInputStream.close();
    }


}

字符流的例子

拷贝文件A变为文件B

package cn.xidian.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo1 {

    public static void main(String[] args) throws IOException {

        File sourceFile = new File("/home/gavinzhou/a.txt");
        File desFile = new File("/home/gavinzhou/b.txt");
        //创建输入流
        BufferedReader  input = new BufferedReader(new FileReader(sourceFile));
        //创建输出流
        BufferedWriter output = new BufferedWriter(new FileWriter(desFile));
        //读取源文件,写入到新的文件
        String line = null;
        while((line = input.readLine()) != null){
            output.write(line);
            output.newLine();
        }
        //关闭输入输出流
        input.close();
        output.close();
    }
}

打印流的例子

package cn.xidian.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

/*
打印流可以打印任意类型的数据,打印数据之前都会先把数据转换成字符串再进行打印
 */

class Animal{
    String name;
    String color;

    public Animal(String name,String color){
        this.name = name;
        this.color = color;
    }
    @Override
    public String toString() {
        return "名字:"+this.name+ " 颜色:"+ this.color;
    }

}



public class Demo6 {

    public static void main(String[] args) throws IOException {
        /*
        File file = new  File("/home/gavinzhou/a.txt");
        //创建打印流
        PrintStream printStream = new PrintStream(file);
        //打印任何信息到文件中
        printStream.println(97);
        printStream.println(3.14);
        printStream.println('a');
        printStream.println(true);
        Animal a = new Animal("老鼠", "黑色");
        printStream.println(a);


        //更改标准的输入输出
        System.setOut(printStream); //标准输出是到屏幕上
        System.out.println("test.......");
        */

        //收集异常的日志信息。
        File logFile = new File("/home/gavinzhou/test.log");
        PrintStream logPrintStream = new PrintStream( new FileOutputStream(logFile,true) );
        try{
            int c = 4/0; //引起异常
            System.out.println("c="+c);
            int[] arr = null;
            System.out.println(arr.length);

        }catch(Exception e){
            e.printStackTrace(logPrintStream); //输出到文件而不是屏幕上
        }   
    }
}       

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏灯塔大数据

干货|Kotlin入门第一课:从对比Java开始

1.介绍 今年初,甲骨文再次对谷歌所谓的安卓侵权使用Java提起诉讼,要求后者赔偿高达90亿美元。随后便传出谷歌因此计划将主力语言切换到苹果主导的Swift,不...

33311
来自专栏jeremy的技术点滴

写py2、py3兼容的代码

4577
来自专栏光变

2.2 ASM-类-接口和组件

ASM API对编译类进行生成和编辑,都是基于抽象类ClassVisitor实现的(参照表格 2.4)。 该类中的每一个方法都对应class文件中的同名的结构部...

601
来自专栏恰同学骚年

.NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式

开篇:在上一篇中,我们了解了匿名类、匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱...

853
来自专栏微信终端开发团队的专栏

JSPatch 实现原理详解

JSPatch 是一个 iOS 动态更新框架,只需在项目中引入极小的引擎,就可以使用就可以使用 JavaScript 调用任何 Objective-C 原生接口...

2908
来自专栏一个会写诗的程序员的博客

第4章 类与面向对象编程第4章 类与面向对象编程

在前面的章节中,我们学习了Kotlin的语言基础知识、类型系统等相关的知识。在本章节以及下一章中,我们将一起来学习Kotlin对面向对象编程以及函数式编程的支持...

712
来自专栏腾讯IVWEB团队的专栏

@ ts-check

每次阅读他人代码的时候,我心中都会冒出来两个强烈的愿望:要是 JavaScript是强类型的多好!要是文档能再详细一点就好了!多亏了 TypeScript和 J...

4190
来自专栏Python小屋

Python多态原理与示例演示

所谓多态(polymorphism),是指基类的同一个方法在不同派生类对象中具有不同的表现和行为。派生类继承了基类行为和属性之后,还会增加某些特定的行为和属性,...

3228
来自专栏老马说编程

(35) 泛型 (上) - 基本概念和原理 / 计算机程序的思维逻辑

之前章节中我们多次提到过泛型这个概念,从本节开始,我们就来详细讨论Java中的泛型,虽然泛型的基本思维和概念是比较简单的,但它有一些非常令人费解的语法、细节、以...

1848
来自专栏前端桃园

JavaScript ES6  让我们写得少,做得多

JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读。它允许您编写更少的代码并执行更多操作。 ES6 向我们介绍了许多强大的功能...

202

扫码关注云+社区