java入门-文件与IO流

File类

提供一些方法(api)来操纵文件和获取文件的信息

File常用API

属性

获取系统分隔符

不同操作系统的分隔符

windows的目录分割符号是用向右的斜线,java中\ 表示转义字符,所以向右的斜线需要写两个 \;

linux目录分割符号是向左的斜线: /

private static final FileSystem fs = DefaultFileSystem.getFileSystem();
public static final char separatorChar = fs.getSeparator();
public static final String pathSeparator = "" + pathSeparatorChar; 

程序案例:

System.out.println("File.pathSeparator:" + File.pathSeparator);
System.out.println("File.separatorChar:" + File.separatorChar);

程序运行结果:

File.pathSeparator:;
File.separatorChar:\

方法

获取文件/文件夹名称

程序案例:

File file = new File("D:\\java-workspace");
System.out.println("文件夹/文件名: " + file.getName());
System.out.println("绝对路径:" + file.getAbsolutePath());
System.out.println("路径: " + file.getPath());

程序运行结果:

文件夹/文件名: \java-workspace
绝对路径:D:\\java-workspace
路径: D:\\java-workspace
文件夹/文件

程序案例:

File file = new File("D:\\java-workspace");
System.out\.println("是否是文件: " + file.isDirectory());
System.out\.println("是否是文件: " + file.isFile());

程序运行结果:

是否是文件: true
是否是文件: false 
文件操作

程序案例:

File file = new File("D:\\newFile.txt");if (file.exists()) {file.delete(); // 删除当前文件,如果是文件夹,要确保文件夹内容为空。
}
boolean f = file.createNewFile();if (f) {// 如果文件创建成功System.out\.println("是否是隐藏问: " + file.isHidden());System.out\.println("最后一次修改时间: " + new Date(file.lastModified()));System.out\.println("是否可读: " + file.canRead());System.out\.println("是否可写: " + file.canWrite());System.out\.println("是否可执行: " + file.canExecute());System.out\.println("磁盘总空间大小: "+ file.getTotalSpace()/1024/1024/1024+"G");System.out\.println("磁盘可用空间大小: "+file.getUsableSpace()/1024/1024/1024+"G");System.out\.println("磁盘剩余空间大小: "+ file.getFreeSpace()/1024/1024/1024+"G");
}
修改文件名称
file.renameTo(new File("D:\\modify.txt"));	
System.out\.println("文件名称: "+ file.getName());
File nFile = new File("D:\\modify.txt");
System.out.println("修改文件名: "+ file.renameTo(nFile));

程序运行结果:

是否是隐藏问: false
最后一次修改时间: Tue Jan 25 14:28:29 CST 2022
是否可读: true
是否可写: true
是否可执行: true
磁盘总空间大小: 429G
磁盘可用空间大小: 424G
磁盘剩余空间大小: 424G
修改文件名: true
文件夹、文件访问

程序案例:

File file = new File("C:\\");
String[] fs = file.list();
File[] files = file.listFiles();for(File f: files) {System.out\.println(f.getName());
}

程序运行结果(部分):

eclipse
hiberfil.sys
Intel
pagefile.sys
PerfLogs
Program Files

流的概念

流是个抽象的概念,是\对输入输出设备的抽象\,Java程序中,对于数据的输入/输出操作都是以“流”的方式进行。设备可以是文件,网络,内存等。

1.2.1 输入、输出流

提输入、输出是相对于\内存\的操作而言。

imgimg

imgimg

字节流、字符流

字节流–传输过程中,传输数据的最基本单位是字节的流。

字符流–传输过程中,传输数据的最基本单位是字符的流。

1.2.3 流的层次结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

imgimg

1.3 字节流

以字节为(8bits)为单位进行IO操作,一般用来处理二进制文件(例如:图片、声音、视频等)。

1.3.1 字节输入流

img

1.3.2 字节输出流

img

程序案例:

程序案例:使用字节流完成流的拷贝功能。

InputStream in = new FileInputStream("c:\\jdk-8u311-windows-x64.exe");OutputStream out = new FileOutputStream("d:\\jdk-8u311-windows-x64.exe");int n = 0;
long t1 = System.currentTimeMillis();while ((n = in.read()) != -1) {out.write(n);}
long t2 = System.currentTimeMillis();
out.close();
in.close();System.out\.println("字节拷贝,耗时: " + (t2 - t1)+"ms");程序运行结果:                                字节拷贝,耗时: 439897ms

