JavaSE(九)I/O流

本文详细介绍了Java中的I/O流,包括字符流、字节流、缓冲流、转换流、数据流、标准输出流、System类、File类、序列化与反序列化,并给出了实例代码。此外,还提及了NIO的基本概念,但未展开详细讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaSE(九)I/O流



提示:以下是本篇文章正文内容,下面案例可供参考

一、I/O

I/O理解
所有流都实现了Closeable接口,都是可关闭的,都有close()方法
所有输出流都实现来Flushable接口,都是可刷新的,都有flush()方法,清空管道(管道数据强行写入)

图示:
请添加图片描述
常用流

		//文件专属
        java.io.FileInputStream
        java.io.FileOutputStream
        java.io.FileReader
        java.io.FileWriter
                
        //转换流(字节流转换成字符流)        
        java.io.InputStreamReader
        java.io.OutputStreamWriter
                
        //缓冲流           
        java.io.BufferedReader
        java.io..BufferedWriter
        java.io.BufferedOutputStream
        java.io.BufferedInputStream
                
        //数据流专属
        java.io.DataInputStream
        java.io.DataOutputStream
        
        //标准输出打印流        
        java.io.PrintWriter
        java.io.PrintStream
          
        //对象专属流        
        java.io.ObjectInputStream
        java.io.ObjectOutputStream 

1.字符流

(1)FileReader

使用:

			reader = new FileReader("./JavaSE/src/jjwb.txt");
//            int data = reader.read();//20013    中
            char[] chars = new char[4];
            int readCount = 0;
            while((readCount = reader.read(chars)) != -1){
                System.out.println(new String(chars,0,readCount));
            }

(2)FileWriter

使用:

		    writer = new FileWriter("./JavaSE/src/jjwb.txt",true);
            char[] chars = {'\t','我','是','中','国','人'};
            writer.write(chars);
            writer.write(chars,3,3);
            writer.write("小江江");
            writer.flush();

(3)字符流文件复制

使用:

			reader = new FileReader("./JavaSE/src/jjwb.txt");
            writer = new FileWriter("./JavaSE/src/newjjwb.txt",true);
            char[] chars = new char[1024 * 512];
            int readCount = 0;
            while((readCount = reader.read(chars)) != -1){
                writer.write(chars,0,readCount);
            }
            writer.flush();  //刷新管道

2.字节流

(1)FileInputStream

常用方法:
	1.read()每次读取一个字节,放回读取到的字节的码,读到文件末尾时返回-1
	2.read(byte[])每次读入到byte数组里,返回读取到的字节数量,一个都没读到时返回-1
	3.available()返回流中剩下还未读取的字节数量。new byte[fis.available()],适用于x小文件
	4.skip()跳过几个字节不读

IDEA中当前路径是工程的根

使用基本架构:

