Java开发从入门到精通(二十):Java的面向对象编程OOP:IO流文件操作的读取和写入

Java大数据开发和安全开发

  • (一)Java的IO流文件读写
    • 1.1 IO流前置知识
      • 1.1.1 ASCII字符集
      • 1.1.2 GBK字符集
      • 1.1.3 Unicode字符集
      • 1.1.4 UTF-8字符集
      • 1.1.4 Java的编码解码
    • 1.2 IO流的基础知识
      • 1.2.1 认识I0流
      • 1.2.2 应用场景
      • 1.2.3 如何学I0流
        • 1.2.3.1 先搞清楚I0流的分类、体系:
        • 1.2.3.1 再挨个学习每个I0流的作用、用法。
          • 1.2.3.1 字节流的用法
            • 1.2.3.1.1 FilelnputStream文件字节输入流:每次读取一个字节
            • 1.2.3.1.2 FilelnputStream文件字节输入流:每次读取多个字节
            • 1.2.3.1.3 FilelnputStream文件字节输入流:一次读取完全部字节
            • 1.2.3.1.4 FileOutputstream文件字节输出流:写字节出去
            • 1.2.3.1.5 案例:文件复制

(一)Java的IO流文件读写

1.1 IO流前置知识

字符集、UTF-8、GBK、ASCII、乱码问题、编码和解码等

1.1.1 ASCII字符集

美国人发明了计算机以后就把自己的字符录入到系统中,也就是英文、数字、标点、特殊符号,但是计算机只能识别0、1,所以为了能使用这些字符,美国人发明了ASCII 将所用到字符编写为特定的编号,从0-127 ,这些被称为码点 然后把ASCII通过编码的方式写进计算机,也就是将编号0-127转换成二进制数表示,不够的补0,使用了一个字节来存储,

  • 标准ASCII字符集 ASCll(American standard Code for Information Interchange):美国信息交换标准代码,包括了英文、符号等
  • 标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符

在这里插入图片描述

1.1.2 GBK字符集

GBK(汉字内码扩展规范,国标)
随着计算机的普及,中国将自己的字符编写成GBK汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储。
注意:GBK兼容了ASCII字符集。

在这里插入图片描述
在这里插入图片描述

ASCII首字节是0 GBK首字节是1

在这里插入图片描述

1.1.3 Unicode字符集

Unicode字符集(统一码,也叫万国码)
Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集。
UTF-32 有容乃大,使用4个字节表示一个字符
不被使用的原因是比较奢侈!占存储空间,通信效率变低

1.1.4 UTF-8字符集

  • 国际组织制定重新制定的,是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节
  • 英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节
    在这里插入图片描述
    注意:技术人员在开发时都应该使用UTF-8编码!

要点记忆部分

  • ASCII字符集:只有英文、数字、符号等,占1个字节
  • GBK字符集:汉字占2个字节,英文、数字占1个字节
  • UTF-8字符集:汉字占3个字节,英文、数字占1个字节

注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
注意2:英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码

在这里插入图片描述

1.1.4 Java的编码解码

  • 编码:把字符按照指定字符集编码成字节。

在这里插入图片描述

  • 解码:把字节按照指定字符集解码成字符。

在这里插入图片描述