字节流的缓存

如果按照一个字节一个字节的进行IO操作,字节的入和出的速度不是对等的。比如我们在工地经常看到传递砖块的操作,一般不是一个砖接一个砖传递,而是几块砖头放在一起传递。在流操作中,经常用到的技术是定义一个缓存区域,积累到一定数量后,一次性发送给接收端。

img

程序案例: 使用缓存优化字节流完成流的拷贝功能

InputStream in = new FileInputStream("c:\\jdk-8u311-windows-x64.exe");OutputStream out = new FileOutputStream("d:\\jdk-8u311-windows-x64.exe");long t1 = System.currentTimeMillis();
byte[] buffer = new byte[1024];
while (in.read(buffer) != -1) {out.write(buffer);
}
long t2 = System.currentTimeMillis();
out.close();
in.close();
System.out\.println("字节缓存拷贝,耗时: " + (t2 - t1)+"ms");

程序运行结果:

字节缓存拷贝,耗时: 586ms

1.4 字符流

以字符为单位的IO操作,一般用来操作文本信息。

1.4.1 字符输入流

img

程序案例:

BufferedReader in =
new BufferedReader(
new FileReader("D:\\java-workspace\\javaio\\src\\javaio\\CopyDemo.java"));
String line = null;
int index = 0;while ((line = in.readLine()) != null) {System.out\.println((++index) +"\t"+ line);}		in.close();

程序运行结果(部分):

1	package javaio;
2  
3	import java.io.FileInputStream;
4	import java.io.FileOutputStream;
5	import java.io.IOException;
6	import java.io.InputStream;
7	import java.io.OutputStream;

1.4.2 字符输出流

img

程序案例:

PrintWriter pw = new PrintWriter(new FileWriter("D:\\pw.html"));
pw.println("<h1>你好,java IO 流</h1>");
pw.println("<h2>java爱好者</h2>");
pw.println("<h3>测试字符输出流的用法</h3>");		
pw.flush();
pw.close();

程序运行结果:

img

流的异常捕获方案

try … catch … finally

一般流的异常都是可检查异常,所有在开发过程中需要强制使用异常捕获流程处理。一般打开流对象后,如果不关闭会一直占用一个通道(就像开辟了几条通道进行数据传输,其中一条已经完成,但是不释放则会一直占用此通道,造成资源浪费)。一般开发中我们会在finally语句块调用流的关闭语句,以此释放流资源。

程序案例:

InputStream in = null;
try{in = new FileInputStream(“D:\\in.dat”);
}catch(IOException e){//异常信息
}finally{
in.close(); //关闭流对象
}

try … with … resource