public class Test{
    public static void main(String[] args){
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("./JavaSE/src/jjwb.txt");
            byte[] bytes = new byte[4];
            int readCount = 0;
            while((readCount = fis.read(bytes)) != -1){
                System.out.print(new String(bytes,0,readCount));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if (fis != null) {
                try {
                    fis.close();        //关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

(2)FileOutputStream

基本代码:

		FileOutputStream fos = null;
        try {                                                             //true    追加写入
            fos = new FileOutputStream("./JavaSE/src/jjwb.txt",true);        //  文件不存时会自动创建
           byte[] data = {97,98,99,100,101};
           fos.write(data);
            fos.flush();        //刷新
        }

(3)字节流文件复制

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

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("./JavaSE/src/jjwb.txt");     //true    追加写入
            fos = new FileOutputStream("./JavaSE/src/newjjwb.txt",true);        //  文件不存时会自动创建
            byte[] bytes = new byte[1024 * 1024];
            int readCount = 0;
            while((readCount = fis.read(bytes)) != -1){
                fos.write(bytes,0,readCount);
            }
            fos.flush();        //刷新
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            //分开try 否则其中一个出现异常会影响另一个流的关闭
            if (fis != null) {
                try {
                    fis.close();        //关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();        //关闭流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.缓冲流与转换流

自带缓冲区,传入的流叫做节点流,外部的流叫做包装流,关闭时只需要关闭包装流(节点流也在源码中关闭了):

在这里插入图片描述

方法:
	1.readLIne() 不带最后的换行符,到达文件末尾时,返回null

使用:

public class Test{
    public static void main(String[] args){
        BufferedReader br= null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream("./JavaSE/src/jjwb.txt")));
            String str;
            while ((str = br.readLine()) != null){
                System.out.println(str);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4.数据流

可以将数据连同数据类型写入文件,所以这个文件不是普通文本,读写顺序要相同才能读
	try {
            dos = new DataOutputStream(new FileOutputStream("./JavaSE/src/data"));
            dis = new DataInputStream(new FileInputStream("./JavaSE/src/data"));
            byte b = 100;
            boolean sex = false;
            char c = 'a';
            dos.writeByte(b);
            dos.writeBoolean(sex);
            dos.writeChar(c);
            dos.flush();
            byte nb = dis.readByte();
            boolean nsex = dis.readBoolean();
            char nc = dis.readChar();
            System.out.println(nb);
            System.out.println(nsex);
            System.out.println(c);
        }

5.标准输出流

使用:

	public static void main(String[] args){
        System.out.println("hello world");

        PrintStream ps = System.out;   // 返回PrintStream   //标准的字节输出流,默认输出到控制台
        ps.println("hello ");           //  标准输出流不需要手动关闭
        PrintStream printStream = null;
        try{
            printStream= new PrintStream(new FileOutputStream("./JavaSE/src/log",true));
            System.setOut(printStream);  //修改输出方向
            System.out.println("今天又胖了");
            System.out.println("西瓜味的胖子");
            System.out.println("逗逼金鱼");
        }catch (IOException e){
            e.printStackTrace();
        }

    }

6.System类

常用方法:
	1.System.gc()
	2.System.currentTimeMillis()
	3.PrintStream ps = System.out
	4.System.exit(0)
	5.System.arrayCopy()

7.File类

文件和目录路径名的抽象表示形式
常用方法:
	1.exists()	判断文件是否存在
	2.f.createNewFile();  	以文件的方式创建
	3.mkdir()		 mkdirs()	以目录[多重目录]	的方式创建
	4.getParent()  getParentFile()    获取父路径[父文件对象]
	5.getAbsolutePath() 		获取绝对路径
	6.getName()		
	7.isDirectory() isFile()
	8.lastModified()   返回最后一次文件修改时间(时间戳)
	9.length() 获取文件大小
	10.listFiles()		获取当目录下的所有子文件对象(数组)

使用:

		File f = new File("D:\\IE down\\newfile");
        PrintStream ps = new PrintStream(new FileOutputStream("./JavaSE/src/consoleLog"));
        System.setOut(ps);
        System.out.println(f.exists());
        System.out.println(f.getName());
        System.out.println(f.getParent());
        System.out.println(f.getParentFile().getAbsolutePath());

8.序列化与反序列化

参与序列化的对象必须实现Serializable(标志接口)接口,被transient(游离的)关键字修饰的属性不参与序列化,JVM会默认提供序列化版本号
建议给手动写固定不变的序列化版本号

理解图:
请添加图片描述
序列化:

 		Student s = new Student(111,"xiaojiang");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("./JavaSE/src/students"));
        oos.writeObject(s);
        oos.flush();
        oos.close();

反序列化:

	   ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./JavaSE/src/students"));
       Object obj = ois.readObject();
       System.setOut(new PrintStream(new FileOutputStream("./JavaSE/src/consoleLog")));
       System.out.println(obj.toString());

序列化多个对象:
将多个对象放入集合中,参与序列化的集合与集合中的元素都需要实现Serializable接口

List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(101,"xiaojiang"));
        studentList.add(new Student(102,"xiaoliu"));
        studentList.add(new Student(103,"xiaohua"));
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("./JavaSE/src/students"));
        oos.writeObject(studentList);
        oos.flush();
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./JavaSE/src/students"));
        for(Student s : (List<Student>)ois.readObject()){
            System.out.println(s.toString());
        }
//        System.out.println(obj instanceof List);   //true
        ois.close();

类区分:
类名,序列化版本号
将该类序列化后,修改了源代码,如果由JVM虚拟机默认生成序列化版本号,将认为这是两个不同的类,不能再反序列化,所以凡是实现了Serializable接口的类,建议给手动写固定不变的序列化版本号;jvm虚拟机才认为时同一个类

    private static final long serialVersionUID = 8678952581122892189L;
//Exception in thread "main" java.io.
// InvalidClassException: Student;
// local class incompatible: stream classdesc serialVersionUID = 8678952581122892189,
// local class serialVersionUID = -4554816821284592035

    private int no;
    private String name;
    private int age;  //<-----修改处

9.I/O与Properties联合使用

属性配置文件建议以.properties后缀结尾

userinfo文件:
在这里插入图片描述

实现:

 	FileReader reader = new FileReader("./JavaSE/src/userinfo");
        Properties pro = new Properties();
        //调用Properties对象的load()方法,将文件中的数据加载到Map集合中
        pro.load(reader);
        for(Map.Entry node: pro.entrySet()){
            System.out.println(node.getKey() + " ==> " + node.getValue());
        }

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

二、NIO

1.待写



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值