当前位置: 首页 > news >正文

Java IO流详解

Java IO流详解

个人主页:https://blog.csdn.net/hello_list
今天我们来学习下java中的io部分

首先我们要知道io指的是什么,输入输出,就是输入输出流,我们在知道就是流又分为两个,输入流和输出流,再从单位上分,又分为字符流和字节流

  • 字节流:以字节为单位,可以读取任何数据
  • 字符流:以字符为单位,只能读写文本数据

再按功能,又分为节点流和过滤流

  • 节点流:具有实际传输数据的读写功能
  • 过滤流:在节点流的基础上增强功能

字节输入输出流

InputStream常用方法

intavailable() 返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
voidclose() 关闭此输入流并释放与流相关联的任何系统资源。
voidmark(int readlimit) 标记此输入流中的当前位置。
booleanmarkSupported() 测试这个输入流是否支持 markreset方法。
abstract intread() 从输入流读取数据的下一个字节。
intread(byte[] b) 从输入流读取一些字节数,并将它们存储到缓冲区 b
intread(byte[] b, int off, int len) 从输入流读取最多 len字节的数据到一个字节数组。
voidreset() 将此流重新定位到上次在此输入流上调用 mark方法时的位置。
longskip(long n) 跳过并丢弃来自此输入流的 n字节数据。

OutputStream常用方法

voidclose() 关闭此输出流并释放与此流相关联的任何系统资源。
voidflush() 刷新此输出流并强制任何缓冲的输出字节被写出。
voidwrite(byte[] b)b.length字节从指定的字节数组写入此输出流。
voidwrite(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
abstract write(int b) 将指定的字节写入此输出流

我们最常用的是实现他们的子类,FileInputStream和FileOutputStream,我们做一个简单的应用

我们首先用FileOutputStream创建一个文件并写入内容

public class FileOutputStreamTest {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("E://hello.txt");
        fileOutputStream.write("hello".getBytes());
        // 刷新磁盘空间
        fileOutputStream.flush();
        // 关闭字节流
        fileOutputStream.close();
        System.out.println("文件写入成功");
    }
}

效果

在这里插入图片描述

FileInputStream读取文件

public class FileInputStreamTest {
    public static void main(String[] args) throws Exception {
        File file = new File("E:\\hello.txt");
//        System.out.println(file.exists());
//        BufferedReader fis = new BufferedReader(new InputStreamReader(System.in));
        FileInputStream fis = new FileInputStream(file);
        int count = -1;
        byte[] buff = new byte[1024];
        while ((count = fis.read(buff)) != -1) {
            System.out.println(new String(buff, 0, count,"UTF-8"));
        }
        fis.close();
    }
}

字节缓冲流

我们还可以使用具有缓存效果的字节流:BufferedInputStream和BufferedOutputStream,具有缓存,可以提高效率

BufferedOutputStream读取文件

public class BufferedOutputStreamTest {
    public static void main(String[] args) throws Exception {
        // 1、创建流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E://hello.txt"));
        // 2、写入文件内容
        bos.write("hello,我是学习日记".getBytes());
        // 3、刷新磁盘,关闭流
        bos.flush();
        bos.close();
        System.out.println("写入文件完成");
    }
}

在这里插入图片描述

BufferedInputStream读取文件

public class BufferedInputStreamTest01 {
    public static void main(String[] args) throws Exception {
    // 1、创建流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E://hello.txt"));
        int len = -1;
        byte[] buffer = new byte[1024];
        // 2、通过流读取内容
        while ((len=bis.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len,"UTF-8"));
        }
        // 3、关闭流
        bis.close();
    }
}

对象流

我们还可以使用对象流创建和保存对象:ObjectOutputStream和ObjectInputStream

使用ObjectOutputStream保存对象

我们首先创建一个student学生类

package com.xuexi.io;


import java.io.Serializable;

// 必须实现序列化接口
public class Student implements Serializable {
    String name;
    Integer age;

    @Override
    public String toString() {
        return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

通过对象流可以保存对象持久化

public class ObjectOutputStreamTest {
    public static void main(String[] args) throws Exception {
        Student xuexi = new Student("学习日记", 18);
        // 1、创建流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\hello.txt"));
        // 2、写入内容
        oos.writeObject(xuexi);
        // 3、关闭流 close的时候会自动进行flush操作
        oos.flush();
        oos.close();
        System.out.println("保存对象成功");
    }
}

我们可以看下保存的对象是什么样子,其实可以看出来,就是我们保存的样子

在这里插入图片描述

还可以使用ObjectInputStream读取对象,反序列化

public class ObjectInputStreamTest {
    public static void main(String[] args) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\hello.txt"));
        Student xuexi = (Student)ois.readObject();
        ois.close();
        System.out.println(xuexi);
    }
}

可以看到读取成功对象,这样也是创建对象的一种方式

在这里插入图片描述

字符流

Reader和Writer这里两大接口

其实跟之前的字节流一样,我们可以直接使用FileReader和FileWriter

FileWriter写入文件

public class FileWriterTest {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("E:\\hello.txt");
        fw.write("hello,我是学习日记");
        fw.flush();
        fw.close();
        System.out.println("写入文件成功");
    }
}

