Java IO流

前言

IO流即输入流和输出流,我们对InputStream进行读操作,对OutputStream进行写操作。我们可以将流分为字节流和字符流,字节流处理一些二进制文件以字节为处理单位比如图片,音乐,视频,word文档等,字符流处理一些文本文件以char为处理单位比如说txt文件、java文件、cpp等文本文件;

节点流(文件流)

接下来我们介绍一下文件流(FileInputSteam、FileOutputSteam、FileWriter、FileReader)。

(1) 文件字节流

这里我们利用FileInputStream和FileOutputStream实现复制图片的功能。注意:输入流指定的文件必须已经存在,输出流指定的文件若存在会实现覆盖,若不存在会自动创建。

    @Test
    public void test1() throws IOException {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        byte[] bytes = new byte[1024];
        int len;
        try {
            fileInputStream = new FileInputStream("binary/Norway.jpg");
            fileOutputStream = new FileOutputStream("binary/copy.jpg");
            long begin = System.currentTimeMillis();
            while((len = fileInputStream.read(bytes))!=-1){
                fileOutputStream.write(bytes,0,len);
            }
            System.out.println("执行花费:"+(System.currentTimeMillis()-begin));// 87ms
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream!=null){
                fileInputStream.close();
            }
            if(fileOutputStream!=null){
                fileOutputStream.close();
            }
        }
    }

上述代码我们看见了一个read方法,它的作用是从输入流中读取数据。当read返回值为 -1 的时候代表已经读完。

(2) 文件字符流

这里我们实现复制文本文件.

@Test
    public void test2() throws IOException {
        String src = "binary/杂文.txt";
        String dest = "binary/copy.txt";
        copyFile(src,dest);
    }
    private void copyFile(String src,String dest) throws IOException{
        FileReader reader = null ;
        FileWriter writer = null;
        try{
            reader = new FileReader(src);
            writer = new FileWriter(dest);// 默认是覆盖不是追加
            char[] c = new char[1024];
            int len;
            long begin = System.currentTimeMillis();
            while((len = reader.read(c))!=-1){
                writer.write(c,0,len);
            }
            long end = System.currentTimeMillis();
            System.out.println("执行一共花费:"+(end-begin)+"ms");// 93ms
        }catch (Exception e){
            System.out.println(e);
        }  finally {
            if(reader!=null){
                reader.close();
            }
            if(writer!=null){
                writer.close();
            }
        }
    }

处理流

下面我们介绍缓存流和转换流

缓存流

我们很少直接使用文件流处理文件,而是将其包装成一个缓存流。缓存流内部保存一个8KB大小的空间,每次先从硬盘读取文件到缓存中比从硬盘中直接读取效率更高。下面给出示例代码:

    private void copyFileByBuffer(String src,String dest) throws IOException{
        FileReader reader = null ;
        FileWriter writer = null;
        try{
            reader = new FileReader(src);
            writer = new FileWriter(dest);
            BufferedReader bufferedReader = new BufferedReader(reader);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            char[] c = new char[1024];
            int len;
            long begin = System.currentTimeMillis();
            while((len = bufferedReader.read(c))!=-1){
                bufferedWriter.write(c,0,len);
            }
            long end = System.currentTimeMillis();
            System.out.println("执行一共花费:"+(end-begin)+"ms");// 78ms
        }catch (Exception e){
            System.out.println(e);
        }  finally {
            if(reader!=null){
                reader.close();
            }
            if(writer!=null){
                writer.close();
            }
        }
    }

小提示: public void flush()throws IOException
刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。close方法返回前也会强制写出缓存中所有的数据到预期目标。

转换流

转换流可以帮助我们实现字节流到字符流之间的转换,转换的同时也可以执行编码格式(上述创建FileReader也可以指定charset,默认utf-8)

private void change(String src,String dest) throws UnsupportedEncodingException, FileNotFoundException {
        FileInputStream fileInputStream = new FileInputStream(src);
        FileOutputStream fileOutputStream = new FileOutputStream(dest);
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"gbk");
    }

对象流

我们有时需要将Java对象转换成一个字节流(序列化),将字节流转换成一个Java对象(反序列化)。在Java中要实现序列化和反序列化,必须要实现Serializable接口(或Externalizable 接口)。
下面文字摘自宋红康老师的课件:
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:private static final long serialVersionUID;
serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。

RandomAccessFile 类

相较上述的类它有以下区别

  1. 一个类同时提供了读和写的方法
  2. 多了一个游标的功能,在游标开始的位置进行部分覆盖(非全覆盖)。
    @Test
    public void test2() throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("binary/hello.txt","rw");
        raf1.seek(3);//将指针调到角标为3的位置
        raf1.write("xyz".getBytes());//实现3 4 5位置被覆盖为"xyz"
        System.out.println(raf1.getFilePointer());// 获取游标所在的位置
        raf1.close();
    }

NIO和IO多路复用

待了解

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值