JAVA文件IO, File类, 字符流,字节流

文章目录

  • 文件IO
    • 1. File
    • 2. IO流
      • 2.1 字符流
        • 2.1.1 Reader
        • 2.1.2 Writer
      • 2.2 字节流
        • 2.2.1 InputStream
        • 2.2.2 FileInputStream
        • 2.2.3 利用Scanner进行字符读取
        • 2.2.4 OutputStream

文件IO

I: Input, 从硬盘往内存读数据

O: Output, 从内存往硬盘输出数据

1. File

Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件。

构造方法

方法说明
File(File parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname)根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径
File(String parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用路径表示

方法

修饰符及返回值类型方法名称说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径
booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是一个目录
booleanisFile()判断 File 对象代表的文件是否是一个普通文件
booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返回 true
booleandelete()根据 File 对象,删除该文件。成功删除后返回 true
voiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象表示
booleanmkdir()创建 File 对象代表的目录
booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目录
booleanrenameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作
booleancanRead()判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限

代码示例

public static void main(String[] args) throws IOException {File file1 = new File("D/text.txt");System.out.println(file1.getName());System.out.println(file1.getParent());System.out.println(file1.getPath());System.out.println(file1.getAbsolutePath());System.out.println(file1.getCanonicalPath());System.out.println("===========================");File file2 = new File("./text.txt");System.out.println(file2.getName());System.out.println(file2.getParent());System.out.println(file2.getPath());System.out.println(file2.getAbsolutePath());System.out.println(file2.getCanonicalPath());
}

输出

text.txt

D:\

D:\text.txt

D:\text.txt

D:\text.txt

===========================

.

.\text.txt

D:\JAVA\java\system_code.\text.txt

D:\JAVA\java\system_code\text.txt

public static void main(String[] args) throws IOException {File file = new File("./test.txt");System.out.println(file.exists());System.out.println(file.isFile());System.out.println(file.isDirectory());//创建文件file.createNewFile();//若当前文件已经存在, 也不会重新创建一个System.out.println(file.exists());System.out.println(file.isFile());System.out.println(file.isDirectory());
}

输出

true

true

false

===========================

true

true

false

public static void main(String[] args) throws IOException {File file = new File("./text.txt");System.out.println(file.exists());file.delete();System.out.println("文件已删除");System.out.println(file.exists());
}

输出

false

文件已删除

false

public static void main(String[] args) throws IOException {File file = new File("text.txt");System.out.println(file.exists());//等到程序结束前再删除file.deleteOnExit();System.out.println(file.exists());
}

输出

true

true

public static void main(String[] args) {File file = new File("./testDir");file.mkdir();System.out.println(file.exists());System.out.println(file.isDirectory());File file1 = new File("./testDir/aaa/bbb/ccc");file1.mkdirs();System.out.println(file1.exists());System.out.println(file1.isDirectory());
}

输出

true

true

true

true

public static void main(String[] args) {File file = new File("./test.txt");File file1 = new File("./testRename.txt");System.out.println("file是否存在: " + file.exists());System.out.println("file1是否存在: " + file1.exists());System.out.println("renameTo执行是否成功: "+file.renameTo(file1));System.out.println("file是否存在: " + file.exists());System.out.println("file1是否存在: " + file1.exists());
}

输出

file是否存在: true

file1是否存在: false

renameTo执行是否成功: true

file是否存在: false

file1是否存在: true

public static void main(String[] args) throws IOException {File file = new File("./test.txt");File file1 = new File("./src/test2.txt");System.out.println("file是否存在: " + file.exists());System.out.println("file1是否存在: " + file1.exists());System.out.println("file的路径" + file.getCanonicalPath());System.out.println("renameTo执行是否成功: "+file.renameTo(file1));System.out.println("file是否存在: " + file.exists());System.out.println("file1是否存在: " + file1.exists());System.out.println("file1的路径" + file1.getCanonicalPath());}

输出

file是否存在: true

file1是否存在: false

file的路径D:\JAVA\java\system_code\test.txt

renameTo执行是否成功: true

file是否存在: false

file1是否存在: true

file1的路径D:\JAVA\java\system_code\src\test2.txt

2. IO流

将硬盘中的数据比喻为池中的水

往池中加水, 相当于数据从内存往硬盘中流动, 称作输出流

从池中放水, 相当于数据从硬盘往内存中流, 称作输入流

IO流可以分为 字节流 , 字符流 两大类

这些类都有各自不同的特性, 但是使用方法还是类似的:

  1. 构造方法: 打开文件

  2. close方法: 关闭文件

    close方法一定要执行到, 如果使用完不关闭, 就会导致文件资源泄露 (尤其是在7*24小时运转的服务器上) 进而导致文件都打不开, 使服务器宕机.

    如何保证close方法一定能执行的到呢?

    1. 使用try-finally, 将close写入finally代码块

    2. 使用try with resources创建流对象. 例如

    try (Reader reader = new FileReader("D:/test.txt");Reader reader1 = new FileReader("");Reader reader2 = new FileReader("");...) {//代码
    }
    

    只要try代码块执行结束, 就会自动调用close方法.

  3. 如果衍生自InputStream或者Reader, 就可以使用read方法读文件

  4. 如果衍生自OutputStream或者Writer, 就可以使用write方法写文件

2.1 字符流

字符流, 顾名思义, 以操作字符为单位, 针对文本文件

2.1.1 Reader

read方法

方法作用返回值
int read()一次读一个字符以int类型返回读到的字符. 如果返回值为-1, 表示文件已经读完, 或者读到EOF.
int read(char cbuf[])一次读若干个字符, 并把读到的内容填充到cbuf[]中返回实际读到的字符个数
int read(char cbuf[], int off, int len)从第off个字符开始, 将字符读入数组, 一共读len个读取的字符数,如果已到达流的结尾,则返回-1

代码案例

public static void main(String[] args) throws IOException {try (Reader reader = new FileReader("D:/test.txt")) {while (true) {char[] buf = new char[1024];int n = reader.read(buf);if(n == -1) {break;}for (int i = 0; i < n; i++) {System.out.print(buf[i] + " ");}}}
}

在这里插入图片描述

2.1.2 Writer

write方法

方法说明
void write(int c)写入单个字符。
void write(char cbuf[])写入字符数组。
void write(char cbuf[], int off, int len)写入字符数组的一部分。cbuf -字符数组off -开始写入字符的偏移量len -要写入的字符数
void write(String str)写入字符串
void write(String str, int off, int len)写入字符串的一部分。str -字符串off -开始写入字符的偏移量len -写入字符的数目

代码示例

public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("D:/test.txt")) {writer.write("hello java");}
}

