JAVA学习笔记13 IO流(1)

File的案例补充:

在这里插入图片描述

package File;

import java.io.File;
import java.io.IOException;

public class FileDiGuiDemo {
    public static void main(String[] args) throws IOException {
        File f = new File("D:\\develop\\IntelliJ IDEA 2021.3");

        getFilePath(f);
    }

    public static void getFilePath(File file) {
        //获取指定目录下的所有目录或文件
        File[] fileArray = file.listFiles();
        if (fileArray != null) {
            for (File f : fileArray) {
                if (f.isDirectory()){
                    getFilePath(f);
                }
                else {
                    System.out.println(f.getAbsolutePath());
                }
            }
        }
    }
}

输出结果:
在这里插入图片描述

字节流

字节流写数据

字节流抽象基类

  • InputStream:此抽象类是所有字节输入流的所有类的超类。
  • OutputStream:此抽象类是所有字节输出流的所有类的超类。
  • 他们都所有子类都是以父类名作为后缀的,比如:FileOutputStream。

FileOutputStream:文件输出流用于将数据写入File。

  • FileOutputStream(String name):创建文件输出流以指定的名称写入文件。

使用字节输出流写数据的步骤:

  • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
//创建字节输出流对象
        //FileOutputStream创建文件输出流,然后将之写入指定文件中
        FileOutputStream fos=new FileOutputStream("ieda_test\\src\\IO\\fos.txt");

        //将指定字节写入此文件输出流
        fos.write(97);//ascii码97对应a
        fos.write(57);//ascii码57对应9

        //最后都需要释放资源
        //void关闭此文件输出流并释放于此流相关联的任何系统资源
        fos.close();

fos.txt中:
在这里插入图片描述
这里需要注意的是

FileOutputStream fos=new FileOutputStream(“ieda_test\src\IO\fos.txt”);

这条语句有三个功能:
①创建一个FileOutputStream对象fos。
②创建了一个文件fos.txt到指定目录下。
③将输出流对象fos写入fos.txt文件中。

④如果文件夹中有fos.txt了,那么会创建一个新的覆盖掉之前的。
⑤并且,通过这种输出流对象写入文件输出流的方式,文件以文本打开后显示的是输出流作为ascii码对应的字符。
如:输出流为97,显示为a
为了方便,可以使用getBytes()方法将字符串直接转换为ascii码,然后作为输出流写入。

byte[]  a="abcde".getBytes();
        fos.write(a);

在这里插入图片描述

字节流写数据的3种方式

在这里插入图片描述

字节流写数据的两个小问题

一、如何实现换行

windows:\r\n
linux:\n
mac:\r

for (int i=0;i<10;i++){
            fos.write("hello\r\n".getBytes());
        }

输出
在这里插入图片描述

二、如何实现追加写入

其实每次使用write写入都是最末尾进行追加,那为何这里还要实现追加写入呢?
因为这里的追加写入的意思其实是,每次使用不同的FileOutputStream对同一个文件进行追加写入:
比如之前这个fos.txt中已经有abcdf,
这个时候如果执行以下这段代码,fos.txt中就只有十行hello而没有abcdf了,因为这是从头重新写入了

public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        FileOutputStream fos=new FileOutputStream("ieda_test\\src\\IO\\fos.txt");

        //写数据
        for (int i=0;i<10;i++){
            fos.write("hello\n".getBytes());
        }

        //释放资源
        fos.close();
    }

要实现不改变之前的内容,从abcdef后面开始写入就只需要在创建 FileOutputStream fos对象的时候,在后面加一个true。

FileOutputStream fos=new FileOutputStream("ieda_test\\src\\IO\\fos.txt",true);

执行结果;
在这里插入图片描述

字节流写数据加异常处理

