2021-09-15

1. I/O系统

I/O:
输入输出,其实就是一套API,通过它可以从硬盘、网络、键盘等地方读取数据,也可以将内容写入到硬盘、网络、屏幕等地方。

I/O是程序获取和交换数据的主要渠道,I/O很容易成为性能瓶颈。

Java在I/O上一直在做持续的优化,1.4开始引入了非阻塞I0(NIO,其实网络IO是同步非阻塞的,文件IO依旧是同步阻塞的),1.7引入了异步IO(AIO)

  • IO

    同步阻塞的BIO

    BIO是面向流的、阻塞式的、串行的一个过程。

    阻塞是线程的一种状态,当线程执行了IO相关的读写方法后,在操作系统处理IO前,当前线程是否可以继续向下执行。
    (比如:程序请求资源时主线程会停下来,此时即为阻塞状态。)

    同步是指线程是否需要主动的去获取读写的结果。
    (当线程为阻塞状态时,程序会等待资源的响应。)

    不管是磁盘I/O还是网络I/O数据在写入OutputStream或者从InputStream读取时都有可能会发生阻塞,一旦有线程阻塞将会失去CPU的使用权,而且线程占用的资源不能被释放,大量浪费了CPU和线程占用的内存资源。

  • NIO:

    同步非阻塞的NIO

    BIO中的阻塞是指当需要有20个资源请求时,需要有对应的20个线程;非阻塞是指资源请求时主线程不会停下来,而是当有响应时来调用一个方法

常用工具类

1)File

​ 对文件或目录进行一系列描述或者操作以及读取文件的属性(即是否存在)。

//小括号中的路径可以是相对路径也可以是绝对路径
File file = new File("f:/test.txt"|"test.txt");

相关方法

getName				获取文件名
createNewFile		新建文件
delete				删除文件
length				文件大小
2)Path

​ 表示、解析文件或目录的路径。

​ Path是一个接口。

//小括号中的路径可以是相对路径也可以是绝对路径。
Path path = Paths.get("f:/test.txt"|"test.txt");
3)Files

​ 对文件或目录进行一系列操作,读取文件的属性以及读写文件内容。

//判断是否是可执行文件,如.exe
Files.isExecutable(path);

2. IO流

流是一组有序的、有起点和终点的字节集合,是对数据传输的总称或抽象。

分类
  • 流向分:输入流、输出流

  • 功能分:节点流、处理流

  • 单位分:字节流、字符流

字节输入流
InputStream

​ 该抽象类是表示字节输入流的所有类的超类。

​ 读取方法有read

​ 使用完需要用close方法

FileInputStream

​ 关于读取文件的一个类,可以从文件系统中的某个文件中获得原始字节流。

//只负责提供字节数据
FileInputStream in = new FileInputStream(path);

int content = 0;

//此时用do while循环结构是最合适的
try{
	do{
  	  content = in.read();	//通过read方法返回字节,-1表示读取结束
	}while(content!=-1);    
}finally{
    //保证资源一定会被关闭
    in.close();
}
字节输出流
OutputStream

​ 该抽象类是表示输出字节流的所有类的超类;

FileOutputStream

​ 关于写出字节流文件的一个类。

示例:

//使用字节流写入一个文件
OutputStream out = new FileOutputStream("d:/demos.txt",true);//true表示追加写入

String content = "你好";

out.write(content.getBytes("utf-8"));
out.flush();
out.close();
字符输入流

如果读取的是字节文件,则需要用二进制流,即字节输入/输出流(InputStream、OutputStream)

如果读取的是字符文件,就可以直接使用字符流,如Writer

Reader
InputStreamReader(适配器模式)

​ 是字节流通向字符流的桥梁,可以使用指定的字符编码将字节文件解码为对应的字符

FileReader
BufferedReader
//InputStreamReader可以指定字符编码
Reader reader = new InputStreamReader(new FileInputStream,charset);

//FileReader默认字符编码,打印的是Unicode字符编号
FileReader fileReader = new FileReader(fileName);