在这里插入图片描述

这里可能就会有疑问了, 文件里面之前的内容呢?

输出流对象(无论字节流还是字符流), 再打开文件之后, 清空文件内容.

如果不想被清空, 那就使用追加写方式打开文件.

Writer writer = new FileWriter("D:/test.txt", true)

在构造方法上, 写一个true, 便可

public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("D:/test.txt", true)) {writer.write("hello world");}
}

在这里插入图片描述

2.2 字节流

字节流, 顾名思义, 以操作字节为单位, 针对二进制文件

2.2.1 InputStream

方法

返回值类型方法说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数; -1 代表以及读完了
intread(byte[] b, int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
voidclose()关闭字节流

说明

InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用FileInputStream

2.2.2 FileInputStream

构造方法

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

代码示例

public static void main(String[] args) {try(InputStream inputStream = new FileInputStream("D:/test.txt")) {while (true) {byte[] bytes = new byte[1024];int n = inputStream.read(bytes);if (n == -1) {break;}for (int i = 0; i < n; i++) {System.out.printf("%x ", bytes[i]);}}} catch (IOException e) {throw new RuntimeException(e);}
}

在这里插入图片描述

读到的字符, 我们更期望的是把他转化成字符串, 更直观. 所以我们可以借助一些额外的工具类, 就可以完成从字节/字符到字符串的转换.

一. 是使用String的构造方法. 但这种方式不够优雅.

String s = new String(bytes, 0, n, "utf8");
System.out.println(s);

在这里插入图片描述

二. 是Scanner.

2.2.3 利用Scanner进行字符读取

我们来看一下Scanner的构造方法

在这里插入图片描述

其中, 构造方法的参数中有InputStream, 也就是说我们可以往里面传字节流. 实际上, 我们经常写的new Scanner(System.in)中的in也是一个字节流

在这里插入图片描述

其实在操作系统中, "文件"是一个广义的概念

  • System.in是一个特殊的文件, 对应到"标准输入"
  • 硬盘上的文件, 也是文件
  • 网卡(socket), 也是文件

Scanner都是一视同仁的, 只是把当前读到的字节数据进行转换, 不关心这个数据的来源.

那么上述读取文件的代码就可以这样写了

public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("D:/test.txt")) {Scanner scanner = new Scanner(inputStream);//Scanner scanner = new Scanner(inputStream, "utf8");//从文件中读取while (scanner.hasNext()) {String s = scanner.next();System.out.print(s + " ");}}
}

