input(读取)、output(写入)
流:数据(字符、字节) 1个字符=2个字节,1个字节=8个二进制位

IO流最顶层的父类

image.png

字节流

一切均是字节
image.png

字节流可以传输任意文件数据

字节输出流

OutputStream(抽象类)所有字节输出流的顶层

文件字节输出流

java.io.FileOutputStream extends OutputStream
作用:把内存中的数据写入到硬盘中

构造方法:

FileOutputStream(String name)
FileOutputStream(File file)
参数:
    写入数据的目的地
    String name:目的地是一个文件的路径
    File file:目的地是一个文件
作用:
  1. 创建一个FileOutputStream对象

2.根据传递的参数(文件/文件路径),创建一个空的文件
3.将FileOutputStream对象指向创建好的文件

写入数据的原理(内存 --> 硬盘)

java程序 --> JVM --> OS --> OS调用写数据的方法 --> 写入数据到文件

字节输出流的使用步骤(!!!)
1.创建FileOutputStream对象,构造方法中传入目的地
2.调用FileOutputStream对象中的write方法,把数据写入文件(将十进制转换为二进制
3.释放资源(流使用会占用内存,释放提高程序效率)

    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("E:\\A JI\\program\\java\\a.txt");

        fos.write(98);

        fos.close();
    }

结果:新建了一个a.txt文件(大小为1kb),并往里面写了98的二进制形式
fos.write(1100010)98 --> 1100010
任意的文本编辑器(记事本、notepad++...)在打开文件的时候,都会查询编码表,把字节转换为字符表示(所以才会显示b)

  • 0-127:查询ASCII表
  • 其他值:查询系统默认码表(中文系统GBK)

image.png
image.png
image.png

write方法(写入字节的方法)

  1. write(byte[] b):将b.length字节从指定的字节数组写入输出流
  2. write(byte[] b, int off, int len):指定字节数组写入len字节,从偏移量off开始输出到此输出流(off:数组的开始索引)

一次写多个字节:

  1. 第一个字节为正数(0-127),先查询ASCLL码再显示
  2. 第一个字节为负数,第一字节和第二字节,组成中文显示,查询GBK
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("E:\\A JI\\program\\java\\b.txt");
        byte[] b = {49, 48, 48};
        fos.write(b);
        fos.write(b, 1, 2);
        fos.close();
    }

写入字符的方法:使用String中方法,将字符串转换为字节数组

byte[] getBytes()
byte[] bytes2 = "你好".getBytes();
        fos.write(bytes2);

数据的续写

FileOutputStream(String name, boolean append): 
    创建一个向具有指定name的文件中写入数据的输出文件流
    
FileOutputStream(File file, boolean append):
    创建一个向指定File**对象**表示的表示的文件中写入数据的文件输出流

参数:
    String name, File file:写入数据的目的地
    boolean append:追加写开关
        true:创建对象不会覆盖原文件,在末尾追写数据
        false:创建一个新文件,覆盖原文件

换行写数据

   public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("E:\\A JI\\program\\java\\b.txt", true);

        fos.write("hello".getBytes());
        for (int i = 1; i < 10; i++) {
            fos.write("heihei".getBytes());
            //系统识别换行标识符才执行,所以把标识符也写进去
            fos.write("\r\n".getBytes());
        }
        fos.close();
    }

字节输入流

InputStream(抽象类)所有字节输入流的顶层

int read():一个读取一个字节(但是会自动把指针往后移动一位

当值被读取完了,往后再读取就返回 -1 

int read(byte[] b):读取多个字节,将其存储在缓冲区数组b中

文件字节输入流

java.io.FileInputStream extends InputStream

作用:把硬盘文件中的数据,读取到内存中使用

构造方法:

FileInputStream(String name)
FileInputStream(File file)
参数:
    读取文件的数据源
    String name:文件的路径
    File file:文件
作用:
  1. 创建一个FileInputStream对象
  2. 将FileInputStream对象指定构造方法中要读取的文件

读取数据的原理(硬盘 --> 内存)

java程序 --> JVM --> OS --> OS调用读数据的方法 --> 读取文件   

字节输出流的使用步骤(!!!)
1.创建FileInputStream对象,构造方法中绑定要读取的数据源
2.调用FileInputStream对象中的read方法,读取文件
3.释放资源(流使用会占用内存,释放提高程序效率)

int read():

    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("E:\\A JI\\program\\java\\b.txt");
        /*
        (len = fis.read()) != -1
        fis.read():读取一个字节
        len = fis.read():把读取到的字节赋值给len
        (len = fis.read()) != -1:判断len是否不等于 -1
            
         */
        int len = 0;
        while ((len = fis.read()) != -1) {
            System.out.println((char) len);
        }

        fis.close();
    }

为啥不能用

        while (fis.read() != -1) {
            System.out.println(fis.read());
        }
当进入循环后,指针会 +1, 输出语句中有fis.read,实际读的是下一个字节,并且再次移动指针,再次进入循环判定的时候,指针已经移动两次了

int read(byte[] b):

image.png

image.png

    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("E:\\A JI\\program\\java\\a.txt");

        byte[] bytes = new byte[1024];
        int len = 0;

        while ((len = fis.read(bytes)) != -1) {
            System.out.println(len);
            //数组有过多剩余
            System.out.println(new String(bytes));
            //把字节数组的一部分转换为字符串, offset:数组开始的索引,length:转换的字节个数
            System.out.println(new String(bytes, 0, len));
        }
        fis.close();
    }

案例

文件复制
image.png

    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\2019招生计划.png");
        FileOutputStream fos = new FileOutputStream("E:\\a.png");
        //最基本的方法,但每次只读取一个,效率太低
//        int len = 0;
//        while ((len = fis.read()) != -1) {
//            fos.write(len);
//        }
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = fis.read()) != -1) {
            fos.write(bytes, 0, len);
        }
        //先关闭写的,再关闭读
        //如果写完了,肯定读完了,反之不一定
        fos.close();
        fis.close();
    }

byte[]并不是把所有的字节都存进来,只是存一部分缓冲,所以不需要容纳所有数据字节

并且不能使用true续写数据,这样会使得文件打开错误!!

FileOutputStream fos = new FileOutputStream("E:\\a.png", true);

waikiki
4 声望2 粉丝