【Java基础】IO流

本文详细介绍了Java中的IO流,包括字节流FileInputStream和FileOutputStream的单个字节和多个字节读取,字符流FileReader和FileWriter的单个字符和多个字符读写,以及处理流BufferedReader和PrintWriter的高效读写操作。此外,还提到了序列化机制和标准输入输出流的概念。
摘要由CSDN通过智能技术生成

IO流

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

最后一定要关闭流,防止资源泄露

字节流

一次读取1字节,8比特

FileInputStream



import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

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

    }
    //单个字节的读取
    @Test
    public void test1() throws IOException{
        FileInputStream in = null;
        FileOutputStream out = null;
        String path="src\\single\\in.txt";
        String dpath="src\\single\\out.txt";
        try {
            in = new FileInputStream(path);
            //String,boolean true追加;false覆盖,默认
            out = new FileOutputStream(dpath,true);
            int datacode;
            //read()一次读取一个字节,返回读取字节的ASCII码,返回-1,表示读取完毕
            while ((datacode = in.read()) != -1) {
                System.out.println(datacode);//输出ASCII码 例如  a 是97 ;一个汉字是3个字节
                System.out.println((char)datacode);
                out.write(datacode);
            }

        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
    @Test
    public void test2() throws IOException{
        FileInputStream in = null;
        FileOutputStream out = null;
        String path="src\\single\\in.txt";
        String dpath="src\\single\\out.txt";
        try {
            in = new FileInputStream(path);
            out = new FileOutputStream(dpath);
            //一次读取多个字节,返回读取字节的长度
            byte[] buf=new byte[2];
            int datalen=0;
            while((datalen=in.read(buf))!=-1){
                System.out.println(datalen);
                System.out.println(new String(buf,0,datalen));
                out.write(buf,0,datalen);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

字符流

FileReader

package file;

import org.junit.jupiter.api.Test;

import java.io.*;

public class FileReader_ {
    public static void main(String[] args) {
    }
    //单个字符
    @Test
    public void readFile01() {
        String filePath = "src\\file\\in.txt";
        String dPath="src\\file\\out.txt";
        FileReader fileReader = null;
        FileWriter fileWriter=null;
        int datacode = 0;
        //1. 创建 FileReader 对象
        try {
            fileReader = new FileReader(filePath);
            fileWriter=new FileWriter(dPath);
            //循环读取 使用 read, 单个字符读取
            while ((datacode = fileReader.read()) != -1) {
                System.out.print(datacode);
                System.out.println((char) datacode);
                fileWriter.write(datacode);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
                if(fileWriter!=null){
                    //这里一定要关闭,才会写入  或者flush   
                    //close 等价于  flush + close
                    //底层还是字节流
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void readFile02() {
        String filePath = "src\\file\\in.txt";
        String dPath="src\\file\\out.txt";
        FileReader fileReader = null;
        FileWriter fileWriter=null;

        int readLen = 0;
        char[] buf = new char[8];
        //1. 创建 FileReader 对象
        try {
            fileReader = new FileReader(filePath);
            fileWriter=new FileWriter(dPath,true);
            //循环读取 使用 read(buf), 返回的是实际读取到的字符数
            //如果返回-1, 说明到文件结束
            while ((readLen = fileReader.read(buf)) != -1) {
                System.out.print(new String(buf, 0, readLen));
                fileWriter.write(buf,0,readLen);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
                if(fileWriter!=null){
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

处理流

BufferedReader

在这里插入图片描述

在这里插入图片描述

处理流以节点流为基础,提供了更加强大的功能

package file;

import java.io.*;

/**
 * @author 韩顺平
 * @version 1.0
 * 演示 bufferedReader 使用
 */
public class BufferedReader_ {
    public static void main(String[] args)  {
        String filePath = "src\\file\\in.txt";
        String dPath="src\\file\\out.txt";
        //创建 bufferedReader
        BufferedReader bufferedReader =null; 
        BufferedWriter bufferedWriter=null;
        try {
            bufferedReader=new BufferedReader(new FileReader(filePath));
            bufferedWriter=new BufferedWriter(new FileWriter(dPath));
            //读取
            String line; //按行读取, 效率高
            //说明
            //1. bufferedReader.readLine() 是按行读取文件
            //2. 当返回 null 时,表示文件读取完毕
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
                bufferedWriter.write(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            
                //关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流
                try {
                    if(bufferedReader!=null) {
                        bufferedReader.close();
                    }
                    if(bufferedWriter!=null){
                        bufferedWriter.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            

        }
       

    }
}

打印流

PrintWriter

也是一种处理流

打印流只有输出流,没有输入流

打印到显示器或文件

PrintStream out = System.out;
//在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
/*
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
*/
out.print("john, hello");
//因为 print 底层使用的是 write , 所以我们可以直接调用 write 进行打印/输出
out.write("韩顺平,你好".getBytes());

//我们可以去修改打印流输出的位置/设备
//1. 输出修改成到 "e:\\f1.txt"
//2. "hello, 韩顺平教育~" 就会输出到 e:\f1.txt
//3. public static void setOut(PrintStream out) {
// checkIO();
// setOut0(out); // native 方法,修改了 out
// }
System.setOut(new PrintStream("e:\\f1.txt"));
System.out.println("hello, 韩顺平教育~");

out.close();//flush + 关闭流, 才会将数据写入到文件.

标准输入输出流

System.in
System.out

System.in System.out System.err
程序启动时创建,退出时关闭。
不需要程序员关闭

package single;

import org.junit.jupiter.api.Test;

import java.util.Scanner;

public class TestClass {
    public static void main(String[] args) {

    }

    @Test
    public void test1(){
        Scanner scanner = new Scanner(System.in);
        /*
        System.in
        System 的public final static InputStream in = null;
        编译类型InputStream
        运行类型BufferedInputStream
        标准输入是键盘
        */

        System.out.println();
        /*
        System.out
         System 的 public final static PrintStream out = null;
         编译类型PrintStream
         运行类型PrintStream
         标准输出是屏幕
         */

    }

}

ObjectOutputStream

对象处理流

序列化
是将对象的状态信息转换为可以存储或传输的二进制形式的过程。
就是在保存数据的时候,保存数据的值和数据类型
反序列化
将在序列化过程中所生成的二进制字节流的过程转换成数据结构或者对象的过程
就是在恢复数据的时候,恢复数据的值和数据类型

需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

  • Serializable //这是一个标记接口(没有方法),推荐
  • Externalizable //有方法,他也实现了Serializable
@Test

public void objectoutputstream() throws Exception{

    //序列化后的文本格式,是按他自己的方式

    String path="D:\\IDEA_file\\Learn_8\\src\\file\\Files\\file5.dat";

    ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(path));

    oos.write(100);//int->Integer,实现了Serializable

    oos.writeBoolean(false);//boolean->Boolean,实现了Serializable

    oos.writeChar('7');//char->Character,实现了Serializable

    oos.writeDouble(9.8);//double->Double,实现了Serializable

    oos.writeUTF("china");//String,实现了Serializable

    oos.writeObject(new Dog("wnag",19));

    //关闭流

    oos.close();

}

}

//要想数据可序列化,必须继承Serializable

class Dog implements Serializable {

String name;

int age ;

public Dog(String name, int age) {

    this.name = name;

    this.age = age;

}

}

如果有些字段不想进行序列化,

对于不想进行序列化的变量,使用 transient 关键字修饰。

transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。

关于 transient 还有几点注意:

  • transient 只能修饰变量,不能修饰类和方法。
  • transient 修饰的变量,在反序列化后变量值将会被置成类型的默认值。例如,如果是修饰 int 类型,那么反序列后结果就是 0
  • static 变量因为不属于任何对象(Object),所以无论有没有 transient 关键字修饰,均不会被序列化。
serialVersion

序列化运行时与每个可序列化类关联一个版本号(称为 serialVersionUID),该版本号在反序列化期间用于验证序列化对象的发送方和接收方是否已加载与序列化兼容的类。如果接收方为对象加载了一个类,该类的串行版本UID与相应发送方的类的类不同,则反序列化将导致无效类异常,可序列化类可以通过声明一个名为 的字段来显式声明自己的串行VersionUID,该字段必须是静态的、最终的和类型:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
不能被继承

转换流

inputStremReader

把字节流转换成字符流

字节流可以指定编码格式,可以处理中文乱码等情况

public class InputStreamReader_ {
public static void main(String[] args) throws IOException {
String filePath = "e:\\a.txt";
//解读
//1. 把 FileInputStream 转成 InputStreamReade
//2. 指定编码 gbk
//InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
//3. 把 InputStreamReader 传入 BufferedReader
//BufferedReader br = new BufferedReader(isr);
//将 2 和 3 合在一起
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(filePath), "gbk"));
//4. 读取
String s = br.readLine();
System.out.println("读取内容=" + s);
//5. 关闭外层流
br.close();
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值