如果打开了外部资源(文件、数据库连接、网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们。因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在编程时确保在正确的时机关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用,数据库连接过多导致连接池溢出等诸多很严重的问题。

对于实现了Closeable接口的类,可以使用try…with…resource处理异常。

程序案例:

try(InputStream in = new FileInputStream(D:/abc.txt”)){//异常信息
}catch(IOException e){//捕获异常
}

序列化

序列化:一个Java对象作一下“变换”,变成\字节序列\,这样一来方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,另外变换成字节序列也更便于网络运输和传播

反序列化:把字节序列恢复为原先的Java对象。

img

实现序列化接口的对象,有一个特殊常量serialVersinUID

img

提示: static修饰的不会被序列化,transient修饰的不会被序列化。

对象流

对象流:有的时候,我们可能需要将内存中的对象持久化到硬盘上,或者将硬盘中的对象信息读到内存中,这个时候我们需要使用对象输入输出流。

当使用对象流写入或者读取对象的时候,必须保证该对象是序列化的,这样是为了保证对象能够正确的写入文件,并能够把对象正确的读回程序。

(1) ObjectInputStream: 字节对象输入流

(2) ObjectOutputStream: 字节对象输出流

程序案例((ObjectInputStream):

public class Car implements Serializable{private static final long serialVersionUID\ = 1L;private String brand;private String color;private double price; public Car(String brand, String color, double price) {this.brand = brand;this.color = color;this.price = price;}//其它代码省略
}
.....ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\car.dat"));
Car car = new Car("BMW", "黑色", 1200000.00);
out.writeObject(car);
out.flush();
out.close();

程序运行结果:

img

程序案例(ObjectOutputStream):

ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\car.dat"));
Car car = (Car) in.readObject();	
System.out\.println(car);
in.close();

程序运行结果:

Car [brand=BMW, color=黑色, price=1200000.0]

序列化接口

Serializable是一个标记性接口,没有实现任何内容,只是告诉JVM当前对象需要序列化。

public interface Serializable {}

日志

日志概念

日志是一种记录、跟踪程序运行的技术。作用主要在以下三个方面:

调试

在Java项目调试时,查看栈信息可以方便地知道当前程序的运行状态,输出的日志便于记录程序在之前的运行结果。

错误定位

项目在运行一段时候后,可能由于数据问题,网络问题,内存问题等出现异常。这时日志可以帮助开发或者运维人员快速定位错误位置,提出解决方案。

数据分析

日志中蕴含了大量的用户数据,包括点击行为,兴趣偏好等,用户画像对于公布下一步的战略方向有一定指引作用。

日志级别

(1) ALL: 最低等级的,用于打开所有日志记录。

(2) TRACE: 很低的日志级别,一般不会使用。

(3) DEBUG: 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于打印一些调试信息。

(4) WARN: 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员一些提示。

(5) INFO: 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息。这个用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。

(6) ERROR: 指出虽然发生错误事件,但任然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。

(7) FATAL: 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误。

log4j

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

日志配置
Loggers

Loggers组件在此系统中被分为五个级别:DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR < FATAL,分别用来指定这条日志信息的重要程度Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR和FATAL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。

Appenders

禁用和使用日志请求只是Log4j的基本功能,Log4j日志系统还提供许多强大的功能,比如允许把日志输出到不同的地方,如控制台(Console)、文件(Files)等,可根据天数或者文件大小产生新的文件,可以以流的形式发送到其它地方等等。

Layouts

Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。

PatternLayout格式参数如下表:

序号格式含义
1%p输出日志信息的优先级:DEBUG,INFO,WARN,ERROR,FATAL。
2%d输出日志时间点的日期或时间。默认格式为ISO8601,也可以在其后指定格式。%d{yyyy/MM/dd HH:mm:ss SSS}。
3%r输出自应用程序启动到输出该log信息耗费的毫秒数。
4%t输出产生该日志事件的线程名。
5%l输出日志事件的发生位置,相当于%C%M(%F%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:testLog4j.java:
6%c输出日志信息所属的类目,通常就是所在类的全名。
7%M输出产生日志信息的方法名
8%F输出日志消息产生时所在的文件名称
9%L输出代码中的行号
10%m输出代码中指定的具体日志位置
11%n输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”。
日志使用

配置文件: 在src定义一个properties文件: log4j.properties

配置文件案例

log4j.rootLogger = DEBUG,Console,infoFile
log4j.appender.Console = org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target = System.out
log4j.appender.Console.Threshold = DEBUG
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
log4j.appender.infoFile = org.apache.log4j.FileAppender
log4j.appender.infoFile.File=D:/logs/test.log
log4j.appender.infoFile.Threshold = DEBUG
log4j.appender.infoFile.layout = org.apache.log4j.PatternLayout
log4j.appender.infoFile.layout.ConversionPattern=[%c] - %m%n

程序案例:

Logger.getLogger(Logger.class).debug("测试log4j日志...");

NIO编程

java.nio全称java non-blocking IO(实际上是 new io),是指JDK 1.4 及以上版本里提供的新api(new IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

NIO组件

img

缓冲区

(缓冲区(Buffer): 本质上是一个可以写入数据的内存块,然后可以再次读取,该对象提供了一组方法,可以更轻松地使用内存。

img

通道(Channel):

channel(通道)可以同时进行读写,而流只能读或者只能写。

通道可以实现异步读写数据。

通道可以从缓冲读数据,也可以写数据到缓冲。

channel提供了一个map()方法,可以直接将数据映射到内存中。

img

选择器(Selector)

可以检测多个NIO channel,看看读或者写事件是否就绪。多个\Channel\以事件的方式可以注册到同一个Selector,从而达到用一个线程处理多个请求成为可能。

img

NIO编程

程序案例:

String fileName = "D:\\java-workspace\\javaio\\src\\javaio\\ReaderDemo.java";RandomAccessFile raf = new RandomAccessFile(fileName, "rw");/** 创建Channel*/		
FileChannel inChannel = raf.getChannel();/** 创建缓存区,缓存48个字节*/		
ByteBuffer buffer = ByteBuffer.allocate(48);/*** 读取48个字符到buffer缓存中* 检查是否到达文件的末尾(-1表示末尾)*/		
while((bytesRead = inChannel.read(buffer)) !=-1) {/*** 把buffer当前位置更改为buffer缓冲区的第一个位置*/buffer.flip();		while(buffer.hasRemaining()) {/*** 从buffer当前位置一个字节、一个字节的读取缓存区数据*/System.out\.print((char)buffer.get());}/*** 清空buffer,设置到buffer缓冲区的第一个位置*/buffer.clear();}
raf.close(); 

程序运行结果(部分):

package javaio;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class ReaderDemo { public static void main(String[] args) throws IOException {:::

BIO/AIO/NIO概念

img

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

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

相关文章

Cocos2d-x 4.0 工程首次建立与编译(Mac m1)

Mac m1芯片下将cocos2d-x升级至4.0版本后&#xff0c;官方剔除了不同平台的工程以及变更了编译方式&#xff0c;直接使用cmake构建&#xff0c;需要做一些前置的准备工作。 环境准备&#xff1a; 项 版本 备注 MacOS10.3 or laterpython2.7.16(建议>2.7.10)cmake3.29.3Do…

自动驾驶场景下TCP协议参数优化调整案例分享

RTT 往返时间&#xff0c;从tcp协议栈决定发包&#xff0c;到收到回包的时间。 包含本地驱动&#xff0c;网卡硬件&#xff0c;网线&#xff0c;交换机&#xff0c;收包方处理的耗时。需注意如果开了delayed ack&#xff0c;协议栈未做特殊处理&#xff08;默认没做&#xff…

探索交互的本质:从指令到界面的演进与Linux基础指令的深入剖析

目录 1.指令 vs 界面//选读 1.1交互的需求 满足需求的第一阶段-指令 满足需求的第二阶段-界面 1.2 指令 和 界面交互 区别 2.操作系统介绍 2.1 举例说明 驱动软件层 2.2 为什么要有操作系统&#xff1f; 0x03 为什么要进行指令操作&#xff1f; 3.Linux基本指令 l…

模型量化 剪枝bevfusion

量化 剪枝 shared mem 只在block内共享&#xff0c;device glob mem能够所有线程共享

从多线程设计模式到对 CompletableFuture 的应用

大家好&#xff0c;我是 方圆。最近在开发 延保服务 频道页时&#xff0c;为了提高查询效率&#xff0c;使用到了多线程技术。为了对多线程方案设计有更加充分的了解&#xff0c;在业余时间读完了《图解 Java 多线程设计模式》这本书&#xff0c;觉得收获良多。本篇文章将介绍其…

重塑IT审计的未来:数智化审计赋能平台的创新与实践

重塑IT审计的未来&#xff1a;数智化审计赋能平台的创新与实践 一、当前企业开展IT审计面临的挑战 随着信息技术的快速发展、企业数字化转型的持续深入&#xff0c;以及网络安全合规要求的不断增强&#xff0c;企业开展新型IT审计重要性越来越突出&#xff0c;但实施难度却越来…

统计信号处理基础 习题解答10-16

题目&#xff1a; 对于例10.1&#xff0c;证明由观察数据得到的信息是&#xff1a; 解答&#xff1a; 基于习题10-15的结论&#xff0c;&#xff0c;那么&#xff1a; 而根据习题10-15的结论&#xff1a; 此条件概率也是高斯分布&#xff0c;即&#xff1a; 根据相同的计算&a…

一文带你搞清楚AI领域的高频术语!RAG、Agent、知识库、向量数据库、知识图谱、Prompt...都是在讲啥?

随着AI人工智能技术的不断发展&#xff0c;一些领域有关的概念和缩写总是出现在各种文章里&#xff0c;像是Prompt Engineering、Agent 智能体、知识库、向量数据库、RAG 以及知识图谱等等&#xff0c;但是这些技术和概念也的的确确在AI大模型的发展中扮演着至关重要的角色。这…

使用 3D 图形 API 在 C# 中将 PLY 转换为 OBJ

OBJ和PLY是一些广泛使用的 3D 文件格式&#xff0c;易于编写和读取。这篇博文演示了如何以编程方式在 C# 中将 PLY 转换为 OBJ。此外&#xff0c;它还介绍了一种用于 3D 文件格式转换的在线3D 转换器。是的&#xff0c;Aspose.3D for .NET为程序员和非程序员提供了此功能来执行…

Day52 代码随想录打卡|二叉树篇---二叉搜索树中的众数

题目&#xff08;leecode T501&#xff09;&#xff1a; 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 如果树中有不止一个众数&#xff0c…

【深度学习】基于EANet模型的图像识别和分类技术

1.引言 1.1.EANet模型简介 EANet&#xff08;External Attention Transformer&#xff09;是一种深度学习模型&#xff0c;它结合了Transformer架构和外部注意力机制&#xff0c;特别适用于图像分类等计算机视觉任务。以下是关于EANet的详细解释&#xff1a; 1.1.1 定义与背…

Node.js版本管理工具-NVM

在开发 Node.js 项目时&#xff0c;经常会遇到需要切换不同版本的 Node.js 的情况。为了方便管理和切换各个版本&#xff0c;我们可以使用一些 Node.js 版本管理工具。 Node Version Manager&#xff1a;简称NVM&#xff0c;最流行的 Node.js 版本管理工具之一。它允许我们在同…

计算机体系结构重点学习(一)

从外部I/O与上层应用交互的整体软硬件过程 上层应用发出I/O请求&#xff1a;上层应用程序&#xff0c;如一个文本编辑器、网络浏览器或者任何软件应用&#xff0c;需要读取或写入数据时&#xff0c;会通过调用操作系统提供的API&#xff08;如文件操作API、网络操作API等&…

Python学习打卡:day04

day4 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day428、while 循环的嵌套应用29、while 循环案例 — 九九乘法表补充知识示例&#xff1a;九九乘法表 30、for 循环基本语法while 和 for 循环对比f…

Android屏幕旋转流程(1)

&#xff08;1&#xff09;Gsensor的注册和监听 App -->I2C过程&#xff1a;App通过SensorManager.getSystemServer调用到SystemSensorManager&#xff0c;SystemSensorManager通过jni调用到SensorManager.cpp&#xff0c;后通过binder调用到SensorService。SensorService通…

SpringBoot+Maven笔记

文章目录 1、启动类2、mapper 接口3、控制类4、补充&#xff1a;返回数据时的封装5、补充a、mybatisplus 1、启动类 在启动类上加入MapperScan扫描自己所写的mapper接口 package com.example.bilili_springboot_study;import org.mybatis.spring.annotation.MapperScan; impo…

CorelDraw 2024软件安装包下载 丨不限速下载丨亲测好用

​简介&#xff1a; CorelDRAW Graphics Suite 订阅版拥有配备齐全的专业设计工具包&#xff0c;可以通过非常高的效率提供令人惊艳的矢量插图、布局、照片编辑和排版项目。价格实惠的订阅就能获得令人难以置信的持续价值&#xff0c;即时、有保障地获得独家的新功能和内容、…

生产中的 RAG:使你的生成式 AI 项目投入运营

作者&#xff1a;来自 Elastic Tim Brophy 检索增强生成 (RAG) 为组织提供了一个采用大型语言模型 (LLM) 的机会&#xff0c;即通过将生成式人工智能 (GenAI) 功能应用于其自己的专有数据。使用 RAG 可以降低固有风险&#xff0c;因为我们依赖受控数据集作为模型答案的基础&…

【菜狗学前端】uniapp(vue3|微信小程序)实现外卖点餐的左右联动功能

记录&#xff0c;避免之后忘记...... 一、目的&#xff1a;实现左右联动 右->左 滚动&#xff08;上拉/下拉&#xff09;右侧&#xff0c;左侧对应品类选中左->右 点击左侧品类&#xff0c;右侧显示对应品类 二、实现右->左 滚动&#xff08;上拉/下拉&#xff09;右…

什么是深拷贝;深拷贝和浅拷贝有什么区别;深拷贝和浅拷贝有哪些方法(详解)

目录 一、为什么要区别深拷贝和浅拷贝 二、浅拷贝 2.1、什么是浅拷贝 2.2、浅拷贝的方法 使用Object.assign() 使用展开运算符(...) 使用数组的slice()方法&#xff08;仅适用于数组&#xff09; 2.3、关于赋值运算符&#xff08;&#xff09; 三、深拷贝 3.1、什么是…