Java IO流(一)IO基础

概述

IO流本质
  • I/O表示Input/Output,即数据传输过程中的输入/输出,并且输入和输出都是相对于内存来讲
  • Java IO(输入/输出)流是Java用于处理数据读取和写入的关键组件
  • 常见的I|O介质包括
    • 文件(输入|输出)
    • 网络(输入|输出)
    • 键盘(输出)
    • 显示器(输出)
  • 使用场景
    • 文件拷贝(File)
    • 文件上传下载
    • Excel导入导出
    • 网络程序中数据传输(聊天工具)

分类

概述

Java中几乎所有的IO操作都需要使用java.io包;流可以通过如下方式进行分类

  • 按流向分(输入输出过程通常都是站在程序角度考虑)
    • 输入流(Input)
    • 输出流(Output)
  • 按流的处理类型分
    • 字节流(byte): 字节是计算机存储容量的基本单位(Byte),1B=8b,二进制中占8位
    • 字符流(char): 字符是文字或符号的统称

        注意:字节流对于什么类型的文件都可以读取,如二进制类型的文件(图片,视频,音频,压缩                    文件等),而字符流用于读取文本类型文件

  • 按流的功能来分
    • 节点流(直接跟输入输出源交互)
    • 处理流(对其他流包装的流:包装流)

字节流(InputStream && OutputStream)

InputStream 类图
OutputStream类图

日常开发过程中常用的字节流:

FileInputStream && FileOutputStream: 常用来实现文件复制/拷贝

BufferedInputStream && BufferedOutputStream: 为了减少IO次数,提高读取效率

PrintStream:源自OutputStream,标准字节的打印输出流(日志框架的实现原理)

ZipOutputStream && ZipInputStream:用来进行文件压缩/文件解压

字符流(Reader && Writer)

Reader类图
Writer类图

日常开发过程中常用的字符流:

FileReader&&FileWriter:作用同FileInputStream && FileOutputStream

BufferedReader&&BufferedWriter:作用同BufferedInputStream && BufferedOutputStream,同时BufferedReader提供了按行读取文本的方法,方便文本处理

扩展: 我们知道字节流可以读取任意文件,为什么还要设计出字符流呢?

  • 对于字符文件,先作为字节传输->再转成字符,比较耗时
  • 对于字符文件,如果其中为中文,则容易乱码

设计模式

在IO流中使用了多种设计模式,包括如下:

适配器模式

适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

Java IO中为了实现字符流和字节流之间的相互转换,设计了两个适配器的类,

InputStreamReader和OutputStreamWriter

InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr);

装饰器模式

装饰器模式可以将新功能动态地附加于现有对象而不改变现有对象的功能。InputStream的子类FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有Writer的子类BufferedWriter、FilterWriter 以及 PrintWriter等,它们都是抽象装饰类。增强了子类对象的功能。

实践

ZipOutputStream&&FileOutputStream&&FileInputStream实现文件压缩

/**
 * 功能: 通过ZipOutputStream压缩文件,最后返回压缩包
 * @param files
 * @param fileName
 * @return
 */