//BufferedReader
BufferedReader bur = new BufferedReader(new FileReader(fileName));
BufferedReader bur = new BufferedReader(new InputStreamReader(new FileInputStream(fileName));

获取默认字符编码

Charset.defaultCharset().name()
字符输出流
Writer

​ 写入字符流的抽象类

OutputStreamWriter

适配器模式,是字符流通向字节流的桥梁,可以使用指定的charset将要写入流中的字符编码成字节

FileWriter

​ 用于写入字符文件的便捷类

BufferedWriter

​ 缓冲流,装饰者模式

PrintWriter

​ 是一种过滤流,也叫处理流,可以对字节流和字符流进行处理,

​ 可以在传入Writer时指定字符编码

public class Sample {
    public static void main(String[] args) throws IOException{
        //可以在传入Writer时指定字符编码,true表示刷新缓存
        PrintWriter writer = 
            new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath),utf-8)),true);
        
        //不换行不刷新缓存
        writer.print("不换行不刷新");
        
        //换行刷新缓存
        writer.println("换行刷新");
    }
}

示例:

1.字节流复制文件

public static void copy1() throws IOException{
  //1.创建字节文件输入流、输出流
    InputStream in = new FileInputStream(infilepath);
    OutputStream out = new FileOutputStream(outfilePath)''

 //2.读、写
   byte[] buf = new byte[1024*4];		//4g
   int length = 0;
   while((length=in.read(buf)!=-1){
      //buf缓冲区,0指从第一个位置写,length是写的长度
       out.write(buf,0,length);
   }
         
 //3.关闭
    in.close();
    out.close();
}

2.字符流复制文件

public static void copy2(){
    //1.创建字符文件的输入流、输出流
    Reader reader = new FileReader(readFilePath);
    Writer writer = new FileWriter(writeFilePath);
    
    //2.读写
    char[] buf = new char[1024*4];
    int length = 0;
    while((length=reader.read(buf)!=-1){
        writer.write(buf,0,length);
    }
          
    //3.关闭
    reader.close();
    writer.flush();//刷新
    writer.close();
}
字节流和字符流的区别

字节流读取二进制数据文件,其实是可以读取任何形式的文件。

字符流读取字符文件,可以多行读取。

对象流

ObjectInputStream:对象输入流;(反序列化)

ObjectOutputStream:对象输出流;(序列化)

对象序列化

是指将内存中的对象转换为可以输出的二进制格式,主要用于对象传输和对象持久化,这个过程的逆向操作称为反序列化。

注意:

​ 序列化的对象所属的类必须实现Serializable接口

​ 序列化会传递一个序列化ID,在反序列化时会对比两个序列化ID如果不一致则不会进行按序列化操作。

示例:

class Demo{
    
    public static void main(String[] args){
        method();
        method2();
    }
    
    
     //通过ObjectInputStream进行反序列化
    public static void readPerson(){
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
     	Person person = (Person)ois.readObject();
    }
 
   
    //通过ObjectOutputStream进行序列化
    public static void writePerson(){
    	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path);
   	 	oos.writeObject(new Person());
}
}

//该类需要实现Serializable接口
class Person implements Serializable{
    private static int age = 100;
    private static String name = null;
    
    public Person(int age,String name){
        this.age = age;
        this.name = name;
    }
}


过滤流

装饰者模式

过滤输入流BufferedInputStream

示例:使用缓存输入流读取二进制数据

/**
 *  如果不使用缓冲流,则每次调用read方法都会从硬盘中读取数据,
 *  而使用了缓冲流则会 一次性读取8921个字节放入缓存,read方法只是在获取缓存中的数据
 *  缓存数据不够时才回去硬盘中读取数据
 * */
public class Sample1{
    public static void readForByte() throws IOException {
        BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("filePath"));
        int content = 0;
        do {
          content =   inputStream.read();
          //转换为字节
            System.out.println(Integer.toBinaryString(content));
        } while (content != -1);

    }
}
 
过滤输出流BufferedOutputStream
public class Sample2{
    public static void readForByte() throws IOException {      
		//true表示是内容否追加
        BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("filePath",true));
        //转为字节,且字符编码为utf-8
        outputStream.write("需要写出的内容".getBytes(StandardCharsets.UTF_8));
        //刷新
        outputStream.flush();
        //关闭
        outputStream.close();
字符缓冲流
BufferedReader
public class Sample3{
    public static void readForByte() throws IOException {       
		BufferedReader reader = new BufferedReader(new FileReader("filePath"));
        String contents = null;
        do {
            contents = reader.readLine();
        } while (contents != null);
    }
}
BufferedWrier
public class Sample3{
    public static void readForByte() throws IOException {       
	   BufferedWriter writer =  new BufferedWriter(new FileWriter("filePath"));
       writer.write("需要写出的内容");
       //刷新、关闭
       writer.flush();
       writer.close();
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值