在这里插入图片描述

但是Scanner只适合读取文本文件, 不适合读取二进制文件

2.2.4 OutputStream

方法

返回值类型方法说明
voidwrite(int b)将指定字节写入此输出流。
voidwrite(byte[] b)将 b 这个字节数组中的数据全部写入 os 中
voidwrite(byte b[], int off, int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
voidclose()关闭字节流
voidflush()刷新此输出流并强制写出任何缓冲的输出字节。

我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。

OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,

所以使用 FileOutputStream

OutputStream 的使用方法和Writer完全一样, 只不过不能写入字符, 字符串.

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

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

相关文章

解析d3dcompiler_47.dll缺失怎么修复,4种方法修复d3dcompiler_47.dll文件

d3dcompiler_47.dll缺失怎么修复&#xff1f;其实在我们使用计算机操作的过程中&#xff0c;有时会遇到一些由dll文件错误导致的问题&#xff0c;其中d3dcompiler_47.dll丢失就是这样一种。那么究竟d3dcompiler_47.dll缺失是什么意思&#xff0c;为何它会发生丢失&#xff0c;以…

PWM占空比原理是什么,几个实例带你进一步了解

PWM : 即脉冲宽度调制(Pulse Width Modulation) 脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术&#xff0c;广泛应用在从测量、通信到功率控制与变换及嵌入式领域的许多领域中。 PWM控制技术以其控制简单&#xff0c;灵活和动态响应好的优点而…

【用unity实现100个游戏之17】从零开始制作一个类幸存者肉鸽(Roguelike)游戏4(附项目源码)

文章目录 本节最终效果前言命中敌人闪白和击退效果敌人死亡效果等级 击杀数 经验绘制经验条显示等级和杀敌数游戏倒计时玩家血条参考源码完结 本节最终效果 前言 本节紧跟着上一篇&#xff0c;主要实现敌人受击死亡效果特效&#xff0c;主角等级、击杀数、经验、血条UI显示。 …

手写promise A+、catch、finally、all、allsettled、any、race

目录 手写promise 同步版 1.Promise的构造方法接收一个executor()&#xff0c;在new Promise()时就立刻执行executor回调 2.executor()内部的异步任务被放入宏/微任务队列&#xff0c;等待执行 3.状态与结果的管理 状态只能变更一次 4.then()调用成功/失败回调 catch是…

内测分发平台是否支持敏捷开发和持续集成?

大家好&#xff0c;我是咕噜-凯撒。敏捷开发和持续集成是软件开发中非常重要的流程和方法。内测分发平台作为应用开发和测试的关键环节需要具备这种能力。下面我简单的介绍一下敏捷开发和持续集成和提供的功能。图片来源&#xff1a;news.gulufenfa.com 敏捷开发是一种迭代、协…

Asp.net core WebApi 配置自定义swaggerUI和中文注释

1.创建asp.net core webApi项目 默认会引入swagger的Nuget包 <PackageReference Include"Swashbuckle.AspNetCore" Version"6.2.3" />2.配置基本信息和中文注释&#xff08;默认是没有中文注释的&#xff09; 2.1创建一个新的controller using Micr…

SELinux(一) 简介

首发公号&#xff1a;Rand_cs 前段时间的工作遇到了一些关于 SELinux 的问题&#xff0c;初次接触不熟悉此概念&#xff0c;导致当时配置策略时束手束脚&#xff0c;焦头烂额&#xff0c;为此去系统的学习了下 SELinux 的东西。聊 SELinux 之前&#xff0c;先来看看什么叫做访…

Linux以nohup方式运行jar包

1、在需要运行的jar包同级目录下建立启动脚本文件&#xff1a; 文件内容&#xff1a; #! /bin/bash #注意&#xff1a;必须有&让其后台执行&#xff0c;否则没有pid生成 jar包路径为绝对路径 nohup java -jar /usr/local/testDemo/jdkDemo-0.0.1-SNAPSHOT.jar >/us…

C51--4G模块

EC03-DNC&#xff1a;4G通信模块 EC03-DNC 功能特点&#xff1a; 采用最新4G CAT1方案&#xff1b; 支持数据透明传输; 支持TCP、UDP 网络协议; 支持心跳包、注册包功能最大支持64个字节数&#xff1b; 支持MQTT协议&#xff0c;支持接入OneNet平台、百度云平台、阿里云平台的…

微信小程序开发——项目开发入门

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 概述 本文重点介绍微信小程序开发者工具的下载与安装与项目开发入门。 下载开发者工具 请在官方网站下载微信小程序开发工具&#xff1b;图示如下&#xff1a; 请依据实际…

解决electron-builder打包不成功只能输出tgz文件的问题

现象&#xff1a; 对应项目里配的指令&#xff1a; 但就是死活不成功&#xff0c;只能输出tgz压缩文件。 最后一咬牙下载了官方的electron-quick-start拿来试试&#xff0c;结果还是一样。 一时间没想法了。 后来突然脑袋灵光一闪&#xff0c;去他妈的直接npx 执行看看&…

Java线程通信

线程通信 案例 package com.itheima.d4;public class ThreadTest {public static void main(String[] args) {Desk desk new Desk();//创建3个生产者线程new Thread(() -> {while (true) {desk.put();}}, "厨师1").start();new Thread(() -> {while (true) {…

华为设备使用python实现文件自动保存下载

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址为172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;STELNET实现设备的自动保存配置文件&#xff0c;使用SFTP实现设备的文件下载。 实验拓扑&#xff1a; 实验步骤&#xff1a; 步骤1&#xff1…

Android flutter项目 启动优化实战(二)利用 App Startup 优化项目和使用flutterboost中的问题解决

背景 书接上回&#xff1a; Android flutter项目 启动优化实战&#xff08;一&#xff09;使用benchmark分析项目 已经分析出了问题: 1.缩短总时长&#xff08;解决黑屏问题、懒启动、优化流程&#xff09;、2.优化启动项&#xff08;使用App Startup&#xff09;、3.提升用…

鸿蒙开发学习——应用程序框架

文章目录 UIAbility的生命周期Create状态WindowStageCreateForeground和Background前后台展示控制onWindowStageDestroyDestory 总结 UIAbility的生命周期 感觉这里他讲的不清晰&#xff0c;UIAbility的4个声明周期是Create、Foreground&#xff08;桌面展示&#xff09;、Back…

Java实现通过经纬度求两个任意地点在球面上的距离

我们在实际开发中会获取对应的经纬度&#xff0c;可以使用ES大数据搜索引擎进行计算对应区域的数据&#xff0c;那我们在如何根据两个经纬度获取对应的球面距离&#xff0c;就是在地球上从一个地点到另一个地点的直线距离 工具类如下: public class GeoUtils {// 地球半径&am…

虚幻学习笔记3—UI跟随弹窗

一、前言 本文使用的虚幻引擎5.3.2&#xff0c;继点击场景3D物体的两种处理方式的基础完成对3D物体的点击触发后&#xff0c;我们需要制作一个可以弹窗显示该物体信息的UI面板&#xff0c;同时保证弹窗可以跟随物体。另外还讲了一种UI上的悬浮提示跟随弹窗。 二、实现 2.1、创…

【计算机毕业设计】nodejs+vue音乐播放器系统 微信小程序83g3s

本系统的设计与实现共包含12个表:分别是配置文件信息表&#xff0c;音乐列表评论表信息表&#xff0c;音乐论坛信息表&#xff0c;歌手介绍信息表&#xff0c;音乐资讯信息表&#xff0c;收藏表信息表&#xff0c;token表信息表&#xff0c;用户表信息表&#xff0c;音乐类型信…

viple模拟器使用(四):unity模拟器中实现沿右墙迷宫算法

沿右墙迷宫算法 引导 线控模拟可以使得通过用户手动操作&#xff0c;实现机器人在模拟环境下在迷宫中行走&#xff08;即&#xff1a;运动&#xff09;&#xff0c;算法可以使得机器人按照一定的策略自动行走&#xff0c;沿右墙迷宫算法就是其中的一种策略。 目的 运行程序后&…

Python---lambda表达式

普通函数与匿名函数 在Python中&#xff0c;函数是一个被命名的、独立的完成特定功能的一段代码&#xff0c;并可能给调用它的程序一个返回值。 所以在Python中&#xff0c;函数大多数是有名函数 > 普通函数。但是有些情况下&#xff0c;我们为了简化程序代码&#xff0c;…