public File zipFiles(File[] files,String fileName) {
    File zipFile = null;
    FileOutputStream fosZipFile = null;
    ZipOutputStream zosZipFile = null; //压缩文件输出流
    try {
        zipFile = downloadAttachmentService.createFile("", fileName); //创建一个空的文件目录
        fosZipFile = new FileOutputStream(zipFile); //以文件流从内存中输出
        zosZipFile = new ZipOutputStream(fosZipFile); //以压缩流从内存中输出

        for (File file : files) {
            FileInputStream fis = new FileInputStream(file); //对每个文件创建输入流,读取文件到内存
            ZipEntry zipEntry = new ZipEntry(file.getName()); //ZipEntry用来创建压缩文件
            zosZipFile.putNextEntry(zipEntry); //加入需要压缩的文件

            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes)) >= 0) { //读取文件到内存
                zosZipFile.write(bytes, 0, length); //文件写入压缩流
            }
            fis.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally { //关闭流
        try {
            zosZipFile.close();
            fosZipFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return zipFile; //返回压缩包
}
/**
 * @Title: createFile
 * @Description: 创建下载目录文件
 * @author Bierce
 * @param rootPath
 * @param filename
 * @return
 * @throws IOException
 */
public File createFile(String rootPath, String filename) throws IOException {
    // Default root path
    if (rootPath.isEmpty()) {
        rootPath = "download-cache";
    }
    File fRoot = new File(rootPath);
    if (!fRoot.exists() || !fRoot.isDirectory()) {
        fRoot.mkdirs();
    }
    // job sub path
    String uuid = UUID.randomUUID().toString();
    String directoryJob = rootPath + File.separator + getClass().getSimpleName() + File.separator + uuid;//文件名称随机生成保证唯一
    File dirJob = new File(directoryJob);
    if (!dirJob.exists() || !dirJob.isDirectory()) {
        dirJob.mkdirs();
    }
    String filePath = directoryJob + File.separator + filename;
    File file = new File(filePath);
    if (!file.exists()) {
        file.createNewFile();
    }
    return file;
}
//-----------------扩展方法-文件名去重保证唯一-----------------
/**
 * @Title: snFileName_noUIID
 * @Description: 去除sn文件UUID以及解决sn文件名重复问题
 * @author Bierce
 * @return file
 */
public File snFileName_noUIID(String fileParentPath,String snFileName,File file){
    //snFileName:完整文件名 sn-xx..UUID..xx.xlsx
    //snFileName_delUIID: sn.xlsx
    //snFileName_prefix: sn
    //suffix:xlsx
    //文件名:如sn.xlsx
    String snFileName_delUIID = snFileName.substring(0,snFileName.length() - 42) + ".xlsx";//42是固定长度:UUID+.xlsx
    String snFileName_prefix = snFileName.substring(0,snFileName.length() - 42);//文件前缀
    String suffix = snFileName.substring(snFileName.lastIndexOf("."));//文件后缀:.xlsx

    try {
        file = new File(fileParentPath + snFileName_delUIID);//设置sn文件所在目录为计划交接文件目录下
        int i = 1;
        //对于同名SN文件情况重新命名
        while(file.exists()) {//保证文件夹下不存在同名文件
            String newFileName = snFileName_prefix + "(" + i + ")" + suffix;
            String parentPath = file.getParent();
            file = new File(parentPath + File.separator + newFileName);
            i++;
        }
        file.createNewFile();//new File 只是创建了一个File对象,还需要调用createNewFile()方法才能实现文件的成功创建
    } catch (Exception e) {
    }
    return file;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Layui列表复选框根据条件禁用

// 禁用客服回访id有值的复选框res.data.forEach(function (item, i) {if (item.feedbackEmpId) {let index res.data[i][LAY_TABLE_INDEX];$(".layui-table tr[data-index"index"] input[typecheckbox]").prop(disabled,true);$(".layui-table tr[d…

谈谈召回率(R值),准确率(P值)及F值

通俗解释机器学习中的召回率、精确率、准确率,一文让你一辈子忘不掉这两个词 赶时间的同学们看这里:提升精确率是为了不错报、提升召回率是为了不漏报 先说个题外话,暴击一下乱写博客的人,网络上很多地方分不清准确率和精确率&am…

SENet网络分析

文章目录 注意力机制:AttentionBiased Competition Theorybottom-up和top-down注意力 SE BlockSqueeze操作Excitation操作scale操作与原结构合并计算复杂度评估 实验与其他网络对比数据集实验内部参数对比实验进一步评估Squeezeexcitation Squuze-and-Excitation网络…

大数据课程I3——Kafka的消息流与索引机制

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Kafka的消息流处理; ⚪ 掌握Kafka的索引机制; ⚪ 掌握Kafka的消息系统语义; 一、Kafka消息流处理 1. Producer 写入消息 流程说明: 1. producer 要向Kafka生产消息,需要先通过…

修改el-table行悬停状态的背景颜色

.content:deep().el-table tr:hover>td {background-color: #f5f5f5 !important; /* 设置悬停时的背景颜色 */ }/*这一点很重要,否则可能会导致hover行时操作列还是原来的背景色*/ .content:deep().el-table__body tr.hover-row>td{background-color: #f5f5f5…

【Axure高保真原型】JS日期选择器筛选中继器表格

今天和大家分享JS日期选择器筛选中继器表格的原型模板,通过调用浏览器的日期选择器,所以可以获取真实的日历效果,具体包括哪一年二月份有29天,几号对应星期几,都是真实的,获取日期值后,通过交互…

GraphQL strawberry的使用回顾和体会

GraphQL vs RESTful 简单来说GraphQL 比起 RESTful 集成额外一些功能 出入参校验、序列化 (简化后端编程)自由可选的返回数据字段 (简化一些多余接口开发和沟通联调成本) 这些都是优点了。 开发效率在项目初期是很重要的,需要快速原型化。 但是后期稳定后&#…

使用维纳过滤器消除驾驶舱噪音(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【NepCTF2023】复现

文章目录 【NepCTF2023】复现MISC与AI共舞的哈夫曼codesc语言获取环境变量 小叮弹钢琴陌生的语言你也喜欢三月七么Ez_BASIC_IImisc参考 WEBez_java_checkinPost Crad For You独步天下配置环境独步天下-镜花水月环境变量提权 独步天下-破除虚妄总结 独步天下-破除试炼_加冕成王知…

TCP服务器实现—多进程版,多线程版,线程池版

目录 前言 1.存在的问题 2.多进程版 3.多线程版 4.线程池版 总结 前言 在上一篇文章中使用TCP协议实现了一个简单的服务器,可以用来服务端和客户端通信,但是之前的服务器存在一个问题,就是当有多个客户端连接服务器的时候,服…

微信开发者工具项目简单介绍和使用

主要目录简介: 页面文件的简介: 四个json文件的简介: 1.app.json 2.project.config.json 3.sitemap.json 4.页面中的json 简单操作 1.快速新建小程序页面,在app.json的pages下编写页面的路径,保存后微信开发者工具会自…

SpringjDBCTemplate_spring25

1、首先导入两个包,里面有模板 2、transtion事务 jDbc操作对象,底层默认的是事务: 3、我们java一般对实体类进行操作。 4、第一步写好坐标。 创建一个Account表 数据修改用update 数据进去了

LeetCode235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 文章目录 [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)一、题目二、题解方法一:递归方法二:迭代 一、题目 给定一个二叉搜索树, 找到该树中两个指定…

XSS 跨站脚本攻击

XSS(DOM) XSS 又称CSS(Cross Site Scripting)或跨站脚本攻击,攻击者在网页中插入由JavaScript编写的恶意代码,当用户浏览被嵌入恶意代码的网页时,恶意代码将会在用户的浏览器上执行。 XSS攻击可分为三种:分别为反射型(Reflected…

VSCODE[配置ssh免密远程登录]

配置ssh免密远程登录 本文摘录于:https://blog.csdn.net/qq_44571245/article/details/123031276只是做学习备份之用,绝无抄袭之意,有疑惑请联系本人! 这里要注意如下几个地方: 1.要进入.ssh目录创建文件: 2.是拷贝带"ssh-…

模糊测试面面观 | 模糊测试工具知多少

自1988年威斯康星大学的Barton Miller首次提出模糊测试这一概念以来,模糊测试领域经历了持续长久发展。模糊测试作为一种软件测试方法,旨在通过向程序输入模糊、随机、异常的数据,探测和发现潜在的漏洞和错误。这种方法备受安全研究人员的青睐…

使用 Ansible Galaxy 安装角色

使用 Ansible Galaxy 安装角色 使用 Ansible Galaxy 和要求文件 /home/curtis/ansible/roles/requirements.yml 。从以下 URL 下载角色并安装到 /home/curtis/ansible/roles : http://rhgls.area12.example.com/materials/haproxy.tar 此角色的名称应当为 balancer …

【无监督】2、MAE | 自监督模型提取的图像特征也很能打!(CVPR2022 Oral)

文章目录 一、背景二、方法三、效果 论文:Masked Autoencoders Are Scalable Vision Learners 代码:https://github.com/facebookresearch/mae 出处:CVPR2022 Oral | 何凯明 | FAIR 一、背景 本文的标题突出了两个词: masked…

微信小程序前后端开发快速入门(完结篇)

这篇是微信小程序前后端快速入门完结篇了,今天利用之前学习过的所有知识做一个新的项目「群登记助手v1.0」小程序。 整体技术架构:小程序原生前端小程序云开发。 经历了前面教程的学习,大家有了一定的基础,所以本次分享重心主要是…

【C++】位图和布隆过滤器

位图和布隆过滤器 前言正式开始位图位图讲解模拟实现位图几道关于位图的题目 布隆过滤器概念实例布隆过滤器模拟实现误判率测试几道题 前言 本来本篇是和前面的两篇连着的,但是没写到一块,位图和布隆过滤器都是基于哈希的思想的,如果对于哈希…