FileReader读取文件

public class FileReaderTest {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("E:\\hello.txt");
        int len = -1;
        char[] buffer = new char[1024];
        while ((len = fr.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len));
        }
        fr.close();
    }
}

字符缓冲流

同样我们肯定还有具有缓冲效果的字符缓冲流,可以提高读写效率:BufferedReader和BufferedWriter

BufferedWriter写入文件

public class BufferedWriterTest {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\hello.txt"));
        bw.write("hello,我是学习日记");
        bw.flush();
        bw.close();
        System.out.println("文件写入完毕");
    }
}

BufferedReader读取文件

public class BufferedReaderTest {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("E:\\hello.txt"));
        int len = -1;
        char[] buffer = new char[1024];
        while ((len = br.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len));
        }
        br.close();
    }
}

字符编码

  • ISO-8859-1收录除了ASCII外,还包括西欧、希腊语、泰语、阿拉伯语等对应的文字符号;

  • UTF-8:针对Unicode码表的可变长度字符编码

  • GB2312:简体中文

  • GBK:简体中文,扩充

  • BIG5台湾,繁体中文

打印流PrintWriter

PrintWriter顾名思义 打印流,支持数据原样直接打印,并且封装了print和println支持写入后换行

public class PrintWriterTest {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter pw = new PrintWriter("D:\\hello.txt");
        pw.println(12);
        pw.println(false);
        pw.println(123.123);
        pw.println('a');
        pw.println("hello,我是学习日记");
        pw.close();
        System.out.println("文件写入完成");
    }
}

我们可以看下写入内容

在这里插入图片描述

转换流

我们知道字符流比字节流更大,那我们也可以讲字节流转换位字符流,同时可以设置字符编码格式

我们就需要用到转换流:InputStreamReader和OutputStreamWriter

OutputStreamWriter字节流转换为字符流写入文件

public class OutputStreamWriterTest {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("E:\\hello.txt");
        OutputStreamWriter osr = new OutputStreamWriter(fos,"UTF-8");
        osr.write("hello,我是学习日记");
        osr.flush();
        osr.close();
        fos.close();
        System.out.println("文件写入成功");
    }
}

InputStreamReader读取文件

public class OutputStreamWriterTest {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("E:\\hello.txt");
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        int len = -1;
        char[] buffer = new char[1024];
        while ((len = isr.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len));
        }
        isr.close();
        fis.close();
    }
}

File文件

看下File文件的使用,我们在之前通过流创建文件的时候就直接写好了绝对路径地址,如果文件不存在就会自动创建文件,我们可以发现其实接口里面也是帮我们new了一个File文件
在这里插入图片描述

使用起来呢其实都很简单,调用一些方法,参数什么的,大家可以参考着API文档去使用就可以了

在这里插入图片描述

FileFilter

这里我们再提一个FileFilter过滤器接口,顾名思义可以用来做一些过滤的操作

public class FileFilterTest {
    public static void main(String[] args) {
        File file = new File("E:\\MarkDown");
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.getName().endsWith(".md"))
                    return true;
                return false;
            }
        });
        for (int i = 0; i < files.length; i++) {
            System.out.println(files[i]);
        }
    }
}

在这里插入图片描述

上手试一下,然后多看着api文档调用下,就可以了,很简单,不过一定要上手哦

ProPerties

properties其实就是属性集合,我们经常用来做配置文件

我们可以看下有哪些方法:

