IO字节流

IO流的概述

IO:输入/输出(Input/Outout)
l流:是一种抽象感念,是对数据传输的总称。数据在设备间的传输称为流,流的本质是数据的传输。

IO流就是用来处理设备间的数据传输问题的。常见的应用有:文本复制,文件上传,文件下载…


分类:

按照数据的流向:
输入流:读取数据
输出流:写入数据

按照数据类型:(默认)

字节流(万能流)
输入字节流
输出字节流

字符流(在使用系统自带的文本文档能读懂的内容就可以使用)
输入字符流
输出字符流


字节流写数据:

InputStream:字节输入流的所有类的超类
OutputStream:字节输出流的所有类的超类

子类名的特点: 子类名都是以其父类名作为子类名的后缀。

/*
    FileOutputStream:文件输出流,用于将指定的数据写入File
    FileOutputStream​(String name) 创建文件输出流以指定的名称写入文件。
 */
import java.io.*;
public class TestDemo_01 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fo = new FileOutputStream("D:\\JavaProject\\JavaSE\\javase.txt");
        /*    这里做了三件事情
                1.调用系统功能创建了文件。 javase.txt
                2.创建了字节输出流对象。    fo
                3.让字节输出流指向了创建好的文件。  fo → javase.txt
         */
        fo.write(97);//小写a,这里写入的都是字符。
        fo.close();//所有和IO有关的操作都要释放资源。
        /*
        close() 关闭此文件输出流并释放与此流相关的任何系统资源。
         */
    }

步骤:
1.创建字节输出流对象{
①.调用系统功能创建了文件(javase.txt )
②创建了字节输出流对象。(fo)
③让字节输出流指向了创建好的文件。 ( fo → javase.txt)
}
2.调用字节流输出对象的写数据方法
3.释放资源(关闭此文件输出流并释放与此流相关的任何系统资源。)

字节流写数据的三种方法:

package IODemo;
/*
    void write​(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。
    void write​(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。
    void write​(int b) 将指定的字节写入此文件输出流。
 */
import java.io.*;
public class TestDemo_01 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fo1 = new FileOutputStream("D:\\JavaProject\\JavaSE\\javase.txt");
        //一次 写一个字节
        fo1.write(89);
        //一次写一个数组的字节
        byte[] b = {97,98,99,100,101};
        fo1.write(b);
        //一次写一个数组指定的字节
        fo1.write(b,1,4);
        fo1.close();
        //FileOutputStream​(String name, boolean append) 创建文件输出流以指定的名称写入文件。
        // append 添加  创建文件输出流以指定的名称写入文件。 如果第二个参数为true ,
        // 则字节将写入文件的末尾而不是开头。 将创建一个新的FileDescriptor对象来表示此文件连接。
        FileOutputStream fo2 = new FileOutputStream("D:\\JavaProject\\JavaSE\\javase.txt",true);
        //byte[] getBytes​() 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。
        for (int a = 0 ; a < 6 ;a++){
            fo2.write("efghi\r\n".getBytes());
        }
        /*
            字节流的换行
            windows:   \r\n
            linux:      \n
            mac:        \r
         */
        fo2.close();
    }
}

字节流读数据:

/*
            D:\JavaProject\text\复制.txt 文件中存有下列内容

            Hello
            Wolrd

            两行字
 */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class InputStreamDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fi = new FileInputStream("D:\\JavaProject\\text\\复制.txt");
        //一次读取一个数组的字节
        byte[] by = new byte[1024];
        int len=fi.read(by);
        while (len!=-1){
            System.out.println(new String(by,0,len));
        }
//        //第二次读取
//        System.out.println(len); //len 是读取到的字节数,这里是5
//        System.out.println(new String(by));// ello  因为已经在上边读取了一个字节,所以这里是从第二个开始的
//                                           //4个字母是因为 o 后边有换行符 /r
//        //第三次读取
//        len = fi.read(by);
//        System.out.println(len); //len 是读取到的字节数,这里是5
//        System.out.println(new String(by));
//        /*
//          5
//
//          Wolr       5,这里空了一行,然后输出Wolr 因为windows中换行是/r/n上边读取了一个
//          /r,还有一个/n这次的读取是从/n开始的,一共五个
//
//
//        */
//        //第四次读取
//        len = fi.read(by);
//        System.out.println(len); //len 是读取到的字节数,这里是3
//        System.out.println(new String(by));
//        /*
//            d
//            lr
//            这里读取的是从d开始然后是/r/n这里只有三个字节,所以读取数字是3,我们要读取五个,还空下两个,这两个是由上一次读
//            到的数组中的后两个组成的。
//         */
//
//        /*
//        这里应该这么写   System.out.println(new String(by,0,len));
//        String​(byte[] bytes, int offset, int length) 通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。
//               byte数组中   从多少个元素开始   读取多少个
//         */
        //释放资源
        fi.close();
    }
}