import java.util.Arrays;public class ZiFu {public static void main(String[] args) throws Exception {// 1、编码String data ="a我b";byte[] bytes = data.getBytes();// 默认是按照平台字符集(UTF-8)进行编码的。System.out.println(Arrays.toString(bytes));// 按照指定字符集进行编码。byte[] bytes1 = data.getBytes(  "GBK");System.out.println(Arrays.toString(bytes1));// 2、解码String s1= new String(bytes);// 按照平台默认编码(UTF-8)解码System.out.println(s1);// 按照指定字符集进行解码。String s2 =new String(bytes1,"GBK");System.out.println(s2);}
}

1.2 IO流的基础知识

1.2.1 认识I0流

IO流概述

  • I指Input,称为输入流:负责把数据读到内存中去
  • 0指Output,称为输出流:负责写数据出去
    在这里插入图片描述

1.2.2 应用场景

在这里插入图片描述

1.2.3 如何学I0流

1.2.3.1 先搞清楚I0流的分类、体系:
  • I0流的分类

在这里插入图片描述
在这里插入图片描述

总结流的四大类:

  • 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
  • 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流。
  • 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。
  • 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。

Java.io包下

  • I0流的体系
    在这里插入图片描述
    在这里插入图片描述
1.2.3.1 再挨个学习每个I0流的作用、用法。
1.2.3.1 字节流的用法
1.2.3.1.1 FilelnputStream文件字节输入流:每次读取一个字节

FilelnputStream(文件字节输入流)
作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去
在这里插入图片描述
在这里插入图片描述

import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、创建文件字节输入流管道,与源文件接通。// InputStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"))// 简化写法:推荐使用。InputStream is = new FileInputStream(("file-io-app\\src\\itheima1.txt"));//2、开始读取文件的字节数据。// public int read():每次读取一个字节返回,如果没有数据了,返回-1.int b1 = is.read();System.out.println((char)b1);int b2 = is.read();System.out.println((char)b2);int b3 = is.read();System.out.println(b3);// 3、使用循环改造上述代码int b;// 用于记住读取的字节。while((b=is.read())!= -1) {System.out.print((char) b);}// 读取数据的性能很差!// 读取汉字输出会乱码!!无法避免的!!// 流使用完毕之后,必须关闭!释放系统资源!2is.close();}
}
1.2.3.1.2 FilelnputStream文件字节输入流:每次读取多个字节
import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {InputStream is =new FileInputStream("/1.txt");// 2、开始读取文件中的字节数据:每次读取多个字节。// public int read(byte b[])throws IOException// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.byte[] buffer = new byte[3];int len = is.read(buffer);String rs=new String(buffer);System.out.println(rs);System.out.println("当次读取的字节数量:"+ len);// buffer = [abc]// buffer = [66c]int len2 = is.read(buffer);// 注意:读取多少,倒出多少。String rs2 = new String(buffer,0,len2);System.out.println(rs2);System.out.println("当次读取的字节数量:"+ len2);int len3 = is.read(buffer);System.out.println(len3);//-1}
}

优化代码

public class FileInputTest {public static void main(String[] args) throws Exception {InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");// 2、开始读取文件中的字节数据:每次读取多个字节。// public int read(byte b[])throws IOException// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.// 3、使用循环改造。byte[] buffer = new byte[3];int len;// 记住每次读取了多少个字节。abc 66while((len=is.read(buffer))!=-1) {// 注意:读取多少,倒出多少。String rs = new String(buffer, 0, len);System.out.print(rs);}is.close();// 关闭流// 性能得到了明显的提升!!// 这种方案也不能避免读取汉字输出乱码的问题!!}
}
  • 使用FilelnputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码
1.2.3.1.3 FilelnputStream文件字节输入流:一次读取完全部字节

方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
在这里插入图片描述

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");// 2、准备一个字节数组,大小与文件的大小正好一样大。File f = new File("lianxi\\src\\com\\qianxin\\file\\1.txt");long size = f.length();byte[] buffer =new byte[(int) size];int len = is.read(buffer);System.out.println(new String(buffer));System.out.println(size);System.out.println(len);}
}

lianxi\src\com\qianxin\file\1.txt 内容

public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
1163
1163

方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。
在这里插入图片描述

import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");byte[] buffer = is.readAllBytes();System.out.println(new String(buffer));is.close();}
}

1、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?

  • 如果文件过大,创建的字节数组也会过大,可能引起内存溢出,
  • 字符流:读写文本内容更适合用
  • 字节流:适合做数据的转移,如:文件复制等
1.2.3.1.4 FileOutputstream文件字节输出流:写字节出去

FileOutputstream(文件字节输出流)
作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

import java.io.FileOutputStream;
import java.io.OutputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通OutputStream os = new FileOutputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");// 2、开始写字节数据出去了os.write(97); //97就是一个字节,代表aos.write('b'); //'b'也是一个字节os.write('磊');// [ooo]默认只能写出去一个字节byte[] bytes ="我爱你中国abc".getBytes();os.write(bytes);os.write(bytes,0,15);os.close();//关闭流}
}

写入文件不覆盖之前的内容

import java.io.FileOutputStream;
import java.io.OutputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通OutputStream os = new FileOutputStream("lianxi\\src\\com\\qianxin\\file\\1.txt",true);// 2、开始写字节数据出去了os.write(97); //97就是一个字节,代表aos.write('b'); //'b'也是一个字节os.write('磊');// [ooo]默认只能写出去一个字节byte[] bytes ="我爱你中国abc".getBytes();os.write(bytes);os.write(bytes,0,15);// 换行符os.write("\r\n".getBytes());os.close();//关闭流}
}
1.2.3.1.5 案例:文件复制

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