Modifier and TypeMethod and Description
StringgetProperty(String key) 使用此属性列表中指定的键搜索属性。
StringgetProperty(String key, String defaultValue) 使用此属性列表中指定的键搜索属性。
voidlist(PrintStream out) 将此属性列表打印到指定的输出流。
voidlist(PrintWriter out) 将此属性列表打印到指定的输出流。
voidload(InputStream inStream) 从输入字节流读取属性列表(键和元素对)。
voidload(Reader reader) 以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。
voidloadFromXML(InputStream in) 将指定输入流中的XML文档表示的所有属性加载到此属性表中。
EnumerationpropertyNames() 返回此属性列表中所有键的枚举,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。
voidsave(OutputStream out, String comments) 已弃用 如果在保存属性列表时发生I / O错误,此方法不会抛出IOException。 保存属性列表的store(OutputStream out, String comments)方法是通过store(OutputStream out, String comments)方法或storeToXML(OutputStream os, String comment)方法。
ObjectsetProperty(String key, String value) 致电 Hashtable方法 put
voidstore(OutputStream out, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法加载到 Properties表中的格式输出流。
voidstore(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式输出到输出字符流。
voidstoreToXML(OutputStream os, String comment) 发出表示此表中包含的所有属性的XML文档。
voidstoreToXML(OutputStream os, String comment, String encoding) 使用指定的编码发出表示此表中包含的所有属性的XML文档。
SetstringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。

这里我们简单使用下:

public class PropertiesTest {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        properties.setProperty("name","学习日记");
        properties.setProperty("age","18");
        System.out.println(properties);

        Set<String> strings = properties.stringPropertyNames();
        strings.forEach((e)->{
            System.out.println(e);
        });

        // 还可以和打印流结合使用
        PrintWriter pw = new PrintWriter("E:\\hello.txt");
        properties.list(pw);
        pw.close();
        System.out.println("properties持久化成功");

        // 还可以通过Store方法保存
        FileOutputStream fos = new FileOutputStream("E:\\hello.properties");
        properties.store(fos,"这是一个注释");
        fos.close();

        // 还有可以加载文件的load方法
        Properties properties1 = new Properties();
        FileInputStream fis = new FileInputStream("E:\\hello.properties");
        properties1.load(fis);
        fis.close();
        System.out.println(properties1);

    }
}

在这里插入图片描述

在这里插入图片描述

小结

都看到这里了还不点个关注三连吗,后面我们还会学习java Nio Bio等,bye~

相关文章:

  • 迷宫_Sarsa算法_边做边学深度强化学习:PyTorch程序设计实践(2)
  • iOS视频捕获入门篇
  • 数据可视化系列教程|六大组件基础知识
  • 《MySQL技术内幕:InnoDB存储引擎》学习笔记-第二章
  • 无线能量传输(WPT)中收发线圈的等效电路模型
  • 回归预测 | MATLAB实现BP神经网络多输入单输出回归预测
  • 新手入门:APP软件测试需要考虑哪些方面
  • .NET序列化 serializable,反序列化
  • 【源码+项目部署】Java课程设计项目_Java人力资源管理系统
  • 从云原生到数字原生,数字化转型背后的需求逻辑发生哪些变化?
  • 2022年最新宁夏水利水电施工安全员模拟试题题库及答案
  • 视频批注软件哪个好用 分秒帧在线批注怎么用
  • Express--获取URL中携带的查询参数、获取URL中的动态参数、获取URL中的动态参数
  • STM32和ESP32- 主讲esp
  • 新库上线 | CnOpenData房地产业工商注册企业基本信息数据
  •  D - 粉碎叛乱F - 其他起义
  • iOS 系统授权开发
  • javascript从右向左截取指定位数字符的3种方法
  • JS函数式编程 数组部分风格 ES6版
  • Mithril.js 入门介绍
  • node-glob通配符
  • opencv python Meanshift 和 Camshift
  • python 装饰器(一)
  • Python_网络编程
  • React 快速上手 - 07 前端路由 react-router
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 计算机在识别图像时“看到”了什么?
  • 每天一个设计模式之命令模式
  • 前端面试总结(at, md)
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 算法系列——算法入门之递归分而治之思想的实现
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 微信小程序--------语音识别(前端自己也能玩)
  • 小程序01:wepy框架整合iview webapp UI
  • 移动端唤起键盘时取消position:fixed定位
  • ​MySQL主从复制一致性检测
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (二)fiber的基本认识
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (一)Thymeleaf用法——Thymeleaf简介
  • **CI中自动类加载的用法总结
  • .“空心村”成因分析及解决对策122344
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .bat批处理(一):@echo off
  • .NET 发展历程
  • .Net(C#)自定义WinForm控件之小结篇
  • []sim300 GPRS数据收发程序
  • [8481302]博弈论 斯坦福game theory stanford week 1
  • [ai笔记4] 将AI工具场景化,应用于生活和工作
  • [BT]BUUCTF刷题第8天(3.26)
  • [CakePHP] 在Controller中使用Helper
  • [CentOs7]图形界面
  • [CISCN2019 华北赛区 Day1 Web2]ikun