复制文件

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fi = new FileInputStream("F:\\GM\\GM命令\\基础命令.txt");
        FileOutputStream fo = new FileOutputStream("D:\\JavaProject\\text\\复制.txt");
        int by;
        while ((by=fi.read())!=-1){     // 只要读取的字节数量不是 -1,就一直读取。
            fo.write(by);               // 每读取by数量的字节,就写入by数量的字节
        }
        fo.close();
        fi.close();
    }
}

对比,下边的为什么会输出乱码

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fi = new FileInputStream("F:\\GM\\GM命令\\基础命令.txt");
        FileOutputStream fo = new FileOutputStream("D:\\JavaProject\\text\\复制.txt");
        while (fi.read()!=-1){     // 只要读取的字节数量不是 -1,就一直读取。
            fo.write(fi.read());               // 每读取by数量的字节,就写入by数量的字节
        }
        fo.close();
        fi.close();
    }
}

一次读取一个数组的复制

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fi = new FileInputStream("F:\\GM\\GM命令\\基础命令.txt");
        FileOutputStream fo = new FileOutputStream("D:\\JavaProject\\text\\复制.txt");
        byte[] by = new byte[1024];
        int len;
        while ((len=fi.read(by))!=-1){     // 只要读取的字节数量不是 -1,就一直读取。
            fo.write(by,0,len);               // 每读取by数量的字节,就写入by数量的字节
        }
        fo.close();
        fi.close();
    }
}

字节缓冲流(提高读写效率)

BufferedOutputStream:
该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。

BufferedInputStream:
创建BufferedInputStream将创建一个内部缓冲区数组。 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。

构造方法:
BufferedInputStream​(InputStream in)
创建一个 BufferedInputStream并保存其参数,输入流 in供以后使用。

BufferedOutputStream​(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

字节缓冲流仅仅提供缓冲区域,而真正的读写数据还得靠基本的字节流对象进行操作。所以,这里的参数是对象,不是具体的文件或者字符串路径。

//BufferedInputStream源码解析
    private static int DEFAULT_BUFFER_SIZE = 8192;
    
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
        //上边的构造方法调用了 下边的构造方法
    public BufferedInputStream(InputStream in, int size) {
        //将DEFAULT_BUFFER_SIZE 的值传给了size
    }
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
        //创建了一个自带的数组,大小是8192
    }

读写代码:

import java.io.*;
public class BuffereDemo {
    public static void main(String[] args) throws IOException {
//        FileInputStream fi = new FileInputStream("F:\\GM\\GM命令\\基础命令.txt");
//        FileOutputStream fo = new FileOutputStream("D:\\JavaProject\\text\\复制.txt");
//        BufferedOutputStream bo = new BufferedOutputStream(fo);
//        BufferedInputStream bi = new BufferedInputStream(fi);
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\JavaProject\\text\\复制.txt"));
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\JavaProject\\text\\复制.txt"));
       //写数据
        //void write​(byte[] b, int off, int len) 从偏移量 off开始的指定字节数组写入 len字节到缓冲输出流。
        //void write​(int b) 将指定的字节写入缓冲的输出流。
        //byte[] getBytes​() 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。
        //这里没有write(byte[] byte)的方法...但是它的父类中有,所以可以用。
        bos.write("Hello\r\n".getBytes());
        bos.write("World\r\n".getBytes());
        bos.close();//先释放才能在下边读取代码。否则是没有写入么?

        //读数据  和 FileOutputStream 一样
        int by;
        while ((by = bis.read())!=-1){  //将读取字节的 值  给by
            System.out.print((char)by);//将by转换为char值并输出
        }
        System.out.println("***********");//因为bis.read()=-1了,所以下边的代码不会执行了
        byte[] bys = new byte[1024];
        int len;
        while ((len = bis.read(bys))!=-1){
            System.out.println(new String(bys,0,len));
        }
        bis.close();


        //        byte[] by = new byte[1024];
//        int len;
//        while ((len = bi.read(by))!= -1){
//                bo.write(by,0,len);
//        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值