瑞芯微RK3328(ROC-RK3328-PC)buildroot 开发QT的hello world

第一部分:编译rk3328 sdk 0. 环境 - EC-R3328PC(ROC-RK3328-PC) - ubuntu18(100GB) 1. 安装依赖 sudo apt-get updatesudo apt-get install repo git-core gitk git-gui gcc-arm-linux-gnueabihf u-boot-tools devi…

二叉树经典OJ题(2)

一、根据二叉树创建字符串 . - 力扣(LeetCode) class Solution { public://前序遍历:根 左 右//左子树为空,右子树不为空的时候,不能省略左//左不为空,右子树为空的时候,可以省略右//都为空&am…

Zynq7000中的应用处理单元(APU)介绍

Zynq 7000 系列基于 AMD 的 SoC 架构。这些产品将功能丰富的双核或单核处理系统(PS)和 AMD 可编程逻辑(PL)集成在单个设备中,这些处理器是 Arm Cortex-A9 处理器,配备 NEON 协处理器,以多处理器…

2024蓝桥A组A题

艺术与篮球(蓝桥) 问题描述格式输入格式输出评测用例规模与约定解析参考程序难度等级 问题描述 格式输入 无 格式输出 一个整数 评测用例规模与约定 无 解析 模拟就好从20000101-20240413每一天计算笔画数是否大于50然后天数; 记得判断平…

每日一VUE——组件的生命周期

文章目录 VUE组件的生命周期生命周期钩子函数实例创建Teleport VUE组件的生命周期 组件生命周期 组件从创建到挂载、更新、到销毁的一系列过程被称为组件的生命周期。 生命周期函数 在组件的各个生命周期节点执行的函数,为生命周期钩子函数。 生命周期钩子函数…

如何在Rust中操作JSON

❝ 越努力,越幸运 ❞ 大家好,我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder。 前言 我们之前在Rust 赋能前端-开发一款属于你的前端脚手架中有过在Rust项目中如何操作JSON。 由于文章篇幅的原因,我们就没详细介绍…

Web 题记

[极客大挑战 2019]LoveSQL 看到这种就肯定先想到万能密码,试试,得到了用户名和密码 总结了一些万能密码: or 11 oror admin admin-- admin or 44-- admin or 11-- admin888 "or "a""a admin or 22# a having 11# a havin…

基于ArcGIS、InVEST与RUSLE水土流失模拟及分析

我国是世界上水土流失最为严重的国家之一,水土流失面广量大。据第一次全国水利普查成果,我国现有水土流失面积294.91万平方公里。严重的水土流失,是我国生态恶化的集中反映,威胁国家生态安全、饮水安全、防洪安全和粮食安全&#…

Stable Diffusion之文生图模型训练

1、数据准备 提前准备好一组相关的照片。 在线的图片处理网站 BIRME - Bulk Image Resizing Made Easy 2.0 (Online & Free) 将图片转成统一大小,支持批量处理,效率高 2、生成提示词 进入stable diffusion webui页面 旧版直接使用 train/proproc…

(四)C++自制植物大战僵尸游戏启动流程

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/ErelL 一、启动方式 鼠标左键单机VS2022上方工具栏中绿色三角按钮(本地Windows调试器)进行项目启动。第一次启动项目需要编译项目中所有代码文件,编译生成需要一定的时间。不同性能的电…

AliyunCTF 2024 - BadApple

文章目录 前言环境搭建漏洞分析漏洞利用参考 前言 本文首发于看雪论坛 https://bbs.kanxue.com/thread-281291.htm 依稀记得那晚被阿里CTF支配的恐惧,今年的阿里CTF笔者就做了一道签到PWN题,当时也是下定决心要学习 jsc pwn 然后复现这道 BadApple 题目…

小米温度计接入HA后,手机米家app里温度计就看不到温度数值了

环境: 小米温度计 HA OS Core 2023.12.1 Supervisor 2024.04.0 Operating System 11.1 问题描述: 小米温度计接入HA后,手机米家app里和HA里面温度计就看不到温度数值了 解决方案: 1.前往米家APP,解绑温度计和本地…