InputStream和OutputStream

news2024/11/19 7:40:20

文章目录

    • 💡FileInputStream 构造方法
    • 💡InputStream 常用方法
    • 💡OutputStream 概述
    • 💡OutputStream 常用方法
    • 💡PrintWriter
    • 💡小程序练习

使用字节流进行读/写操作时,是以字节为单位的;

InputStream 只是一个抽象类,在实例化时,需要使用具体的实现类,而InputStream 的实现类有很多,可以认为不同的输入设备都对应着一个InputStream 类,而针对于文件读写时,主要使用 FileInputStream

💡FileInputStream 构造方法

构造方法说明
FileInputStream(File file)使用 File 对象构造输入流
FileInputStream(String name)使用文件路径构造输入流

💡InputStream 常用方法

返回值方法说明
intread()读取一个字节的数据,返回-1代表已经读完
intread(byte[] b)最多读取b.length长度字节的数据到b中,返回实际读到的数量,-1表示读完
intread(byte[] b, int off, int len)最多读取off-len长度字节的数据到数组中,从off位置开始放数据
voidclose()关闭字节流

代码演示:

第一种读取方式:

    public static void main(String[] args) {
        try(InputStream is = new FileInputStream("d:/新建文件夹/text.txt")) {
            while(true) {
                byte[] b = new byte[1024];
                int n = is.read(b);//返回读到的字节个数
                System.out.println(n);
                if(n == -1) {
                    //表示数据已经读完了
                    break;
                }
                for(int i = 0; i < n; i++) {
                    System.out.printf("%x\n",b[i]);//用十六进制显示
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

在这里插入图片描述

第二种读取方式:使用Scanner进行读取

Scanner(InputStream is, String charset)使用charset字符集对流对象进行读取
    public static void main(String[] args) {
        try(InputStream is = new FileInputStream("d:/新建文件夹/text.txt");
            Scanner scanner = new Scanner(is, "UTF-8")) {
            //使用Scanner包装一下流对象,将读的内容转换为字符
            while(scanner.hasNext()) {
                String s = scanner.next();
                System.out.println(s);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

在这里插入图片描述

💡OutputStream 概述

与InputStream一样,OutputStream也是一个抽象类,需要具体类进行实现,例如:FileOutputStream ,构造方法的参数与InpuStream也是一样的;

💡OutputStream 常用方法

返回值方法说明
voidwrite()写入一个字节的数据
voidwrite(byte[] b)将b这个数组中的数据全都写入文件中
voidwrite(byte[] b, int off, int len)将b这个字节数组中,从off这个位置开始的数据写入文件中,一直写len个长度
voidclose()关闭字节流
voidflush()下面讲解

flush作用:

举一个例子,平时嗑瓜子时,难道我们嗑一个瓜子就跑出去扔一个瓜子皮吗?并不是的,而是嗑了许多瓜子之后,瓜子皮一块扔,这样就很省力气,OutputStream 也就是这样的,因为写向硬盘中写入数据时是很慢的,所以,会将写入的数据先存放在缓冲中,等缓冲区满了,再写入到硬盘中,但是这样就会有一个缺陷就是,如果还没来得及写入硬盘中时,进程就结束了,那么数据就遗留到了缓冲区中,所以为了防止这种情况,就可以在合适的位置使用 flush() 来刷新缓冲区,这样才真正的将数据写入到了硬盘中

示例一:

import java.io.*;
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            os.write('a');
            os.write('b');
            os.write('c');
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

示例二:

import java.io.*;
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            byte[] b = new byte[]{(byte)'Q',(byte)'E',(byte)'R',(byte)'T'};
            os.write(b);//将数组中的数据全都写入到文件中
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

示例三:

import java.io.*; 
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            byte[] b = new byte[]{(byte)'Q',(byte)'E',(byte)'R',(byte)'T'};
            os.write(b, 0, 3);//将数组中的数据从0位置开始写入到文件中,写入3个字节的数据
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

示例四:

import java.io.*; 
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            String s = "你好中国";
            byte[] b = s.getBytes();
            //s.getBytes("UTF-8");指定一个字符集
            os.write(b);
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

💡PrintWriter

在上述的流对象中,写入数据时,都必须先转化成字节然后再写入,这对于这一点,可以使用PrintWriter 这个类对输出流进行包装,这样就不用我们自己手动的转化了;

PrintWriter 类中,也提供 Print()、printf()、println() 这样的方法进行写入

演示:

public static void main(String[] args) {
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt")) {
            try(OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
                //也可以省略上一行直接写PrintWriter pw = new PrintWriter(os),只不过这里没有指定字符集
                PrintWriter pw = new PrintWriter(osw)) {//告诉它我们使用的字符集时UTF-8

                pw.println("我是第一行");//println写入时,会自动写入一个字符串
                pw.print("我是第二行\n");
                pw.printf("%s\n", "我是第三行");
                pw.flush();
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

在这里插入图片描述

💡小程序练习

示例1:

扫描指定路径,并找到名称中包含指定字符的所有普通文件,并且后续询问用户是否要删除该文件

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //1.输入文件路径
        Scanner in = new Scanner(System.in);
        while(true) {
            System.out.println("请输入要扫描的路径");
            String path = in.nextLine();
            //2.判断路径是否正确
            File path_file = new File(path);
            while(true) {
                if(!path_file.exists()) {
                    System.out.println("您输入的路径不存在,请重新输入");
                }else if(!path_file.isDirectory()) {
                    System.out.println("您输入的路径不是一个目录,请重新输入");
                }else{
                    break;
                }
                path = in.nextLine();
                path_file = new File(path);
            }
            //3.递归扫描目录,将目标文件加入到集合中
            System.out.println("请输入指定字符");
            String aim_char = in.nextLine();
            List<File> result = new ArrayList<>();
            search_comment(path_file, aim_char, result);
            //4.遍历这个集合,判断是否要删除该文件
            for(File f : result) {
                //打印该文件名称
                System.out.println("是否要删除该文件"+f.getName()+"(Yes/No):");
                while(true) {
                    String input = in.nextLine().toLowerCase();
                    if(input.equals("yes")) {
                        //5.删除操作
                        f.delete();
                        System.out.println("删除成功");
                        break;
                    }else if(input.equals("no")){
                        System.out.println("取消删除");
                        break;
                    }else {
                        System.out.println("输入有误,请重新输入");
                    }
                }
            }
        }

    }
    private static void search_comment(File path, String aim, List<File> result) {
        //将path这个目录中的所有文件全部拿出来进行遍历
        File[] all_file = path.listFiles();
        if(all_file == null || all_file.length == 0) {
            return;
        }
        for(File f : all_file) {
            if(f.isDirectory()) {
                //如果f是一个目录,那么就继续递归这个目录
                search_comment(f, aim, result);
            }else {
                //判断该文件是否是目标文件
                if(f.getName().contains(aim)) {
                    //该文件是目标文件,加入到result中
                    result.add(f);
                }
            }
        }
    }
}

示例2:

进行 普通文件的复制

import java.io.*;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        //1.输入源文件路径
        Scanner scan = new Scanner(System.in);
        while (true) {
            System.out.println("请输入文件路径:>");
            String srcPath = scan.nextLine();
            //2.构建file对象
            File srcFile = new File(srcPath);
            //3.检查指定的源文件
            while(true) {
                if(!srcFile.exists()) {
                    //判断指定的文件是否存在
                    System.out.println("你输入的路径不存在,请重新输入!!!");
                }else if(!srcFile.isFile()) {
                    //如果是目录,则重新输入
                    System.out.println("您输入的路径不是一个普通文件,请重新输入!!!");
                }else {
                    break;
                }
                srcPath = scan.nextLine();
                srcFile = new File(srcPath);
            }
            //4.输入目标路径
            System.out.println("请输入目标文件路径:>");
            String destPath = scan.nextLine();
            File destFile = new File(destPath);
            //判断要复制的文件在该路径下是否已经存在
            while(true) {
                if(!destFile.exists()) {
                    //如果文件不存在,则创建一个文件
                    try {
                        destFile.createNewFile();
                        break;
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }else if(destFile.isDirectory()) {
                    System.out.println("您输入的路径是一个目录,请重新输入");
                }else if(destFile.isFile()){
                    //表示目标文件已经存在,是否进行覆盖
                    System.out.println("目标文件已经存在,是否进行覆盖(Yes/No)");
                    String input = scan.nextLine().toLowerCase();
                    if(!input.equals("no")) {
                        break;
                    }else {
                        System.out.println("停止复制");
                        return;
                    }
                }else {
                    break;
                }
                destPath = scan.nextLine();
                destFile = new File(destPath);
            }
            //复制文件
            try(InputStream is = new FileInputStream(srcFile);
                OutputStream os = new FileOutputStream(destFile)) {
                //定义一个数组,用来存储读出的内容
                byte[] arr = new byte[1024];
                //定义一个标记,用来记录是否读到最后的位置
                int len;
                while(true) {
                    //定义循环是为了防止内容不能一次读完
                    len = is.read(arr);
                    if(len == -1) {
                        break;
                    }
                    os.write(arr, 0, len);
                }
                os.flush();

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            System.out.println("复制完毕!!!");
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1210622.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python如何使用Matplotlib模块的pie()函数绘制饼形图?

Python如何使用Matplotlib模块的pie函数绘制饼形图&#xff1f; 1 模块安装2 实现思路3 pie()函数说明4 实现过程4.1 导入包4.2 定义一个类4.3 读取数据并处理4.4 定义饼图绘制方法 5 完整源码 1 模块安装 先安装matplotlib&#xff1a; pip install matplotlib安装numpy模块…

Pandas教程(非常详细)(第六部分)

接着Pandas教程&#xff08;非常详细&#xff09;&#xff08;第五部分&#xff09;&#xff0c;继续讲述。 三十一、Pandas Excel读写操作详解 Excel 是由微软公司开发的办公软件之一&#xff0c;它在日常工作中得到了广泛的应用。在数据量较少的情况下&#xff0c;Excel 对…

动手学深度学习——序列模型

序列模型 1. 统计工具1.1 自回归模型1.2 马尔可夫模型 2. 训练3. 预测4. 小结 序列模型是一类机器学习模型&#xff0c;用于处理具有时序关系的数据。这些模型被广泛应用于自然语言处理、音频处理、时间序列分析等领域。 以下是几种常见的序列模型&#xff1a; 隐马尔可夫模型…

忘记7-zip密码,如何解压文件?

7z压缩包设置了密码&#xff0c;解压的时候就需要输入正确对密码才能顺利解压出文件&#xff0c;正常当我们解压文件或者删除密码的时候&#xff0c;虽然方法多&#xff0c;但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么&#xff0c;忘记了7z压缩包的密码…

字符流的讲解 以及 Reader和Writer的用法

文章目录 ❤专栏导读❤字符流❤Reader类的操作 ❤Writer类操作❤Writer类的构造方法 ❤专栏导读 &#x1f680;《多线程》 &#x1f680;《数据结构剖析》 &#x1f680;《JavaSE语法》 在Java标准库中&#xff0c;提供的读写文件的流对象有很多很多的类&#xff0c;但是可以将…

盘点49个Python网站项目Python爱好者不容错过

盘点49个Python网站项目Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1aFYJtNZjgst1l5KFBckP2A?pwd8888 提取码&#xff1a;8888 项目名称 A simpleshorturl…

C++ vector中capacity()和size() 的区别

文章目录 1 capacity()和size() 介绍2 vector满了之后&#xff0c;capacity()会自动了扩充为原来的2倍 &#xff1f; 1 capacity()和size() 介绍 size是指容器当前拥有元素的个数&#xff0c; capacity是指容器在必须分配新的存储空间之前可以存放的元素总数。 如vector<i…

PasswordPusher:能通过URL安全传递密码

什么是 Password Pusher &#xff1f; Password Pusher 是一个开源应用程序&#xff0c;用于通过网络安全的传递密码。在经过一定数量的查看和/或时间后&#xff0c;指向密码的链接会过期。 从功能上说&#xff0c;类似于 Bitwarden Send&#xff0c;思路上与传统阅后即焚工具一…

智能电网线路阻抗模拟的工作原理

智能电网线路阻抗模拟是一种通过模拟电网线路的阻抗特性来实现电网故障检测和定位的技术。智能电网系统通过安装在电网线路上的传感器&#xff0c;实时采集线路上的电流、电压等参数&#xff0c;并将这些数据传输到监控中心。监控中心接收到传感器采集的数据后&#xff0c;对数…

Java排序算法之贪心算法

贪心算法是一种优化问题的解决方法&#xff0c;它在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最优的。贪心算法常用于最优化问题&#xff0c;比如最小生成树、哈夫曼编码、最短路径等。贪心算法是一…

《ThingsBoard从入门到精通》的优秀课程

0、介绍 多年java物联网行业开发&#xff0c;精通物联网平台的架构与设计&#xff0c;精通开源物联网平台ThingsBoard&#xff0c;ThingsBoard专家。最近出了一套《ThingsBoard从入门到精通》的全套课程&#xff0c;只要学习了这一套课程&#xff0c;你将随便驾驭ThingsBoard。…

.net core windows 最详细步骤,傻瓜式如何安装rabbitmq 通知消息中间件

本次安装环境信息&#xff1a; 系统&#xff1a;win11 64位专业版 erlang rabbitMQ 一、下载安装程序 rabbitMQ安装程序下载路径&#xff1a;Installing on Windows — RabbitMQ 不能下载使用 Index of /download/ (erlang.org) otp_win64_22.0.exe

Qt图形视图框架:QGraphicsItem详解

Qt图形视图框架&#xff1a;QGraphicsItem详解 Chapter1 Qt图形视图框架&#xff1a;QGraphicsItem详解Chapter2 自定义QGraphicsItem实现平移、改变尺寸和旋转1. 平移2. 改变尺寸3. 旋转完整代码如下&#xff1a;头文件源文件 Chapter1 Qt图形视图框架&#xff1a;QGraphicsIt…

docker部署Prometheus+Cadvisor+Grafana实现服务器监控

一&#xff1a;Prometheus 1&#xff1a;介绍&#xff1a; Prometheus是一个在SoundCloud上构建的开源系统监视和警报工具包 2&#xff1a;特点 多维度数据模型-由指标键值对标识的时间序列数据组成&#xff1b;PromQL&#xff0c;一种灵活的查询语言&#xff1b;不依赖分布…

前端JS解构数组对象

// 3. 对象数组解构const arr [{username: 小明,age: 18,agw:19},{username: 小ha,age: 18,agw:19}]arr.map(item>item.age)//js结构数组对象console.log( arr.map(item>{return {aaa:item.age,bbb:item.username}}))

【Proteus仿真】【Arduino单片机】DHT11温湿度

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、DHT11温湿度传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器采集温度和湿度。 二、软件设…

基于JAVA SpringBoot和HTML美食网站博客程序设计

摘要 美食网站是一个提供各种美食信息和食谱的网站&#xff0c;旨在帮助用户发现、学习和分享美食。旨在探讨美食网站在现代社会中的重要性和影响。随着互联网的普及&#xff0c;越来越多的人开始使用美食网站来获取各种美食信息和食谱。这些网站不仅提供了方便快捷的搜索功能&…

Live800:客服中心必备的7种客户服务原则

在现代商业社会中&#xff0c;客户服务已经成为企业竞争的重要因素之一。提供高质量的客户服务可以帮助企业赢得客户的忠诚度和信任&#xff0c;从而推动企业的发展。客服中心是企业与客户之间的桥梁&#xff0c;对于客户服务的质量要求更高。为了提高客服中心的服务质量&#…

冰点还原精灵Deep Freeze for mac:Mac用户的最佳系统保护选择

你是否曾在Mac上安装软件后&#xff0c;发现系统性能下降&#xff0c;或者某些应用程序无法正常运行&#xff1f;这些问题可能让你感到困扰&#xff0c;但幸运的是&#xff0c;有一个解决方案可以帮你解决这些问题——Faronics Deep Freeze for mac。 Deep Freeze for mac是一…

【fbtft】如何添加fbtft驱动

获取lcd ic的datasheet&#xff0c;或者直接找到其他平台&#xff08;linux&#xff0c;stm32&#xff0c;esp32&#xff09;的驱动 我用的是合宙的esp32驱动&#xff0c;注意是c语言的&#xff0c;合宙上层用lua封装了&#xff0c;需要找到sdk源码。 源码路径&#xff1a; …