public static void main(String[] args) {
        try{
            //创建字节输出流对象
            FileOutputStream fos=new FileOutputStream("ieda_test\\src\\IO\\fos.txt",true);

            //写数据
            for (int i=0;i<10;i++){
                fos.write("hello\n".getBytes());
            }

            //释放资源
            fos.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

像这样就完成了最基础的异常处理,但是这样的话,如果在write的过程中出现了IOException的异常,程序进入catch中就无法执行close释放资源操作了。所以为了避免出现这种情况,try,catch还有另外一个finally操作。

finally:在异常处理时提供finally块来执行所有清除操作。比如说IO流中的释放资源
特点:被finally控制的语句-定会执行,除非JVM退出。
在这里插入图片描述


```java
public class IODemo04 {
    public static void main(String[] args) {
        FileOutputStream fos = null;//为什么这里要声明在外面,并且赋初值null呢? 因为finally里获取不到try里面声明的fos,所以需要先声明在外面;并且为了防止fos没有被初始化,所以要先赋值一个null。
        try{
            //创建字节输出流对象
            fos=new FileOutputStream("ieda_test\\src\\IO\\fos.txt",true);

            //写数据
            for (int i=0;i<10;i++){
                fos.write("hello\n".getBytes());
            }

            //释放资源
            fos.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在这里插入图片描述

 public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fis=new FileInputStream("ieda_test\\src\\IO\\fos.txt");

        //读取数据
        int by=fis.read();
        System.out.println(by);
        System.out.println((char)by);
    }

fis.read()读取fis文件的第一个字符,输出是以字符的ascii码输出的
输出结果:
在这里插入图片描述
这是只读取一次的情况,如果读取多次呢?

public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        FileInputStream fis=new FileInputStream("ieda_test\\src\\IO\\fos.txt");

        //读取数据
        int by=fis.read();
        System.out.println(by);
        System.out.println((char)by);

        by=fis.read();
        System.out.println(by);
        System.out.println((char)by);

        by=fis.read();
        System.out.println(by);
        System.out.println((char)by);

        by=fis.read();
        System.out.println(by);
        System.out.println((char)by);
    }

执行结果:
在这里插入图片描述
如果执行到了最后一个字符会返回什么呢?
返回-1
所以返回-1的时候就是读取完成的意思,可以以此为条件结束读取。

while(by!=-1){xxx}

一次读取多个字符

public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("ieda_test\\src\\IO\\fos.txt");

        byte[] bys=new byte[5];//一次读取5个字符数组
        fis.read(bys);
        System.out.println(new String(bys));

        bys=new byte[5];//一次读取5个字符数组
        fis.read(bys);
        System.out.println(new String(bys));

        bys=new byte[5];//一次读取5个字符数组
        fis.read(bys);
        System.out.println(new String(bys));


        fis.close();
    }

但需要注意:在**分段读取(比如一次读5个,多次读入)**的时候,换行符之类的符号也会作为一个字符读入。
如:/r/n读为两个字符
并且在这里,如果剩下可供读入的不足5个字符了,那么bys中只会将新读入的前几个替换掉,后面的不会变。
在这里插入图片描述一次读入的话就不会出现这种情况。

public class IOInputDemo02 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("ieda_test\\src\\IO\\fos.txt");

        byte[] bys=new byte[1024];//一次读取5个字符数组

        int len;
        while((len=fis.read(bys))!=-1){
            System.out.println(new String(bys,0,len));
        }
        
        fis.close();
    }
}
执行结果:
hello
world

在这里插入图片描述

public class CopyTxtDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("ieda_test\\src\\IO\\fos.txt");
        FileOutputStream fos=new FileOutputStream("ieda_test\\src\\IO\\copyFos.txt");

        int by;
        while ((by=fis.read())!=-1){
            fos.write(by);
        }

        fis.close();
        fos.close();

    }
}

注意:每次使用完IO后都要释放资源。

在这里插入图片描述

package IO;

import java.io.*;

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

        FileInputStream fis=new FileInputStream("ieda_test\\src\\IO\\ddd.jpg");

        FileOutputStream fos=new FileOutputStream("ieda_test\\src\\IO\\img_copy.jpg");

        int len;
        byte[]  bys=new byte[1024];
        while ((len=fis.read(bys))!=-1){
            fos.write(bys,0,len);
        }

        fos.close();
        fis.close();
    }
}

在这里插入图片描述

字节缓冲流

在这里插入图片描述

字节缓冲流和之前的字节流的区别:

字节缓冲流在使用的时候向底会输出流或入字节,而不必为写入的每个字节导致底层系统的调用。所以他的效率会更好一些。

字符流

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值