输入输出(I/O):熟悉 Java 的 I/O 类库,尤其是 NIO 和文件操作
输入输出(I/O):熟悉 Java 的 I/O 类库,尤其是 NIO 和文件操作
在 Java 中,I/O(输入输出)操作是开发中非常重要的一部分,用于与文件、网络和其他数据流交互。Java 提供了传统的 I/O(基于流的 I/O)和更现代的 NIO(非阻塞 I/O)两种方式。本文将带你熟悉 Java I/O 的核心类库,并重点介绍 NIO 的特点及文件操作相关内容。
一、Java I/O 的基本概念
-
1.1 流(Stream)
流(Stream)是 Java I/O 的核心概念,代表了数据传输的路径。在 Java 中,流的概念被分为 输入流 和 输出流,并且每种流都可以分为字节流和字符流。
- 输入流(Input Stream): 从数据源读取数据。
- 输出流(Output Stream): 向目标写入数据。
字节流与字符流
- 字节流(Byte Stream): 以字节为单位进行数据读写。适用于所有类型的I/O操作,包括文本、图像、音频等。
InputStream和OutputStream是字节流的根类。- 常用类:
FileInputStream,FileOutputStream,BufferedInputStream,BufferedOutputStream。
- 字符流(Character Stream): 以字符为单位进行数据读写,适用于文本文件的处理。
Reader和Writer是字符流的根类。- 常用类:
FileReader,FileWriter,BufferedReader,BufferedWriter。
示例代码:字节流和字符流的使用
// 使用字节流读取文件 import java.io.*;public class ByteStreamExample {public static void main(String[] args) throws IOException {FileInputStream inputStream = new FileInputStream("example.txt");int byteData;while ((byteData = inputStream.read()) != -1) {System.out.print((char) byteData); // 输出文件内容}inputStream.close();} }// 使用字符流读取文件 import java.io.*;public class CharStreamExample {public static void main(String[] args) throws IOException {FileReader fileReader = new FileReader("example.txt");BufferedReader bufferedReader = new BufferedReader(fileReader);String line;while ((line = bufferedReader.readLine()) != null) {System.out.println(line); // 输出文件内容}bufferedReader.close();} }
二、常见的 Java I/O 类库
2.1 文件操作类
-
File类:是 Java 早期提供的文件操作类,提供了创建、删除文件和目录的功能。
- 优点:操作简单。
- 缺点:功能有限,不支持高级操作如复制、移动等。
示例代码:
import java.io.File;public class FileExample {public static void main(String[] args) {File file = new File("example.txt");// 创建文件try {if (file.createNewFile()) {System.out.println("File created: " + file.getName());} else {System.out.println("File already exists.");}} catch (Exception e) {e.printStackTrace();}// 删除文件if (file.delete()) {System.out.println("Deleted the file: " + file.getName());}}
}
-
Files类:Java 7 引入的 NIO 类,提供了文件操作的高级接口,支持复制、移动、删除等操作。
- 优点:功能丰富,支持文件复制、移动、文件权限操作等。
- 常用方法:
copy(),move(),delete(),exists(),createDirectory()等。
示例代码:使用 Files 类进行文件复制
import java.nio.file.*;public class FilesExample {public static void main(String[] args) {Path source = Paths.get("source.txt");Path target = Paths.get("target.txt");try {Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);System.out.println("File copied successfully.");} catch (Exception e) {e.printStackTrace();}}
}
三、Java NIO 的特点与使用
3.1 什么是 NIO?
NIO(New I/O)是 Java 1.4 引入的一组 API,旨在提供比传统 I/O 更高效的操作。它支持基于缓冲区和通道的 I/O 方式,能有效提高性能。
- 传统 I/O: 基于流,采用阻塞方式,即每次只能处理一个连接。
- NIO: 基于缓冲区和通道,支持非阻塞操作,并且能够处理多个 I/O 操作。
3.2 NIO 的核心组件
- 通道(Channel): NIO 中的通道类似于传统 I/O 中的流,但通道支持双向数据传输。常见的通道类包括:
FileChannel:用于文件的读取和写入。SocketChannel:用于网络的客户端和服务端通信。ServerSocketChannel:用于创建服务端套接字通道。
- 缓冲区(Buffer): NIO 中的数据读写都通过缓冲区进行,避免了流的每次读取。常见的缓冲区包括:
ByteBuffer:用于字节数据的处理。CharBuffer:用于字符数据的处理。
- 选择器(Selector): 选择器允许单个线程同时监控多个通道的 I/O 操作。常用于网络 I/O。
3.3 NIO 文件操作示例
示例:使用 FileChannel 和 ByteBuffer 读写文件
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;public class FileChannelExample {public static void main(String[] args) {try (RandomAccessFile file = new RandomAccessFile("example.txt", "rw");FileChannel channel = file.getChannel()) {// 写数据到文件ByteBuffer buffer = ByteBuffer.allocate(48);buffer.put("Hello NIO!".getBytes());buffer.flip();channel.write(buffer);// 读数据从文件buffer.clear();channel.read(buffer);buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}} catch (Exception e) {e.printStackTrace();}}
}
3.4 非阻塞 I/O 示例
示例:使用 Selector 实现多路复用
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;public class NIONonBlockingExample {public static void main(String[] args) throws IOException {Selector selector = Selector.open();ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false);serverChannel.bind(new InetSocketAddress(8080));serverChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Iterator<SelectionKey> keys = selector.selectedKeys().iterator();while (keys.hasNext()) {SelectionKey key = keys.next();keys.remove();if (key.isAcceptable()) {SocketChannel client = serverChannel.accept();client.configureBlocking(false);client.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {SocketChannel client = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(256);client.read(buffer);System.out.println("Received: " + new String(buffer.array()).trim());}}}}
}
四、传统 I/O 与 NIO 的对比
| 特性 | 传统 I/O | NIO |
|---|---|---|
| 数据处理方式 | 基于流 | 基于缓冲区 |
| 阻塞模式 | 阻塞 I/O | 非阻塞 I/O 和多路复用 |
| 线程模型 | 每连接一个线程 | 单线程处理多个连接 |
| 性能 | 相对较低,适合小型系统 | 高性能,适合高并发场景 |
| 使用复杂度 | 简单易用 | 需要理解更多底层概念 |
| 适用场景 | 文件操作、小规模 I/O | 高并发网络、文件大数据处理 |
五、总结
-
通过本文,你了解了 Java I/O 的基础概念、常见类库及其用法,并深入探讨了 NIO 的核心特点与实际应用。在实际开发中:
- 传统 I/O 适用于小规模、简单的 I/O 场景,使用简单直观。
- NIO 更适合处理大规模、高并发的 I/O 场景,如高性能的网络服务器和大文件的异步处理。
希望通过本文的学习,你可以更好地理解和选择适合的 I/O 模型,以提升 Java 开发中的性能和效率!
相关文章:
输入输出(I/O):熟悉 Java 的 I/O 类库,尤其是 NIO 和文件操作
输入输出(I/O):熟悉 Java 的 I/O 类库,尤其是 NIO 和文件操作 在 Java 中,I/O(输入输出)操作是开发中非常重要的一部分,用于与文件、网络和其他数据流交互。Java 提供了传统的 I/O&…...
mysql建立主从集群
mysql建立主从集群需要多个mysql服务器,主从数据库是通过log日志来进行同步的,所以需开启log-bin。本地安装多个mysql参考底部 主数据库配置 打开主数据库my.ini配置文件,给其配置server_id1 [mysqld] port3306 basedirD:/phpstudy_pro/1/…...
Python AI 教程之四:无监督学习
什么是无监督学习? 无监督学习是机器学习的一个分支,用于处理未标记的数据。与监督学习(其中数据被标记为特定类别或结果)不同,无监督学习算法的任务是在不了解数据含义的情况下寻找数据中的模式和关系。这使得无监督学习成为探索性数据分析的强大工具,其目标是了解数据…...
ReactiveStreams、Reactor、SpringWebFlux
注意: 本文内容于 2024-12-28 21:22:12 创建,可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容,请访问原文地址:ReactiveStreams、Reactor、SpringWebFlux。感谢您的关注与支持! ReactiveStreams是…...
Qt 的信号槽机制详解:之信号槽引发的 Segmentation Fault 问题拆析(下)
Qt 的信号槽机制详解:之信号槽引发的 Segmentation Fault 问题拆析(下) 前言一. 信号槽的误用导致崩溃的常见原因1.信号和槽连接的对象被提前释放案例解决方法 2.参数类型不匹配案例解决方法 3. 多线程信号槽使用不当案例解决方法 4. 信号重复…...
opencv(cpp) Mat使用总结
opencv访问矩阵的通道数 #include <opencv2/opencv.hpp> #include <iostream>int main() {// 创建一个3通道的彩色图像(例如,BGR格式)cv::Mat colorImage cv::Mat::zeros(100, 100, CV_8UC3);// 创建一个单通道的灰度图像cv::M…...
【Hackthebox 中英 Write-Up】Web Request | 分析 HTTP 请求和响应
欢迎来到我的writeup分享!我希望大家不要只关注结果或答案,而是通过耐心阅读,尝试逆向工程理解背后的运作原理。在这里,你不仅能找到解题的思路,还能学到更多与Hack The Box等平台相关的技术和技巧,期待与你…...
c#多线程之生产者-消费者模型
在 C# 中实现 生产者-消费者模式,通常需要多个线程来处理数据的生产和消费。我们可以使用 Queue<T> 来作为存储数据的队列,并使用 Thread、Mutex 或 Monitor 来确保线程安全。BlockingCollection<T> 是 C# 提供的一个线程安全的集合…...
Spring Boot中幂等性的应用
在 Spring Boot 中,幂等性是实现分布式系统设计和接口调用的一个重要概念,尤其在高并发、分布式环境下,确保接口重复调用不会引发系统数据异常至关重要。 幂等性概念 幂等性(Idempotence)是指一次请求和重复多次请求…...
【机器学习】分类
文章目录 1. 能否用回归解决分类问题2. 生成模型(概率生成)3. 判别模型(逻辑回归)4. 多分类问题 1. 能否用回归解决分类问题 二元分类 数据分布不规律,回归函数会尽量减少误差,导致不合理的偏移离分界较远…...
5.若依的角色权限控制
RBAC 基于角色的访问控制,通过角色来分配和管理用户的菜单权限。 修改课程管理的菜单到主类目下 新建角色并分配菜单 新建用户并分配角色 添加一个根菜单,父级为主类目...
Lumos学习王佩丰Excel第二十三讲:饼图美化与PPT图表
一、双坐标柱形图的补充知识 1、主次坐标设置 2、主次坐标柱形避让(通过增加两个系列,挤压使得两个柱形挨在一起) 增加两个系列 将一个系列设置成主坐标轴,另一个设成次坐标轴 调整系列位置 二、饼图美化 1、饼图美化常见设置 …...
安装winserver2008R2虚拟机步骤
一、服务器系统介绍 1.1什么是服务器? 服务器英文名称为“Server”,指的是网络环境下为客户机(Client)提供某种服务的专用计算机,服务器安装有网络操作系统(如Windows 2000 Server、Linux、Unix等)和各种服务器应用系统软件(如Web服务、电子…...
ACPI PM Timer
ACPI PM Timer 概述: ACPI PM Timer是一个非常简单的计时器,它以 3.579545 MHz 运行,在计数器溢出时生成系统控制中断(SCI)。它精度较低,建议使用其他定时器,如HPET或APIC定时器。 检测ACPI P…...
Linux 和设备树
“开放固件设备树”,简称 Devicetree (DT),是一种用于描述硬件的数据结构和语言。更具体地说,它是操作系统可读取的硬件描述,因此操作系统无需对机器的详细信息进行硬编码。 从结构上看,DT 是一棵树,或具有…...
Qt仿音乐播放器:QFileDialog添加本地文件
一、套路 QFileDialog fileDialog(this);// 创建对话框,并设置父元素;fileDialog.setWindowTitle("添加本地下载的音乐");//设置窗口标题//设置文件对话框的默认打开路径 QString projectPathQDir::currentPath();//获取当前目录 QDir dir(pr…...
Odoo 引用字段 fields.Reference:动态关系的选择器
在 Odoo 模型开发中,关系型字段是构建复杂应用的基础。 然而,传统的 m2o、o2m 和 m2m 字段需要在模型定义时就明确指定关系的目标模型,这在某些场景下会显得不够灵活。 为了解决这个问题,Odoo 提供了 fields.Reference 引用字段&a…...
Android笔试面试题AI答之Android基础(6)
Android入门请看《Android应用开发项目式教程》 文章目录 1.Android Studio版本与Gradle版本有什么关联?**1. Gradle 的作用****2. Android Studio 与 Gradle 的关系****3. 版本对应关系****4. 如何查看和修改版本****查看当前版本****修改版本** **5. 版本不兼容的…...
C# 中的记录类型简介 【代码之美系列】
🎀🎀🎀代码之美系列目录🎀🎀🎀 一、C# 命名规则规范 二、C# 代码约定规范 三、C# 参数类型约束 四、浅析 B/S 应用程序体系结构原则 五、浅析 C# Async 和 Await 六、浅析 ASP.NET Core SignalR 双工通信 …...
利用Java爬虫速卖通按关键字搜索AliExpress商品
在这个信息爆炸的时代,数据的价值日益凸显。对于电商领域的从业者来说,能够快速获取商品信息成为了一项重要的技能。速卖通(AliExpress)作为全球领先的跨境电商平台,拥有海量的商品数据。本文将介绍如何使用Java语言编…...
OpenClaw内容创作:nanobot镜像辅助生成技术文章大纲与初稿
OpenClaw内容创作:nanobot镜像辅助生成技术文章大纲与初稿 1. 为什么需要自动化内容创作工具 作为一名技术博主,我经常面临这样的困境:明明积累了大量实践经验,却总是卡在"如何把零散知识点组织成结构化的文章"这个环…...
避坑指南:在Windows 11上用Docker Compose一键部署Casdoor(含MySQL和持久化配置)
Windows 11容器化部署Casdoor全攻略:告别环境配置噩梦 "明明按照文档一步步操作,为什么我的Casdoor就是跑不起来?"这可能是许多Windows开发者初次接触开源身份认证系统时的共同困惑。传统部署方式需要手动配置Go、Node.js、Yarn、…...
Stash缓存机制终极指南:5个配置技巧大幅提升媒体访问速度
Stash缓存机制终极指南:5个配置技巧大幅提升媒体访问速度 【免费下载链接】stash An organizer for your porn, written in Go. Documentation: https://docs.stashapp.cc 项目地址: https://gitcode.com/gh_mirrors/st/stash Stash是一款用Go语言开发的媒体…...
SillyTavern角色系统全解析:从基础构建到高级定制
SillyTavern角色系统全解析:从基础构建到高级定制 【免费下载链接】SillyTavern LLM Frontend for Power Users. 项目地址: https://gitcode.com/GitHub_Trending/si/SillyTavern 引言:当AI角色拥有"灵魂" 想象一下,你正在…...
OFA-VE多模态推理实操手册:基于OFA-Large的语义对齐分析全流程
OFA-VE多模态推理实操手册:基于OFA-Large的语义对齐分析全流程 1. 引言:什么是视觉蕴含分析? 你有没有遇到过这样的情况:看到一张图片,然后有人用文字描述它,但你不太确定这个描述是否准确?或…...
实战应用解析:基于快马平台实现openclaw切换模型赋能电商数据爬取与可视化项目
最近在做一个电商数据分析的小项目时,发现不同环节对AI模型的需求差异很大。比如爬虫需要严谨的逻辑,而可视化则需要创意和美观。正好在InsCode(快马)平台上尝试了openclaw切换模型的功能,整个过程特别顺畅,分享下我的实战经验。 …...
8个智能脚本,让Illustrator设计效率提升10倍
8个智能脚本,让Illustrator设计效率提升10倍 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 设计效率的隐形杀手:你是否也在重复劳动? 每天花费…...
Qwen3-4B-Instruct-2507快速上手:手把手教你用Chainlit搭建可视化聊天界面
Qwen3-4B-Instruct-2507快速上手:手把手教你用Chainlit搭建可视化聊天界面 1. 准备工作与环境检查 1.1 了解Qwen3-4B-Instruct-2507模型 Qwen3-4B-Instruct-2507是阿里通义千问团队推出的轻量级语言模型,具有以下特点: 参数规模ÿ…...
1.NCM格式解密技术全解析:从原理到实战的音乐自由之路
1.NCM格式解密技术全解析:从原理到实战的音乐自由之路 【免费下载链接】ncmdump ncmdump - 网易云音乐NCM转换 项目地址: https://gitcode.com/gh_mirrors/ncmdu/ncmdump 问题引入:当音乐遭遇数字围栏 "花了千元订阅的无损音乐,…...
别再硬编码了!用CRMEB标准版的可视化定时任务,5分钟搞定自动发券
告别硬编码时代:CRMEB可视化定时任务实战指南 在电商系统开发中,定时任务就像一位不知疲倦的助手,默默处理着自动发券、订单状态更新、数据清理等重复性工作。但传统开发方式往往需要开发者手动编写Crontab配置或硬编码任务逻辑,不…...
