Java EE 初阶——文件操作和IO
1. 认识硬盘
硬盘(Hard Disk Drive,HDD)和固态硬盘(Solid State Drive,SSD)是计算机中用于存储数据的核心硬件设备,它们的性能和容量直接影响系统的运行效率和数据存储能力。
1. 机械硬盘(HDD,Hard Disk Drive)
- 核心原理:
通过旋转的磁盘盘片(铝合金或玻璃材质,表面涂有磁性材料)和磁头臂的机械运动来读写数据。数据以二进制形式存储在盘片的磁道和扇区中。 - 关键组件:
- 盘片:存储数据的物理载体,通常有多个叠放(单碟容量可达 2TB 以上)。
- 磁头:悬浮在盘片上方纳米级距离,负责读取和写入磁信号。
- 主轴电机:驱动盘片高速旋转(转速常见为 5400rpm、7200rpm,服务器级可达 10000rpm)。
- 控制电路:处理数据传输和指令控制。
- 优点:
- 单位容量成本低(性价比高),适合大容量存储(如监控、备份)。
- 技术成熟,使用寿命较长(正常使用 5-10 年)。
- 缺点:
- 机械结构易受震动损坏,读写速度较慢(顺序读写约 100-200MB/s,随机读写仅 0.1-1MB/s)。
- 启动速度和响应时间较长,影响系统开机和程序加载。
2. 固态硬盘(SSD,Solid State Drive)
- 核心原理:
基于闪存(NAND Flash)芯片存储数据,通过电子信号而非机械运动读写,无任何机械部件。 - 关键类型:
- SATA 接口 SSD:使用传统 SATA 协议,接口和外形与 HDD 兼容,速度约 500-600MB/s。
- NVMe SSD:通过 PCIe 接口连接(如 M.2 插槽),使用 NVMe 协议,速度可达 2000-7000MB/s(取决于 PCIe 版本,如 PCIe 3.0/4.0)。
- 关键组件:
- 闪存颗粒:存储数据的核心,分为 SLC(单层)、MLC(双层)、TLC(三层)、QLC(四层),密度依次增加但寿命和速度递减。
- 主控芯片:管理数据读写、磨损均衡、坏块管理等,影响性能和稳定性。
- 缓存芯片(部分高端型号):提升随机读写性能,降低延迟。
- 优点:
- 读写速度极快(尤其是随机读写),大幅提升系统响应速度和程序加载效率。
- 抗震抗摔,无机械故障风险,适合移动设备和高频读写场景。
- 低功耗、低发热、无噪音。
- 缺点:
- 单位容量成本高于 HDD(但价格逐年下降)。
- 闪存颗粒有写入次数限制(寿命由 TBW 或 DWPD 衡量,现代 SSD 通常足够日常使用)。
计算机在存储数据设备
设备 | 存储速度 | 空间大小 | 断电后数据是否丢失 | 价格 |
---|---|---|---|---|
cpu(寄存器,缓存) | 最快 | 最小 | 是 | 最贵 |
内存 | 其次 | 其次 | 是 | 其次 |
硬盘 | 最慢 | 最大 | 否 | 最便宜 |
2. 认识文件
文件是计算机系统中用于存储和组织数据的基本单位,它可以包含文本、图像、音频、视频、程序代码等各种形式的信息。
狭义:指存储在存储介质(如硬盘、U 盘)上的命名数据集合,具有明确的存储路径和物理形态,可被操作系统直接管理和访问。
广义:广义的文件是操作系统中一切可被抽象为 “输入 / 输出(I/O)对象” 的资源,不仅包括物理存储的文件,还涵盖硬件设备、进程间通信通道等虚拟实体。
文件的核心属性
-
名称:唯一标识符(可能包含扩展名)。
-
类型:由扩展名决定(如
.pdf
、.mp3
)。 -
大小:以字节(KB、MB、GB等)衡量。
-
存储位置:路径(如
C:\Users\Name\Documents
)。 -
权限:控制谁可以读、写或执行文件。
常见文件类型
类型 | 扩展名示例 | 用途 |
---|---|---|
文本文件 | .txt , .docx | 存储纯文本或格式化文字 |
图像文件 | .jpg , .png | 存储图片 |
音频文件 | .mp3 , .wav | 存储声音 |
视频文件 | .mp4 , .avi | 存储动态影像 |
可执行文件 | .exe , .sh | 运行程序或脚本 |
压缩文件 | .zip , .rar | 打包并压缩多个文件 |
文件的读写:
特性 | 顺序读写 | 随机读写 |
---|---|---|
访问方式 | 线性顺序(从头到尾) | 直接定位(任意位置) |
速度 | 连续读写时快 | 频繁跳转时可能慢(依赖存储介质) |
适用场景 | 日志文件、流媒体、备份 | 数据库、索引文件、视频编辑 |
分层目录结构(树形结构)
- 以 “根目录”(如 Windows 的
C:\
、Linux 的/
)为起点,通过创建子目录(文件夹)分级存储文件。 - 优势:层级清晰,便于按功能、类型或用户分组管理文件。
** 文件路径(File Path)** 是用于定位文件或目录在存储设备中具体位置的字符串表示。它类似于现实中的 “地址”,通过层级结构明确文件的位置,方便操作系统和用户访问、管理数据。
根据是否包含完整的根目录信息,文件路径可分为两类:
1. 绝对路径(Absolute Path)
- 定义:从文件系统的根目录开始,完整描述文件位置的路径,包含从根目录到目标文件的所有层级目录。
2. 相对路径(Relative Path)
- 定义:相对于 ** 当前工作目录(或指定参考目录)** 的路径,不包含根目录信息,从当前目录的子目录开始描述。
- 特点:
- 路径以
.
(当前目录)或..
(上级目录)开头,或直接从子目录名开始。 - 依赖于当前位置,位置变化时路径可能失效。
- 路径以
1. 文件分类
1. 文本文件
定义
文本文件是以 字符编码(如 ASCII、UTF-8、GBK 等) 存储数据的文件,内容可直接用文本编辑器(如记事本、Notepad++)查看和编辑,人类可读。
核心特点:
- 由 字符序列 组成(如字母、数字、符号)。
- 以 换行符(
\n
或\r\n
) 作为行分隔符。 - 存储时每个字符对应一个或多个字节(取决于编码,如 UTF-8 中一个汉字占 3 字节)
2. 二进制文件(Binary File)
定义
二进制文件以 二进制格式(0 和 1 的序列) 存储数据,内容无法直接用文本编辑器读懂,需特定软件解析。
核心特点:
- 数据按 字节(Byte)或特定数据结构 存储(如整数、浮点数、图像像素值)。
- 没有固定的编码规则,由应用程序自定义解析方式。
- 可存储任意类型的数据(文本、图像、音频、视频、程序等)。
如何判断文件类型?
- 看扩展名:常见扩展名(如
.txt
、.png
)可直接判断类型。 - 用工具查看:
- 文本文件:用记事本打开,内容可读。
- 二进制文件:用记事本打开会显示乱码(如
����JFIF��
),需用专用软件。
- 底层逻辑:文本文件本质是二进制文件的一种特例(用字符编码的二进制文件),但习惯上单独分类。
3. java 中文件操作
java 对于文件操作的 API
1. 针对文件系统的操作
管理文件和目录本身,包括不限于,创建文件,删除文件,文件重命名,列出目录内容... 右键目录可以进行的一系列操作
2. 针对文件内容操作
读文件 / 写文件
java 中针对文件系统操作,使用 File 类
i:input(输入)数据从键盘到 cpu
o:output(输出)
1. 属性
修饰符及类型 | 属性名 | 说明 |
---|---|---|
static String | pathSeparator | 依赖于系统的路径分隔符(如 Windows 为 ; ,Linux/macOS 为 : ) |
static char | pathSeparatorChar | 依赖于系统的路径分隔符(字符形式) |
static String | separator | 依赖于系统的名称分隔符(如 Windows 为 \ ,Linux/macOS 为 / ) |
static char | separatorChar | 依赖于系统的名称分隔符(字符形式) |
2. 构造方法
签名 | 说明 |
---|---|
File(String pathname) | 根据文件路径创建 File 实例,路径可以是绝对路径或相对路径 |
File(String parent, String child) | 根据父目录路径(字符串)和子文件路径创建实例 |
File(File parent, String child) | 根据父目录 File 对象和子文件路径创建实例 |
File(URI uri) | 通过文件的 URI 创建实例(如 file:///path/to/file.txt ) |
3. 常用方法
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
String | getParent() | 返回父目录的路径(字符串),若无父目录则返回 null |
File | getParentFile() | 返回父目录的 File 对象 |
String | getName() | 返回文件名或目录名 |
String | getPath() | 返回创建时的路径(绝对或相对路径) |
String | getAbsolutePath() | 返回绝对路径(若创建时为相对路径,则基于当前工作目录解析) |
String | getCanonicalPath() | 返回规范化的绝对路径(解析符号链接、. 、.. 等) |
boolean | exists() | 判断文件或目录是否存在 |
boolean | isDirectory() | 判断是否为目录 |
boolean | isFile() | 判断是否为普通文件 |
boolean | createNewFile() | 若文件不存在,则创建空文件(成功返回 true ) |
boolean | delete() | 删除文件或空目录(成功返回 true ) |
void | deleteOnExit() | 标记文件在 JVM 退出时删除(常用于临时文件) |
String[] | list() | 返回目录下的所有文件名和目录名(字符串数组) |
File[] | listFiles() | 返回目录下的所有文件和目录的 File 对象数组 |
boolean | mkdir() | 创建目录(仅当父目录已存在时) |
boolean | mkdirs() | 创建目录,必要时创建所有不存在的父目录(如 a/b/c ) |
boolean | renameTo(File dest) | 重命名文件或移动文件(跨目录时需谨慎使用) |
boolean | canRead() | 判断文件是否可读 |
boolean | canWrite() | 判断文件是否可写 |
boolean | isHidden() | 判断文件是否为隐藏文件 |
long | lastModified() | 返回文件最后修改时间(毫秒级时间戳) |
long | length() | 返回文件长度(字节数,目录返回值未定义) |
4. 代码示例
import java.io.File;
import java.io.IOException;public class IOFile {public static void main(String[] args) throws IOException {File file = new File("./test.txt");System.out.println(file.getName());//返回 FIle 对象的纯⽂件名称System.out.println(file.getParent());//返回 File 对象的⽗⽬录⽂件路径System.out.println(file.getPath());//返回 File 构造方法中的⽂件路径System.out.println(file.getAbsoluteFile());//返回 File 对象的绝对路径System.out.println(file.getCanonicalPath());//返回 File 对象的简化绝对路径}
}
import java.io.File;
import java.io.IOException;public class IOFile2 {public static void main(String[] args) throws IOException {File file = new File("./test.txt");System.out.println(file.exists());//判断 File 对象描述的⽂件是否真实存在System.out.println(file.isDirectory());//判断 File 对象代表的⽂件是否是⼀个⽬录System.out.println(file.isFile());//判断 File 对象代表的⽂件是否是⼀个普通⽂件System.out.println(file.createNewFile());//根据 File 对象,⾃动创建⼀个空⽂件}
}
import java.io.File;public class IOFile4 {public static void main(String[] args) {File file = new File("./test.txt");System.out.println(file.delete());//根据 File 对象,删除该⽂件File file1 = new File("./text.txt");file1.deleteOnExit();//根据 File 对象,标注⽂件将被删除,删除动作会到 JVM 运⾏结束时才会进⾏}
}
import java.io.File;
import java.util.Arrays;public class IOFile5 {public static void main(String[] args) {File file = new File(".");System.out.println(Arrays.toString(file.list()));//返回 File 对象代表的⽬录下的所有⽂件名System.out.println(Arrays.toString(file.listFiles()));}
import java.io.File;public class IOFile6 {public static void main(String[] args) {File file1 = new File("./a");File file2 = new File("./b/c/d");System.out.println(file1.mkdir());//创建单个目录System.out.println(file1.mkdirs());//创建层级目录System.out.println(file2.mkdir());System.out.println(file2.mkdirs());}
}
import java.io.File;public class IOFile7 {public static void main(String[] args) {File file1 = new File("./test.txt");File file2 = new File("./a/text.txt");System.out.println(file1.renameTo(file2));//重命名文件或移动文件位置}
}
4. ⽂件内容的读写⸺数据流
在计算机编程中,数据流(Stream) 是一种抽象概念,用于处理连续的、顺序的数据传输。在文件操作中,数据流提供了一种统一的方式来读写文件内容,而不必关心底层的硬件细节。
流分类
1. 流分类
-
字节流(Byte Stream):以 字节(8 位) 为单位处理数据,一次最少读写一个字节,适用于二进制文件(如图片、视频)。
- 输入:
InputStream
(抽象类)、FileInputStream
(文件输入流)。 - 输出:
OutputStream
(抽象类)、FileOutputStream
(文件输出流)。
- 输入:
-
字符流(Character Stream):以 字符(16 位,支持 Unicode) 为单位处理数据,适用于文本文件。
- 输入:
Reader
(抽象类)、FileReader
(文件字符输入流)。 - 输出:
Writer
(抽象类)、FileWriter
(文件字符输出流)。
- 输入:
读写文件内容的固定套路:
1. 打开文件
2. 读/写文件
3. 关闭文件
2. try-with-resources
try-with-resources
是 Java 7 引入的语法,用于 自动关闭实现了 AutoCloseable
或 Closeable
接口的资源,避免资源泄漏(如文件未关闭、数据库连接未释放等)。
try 中的() 可以定义多个对象,使用 ;分隔
1. I/O 流(字节流 & 字符流)
字节流
-
InputStream
/OutputStream
及其子类:-
FileInputStream
/FileOutputStream
-
ByteArrayInputStream
/ByteArrayOutputStream
-
BufferedInputStream
/BufferedOutputStream
-
DataInputStream
/DataOutputStream
-
ObjectInputStream
/ObjectOutputStream
-
字符流
-
Reader
/Writer
及其子类:-
FileReader
/FileWriter
-
CharArrayReader
/CharArrayWriter
-
BufferedReader
/BufferedWriter
-
InputStreamReader
/OutputStreamWriter
-
StringReader
/StringWriter
-
2. 数据库连接(JDBC)
-
Connection
、Statement
、PreparedStatement
、ResultSet
等 JDBC 资源
3. NIO(New I/O)资源
-
java.nio.channels
中的类:-
FileChannel
-
SocketChannel
-
ServerSocketChannel
-
Selector
-
4. 网络套接字(Socket)
-
Socket
、ServerSocket
5. 压缩/解压缩流
-
ZipInputStream
/ZipOutputStream
-
GZIPInputStream
/GZIPOutputStream
6. 自定义资源(实现 AutoCloseable
)
任何实现了 AutoCloseable
或 Closeable
接口的类都可以使用 try-with-resources
:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IOFile8 {public static void main(String[] args) throws IOException {InputStream f = new FileInputStream("./text.txt");//...f.close();//关闭文件,释放文件的相关资源}
}
-
如果在
//...
部分的代码抛出异常,close()
方法将不会被执行,导致文件句柄泄漏 -
未关闭的流会一直占用系统资源,可能导致最终文件描述符耗尽
如果要打开的文件不存在,会抛出异常
优化建议:使用 try-with-resources
自动管理资源,替代手动调用 close()
,并添加异常处理逻辑:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IOFile9 {public static void main(String[] args) {//使用 try-with-resources 自动管理资源try(InputStream f = new FileInputStream("./text.txt")){//...} catch (IOException e) {throw new RuntimeException(e);}}
}
改进后的优势
-
自动资源管理:
-
无论是否发生异常,流都会自动关闭
-
符合Java 7+的最佳实践
-
-
更好的异常处理:
-
捕获并处理了IOException
-
提供了错误信息输出
-
-
更健壮的代码:
-
避免了资源泄漏
-
提供了基本的错误诊断信息
-
4. 字节输入流
1. FileInputStream
(文件字节输入流)
构造方法:
构造方法 | 说明 |
---|---|
FileInputStream(String name) | 通过 文件名 创建输入流(文件不存在会抛出 FileNotFoundException ) |
FileInputStream(File file) | 通过 File 对象 创建输入流 |
FileInputStream(FileDescriptor fdObj) | 通过 文件描述符 创建输入流 |
2. ByteArrayInputStream
(字节数组输入流)
构造方法:
构造方法 | 说明 |
---|---|
ByteArrayInputStream(byte[] buf) | 从 字节数组 创建输入流 |
ByteArrayInputStream(byte[] buf, int offset, int length) | 从字节数组的 offset 位置开始读取 length 个字节 |
3. InputStream
(输入字节流基类)
方法 | 说明 | 示例 |
---|---|---|
int read() | 读取 1个字节(返回int ,范围0-255 ),如果到达文件末尾返回-1 | int data = inputStream.read(); |
int read(byte[] b) | 读取数据存入字节数组 b ,返回实际读取的字节数 | byte[] buffer = new byte[1024]; int len = inputStream.read(buffer); |
int read(byte[] b, int off, int len) | 从 off 位置开始读取 len 个字节存入数组 | inputStream.read(buffer, 0, 100); |
long skip(long n) | 跳过 n 个字节不读 | inputStream.skip(10); |
int available() | 返回可读的剩余字节数(不保证全部可用) | if (inputStream.available() > 0) { ... } |
void close() | 关闭流,释放资源 | inputStream.close(); |
boolean markSupported() | 是否支持 mark() 和 reset() | if (inputStream.markSupported()) { ... } |
void mark(int readlimit) | 标记当前位置,后续可用 reset() 返回 | inputStream.mark(1000); |
void reset() | 返回上次 mark() 的位置 | inputStream.reset(); |
1. 读取单个字节
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class IOFile10 {public static void main(String[] args) {try(InputStream f = new FileInputStream("./test.txt")){while(true){int n = f.read();//读取一个字节if(n==-1){break;}System.out.print(n+" ");//打印}} catch (IOException e) {throw new RuntimeException(e);}}
}
2. 读取字节数组
5. 字节输出流
1. FileOutputStream
(文件字节输出流)
构造方法:
构造方法 | 说明 |
---|---|
FileOutputStream(String name) | 通过 文件名 创建输出流(文件不存在会自动创建,文件存在时会清空文件内容) |
FileOutputStream(String name, boolean append) | append=true 表示 追加写入,否则覆盖 |
FileOutputStream(File file) | 通过 File 对象 创建输出流(文件不存在会自动创建,文件存在时会清空文件内容) |
FileOutputStream(File file, boolean append) | append=true 表示追加写入 |
FileOutputStream(FileDescriptor fdObj) | 通过 文件描述符 创建输出流 |
2. ByteArrayOutputStream
(字节数组输出流)
构造方法:
构造方法 | 说明 |
---|---|
ByteArrayOutputStream() | 创建默认大小(32字节)的缓冲区 |
ByteArrayOutputStream(int size) | 指定初始缓冲区大小 |
3. OutputStream
(输出字节流基类)
核心方法:
方法 | 说明 | 示例 |
---|---|---|
void write(int b) | 写入 1个字节(低8位,高24位忽略) | outputStream.write(65); (写入 'A' ) |
void write(byte[] b) | 写入整个字节数组 | outputStream.write(buffer); |
void write(byte[] b, int off, int len) | 写入字节数组 b 的 off 位置开始的 len 个字节 | outputStream.write(buffer, 0, 100); |
void flush() | 强制刷新缓冲区(确保数据写入目标) | outputStream.flush(); |
void close() | 关闭流 | outputStream.close(); |
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class IOFile12 {public static void main(String[] args) {try(OutputStream f = new FileOutputStream("./test.txt")){byte[] buffer = new byte[]{65,66,67,68};f.write(buffer);}catch(IOException e){throw new RuntimeException();}}
}
初始时,文件 test.txt 中的内容为,当我们运行到 OutputStream 时,会将文件中的内容全部清空,运行完毕后,文件中只存在我们刚刚写入的内容
,如果想保存之间文件的内容,追加写入,可以使用 append = true;
6. 字符输入流
1. FileReader
(文件字符输入流)
构造方法:
构造方法 | 说明 |
---|---|
FileReader(String fileName) | 通过 文件名 创建字符输入流 |
FileReader(File file) | 通过 File 对象 创建字符输入流 |
FileReader(FileDescriptor fd) | 通过 文件描述符 创建字符输入流 |
2. Reader
(输入字符流基类)
核心方法:
方法 | 说明 | 示例 |
---|---|---|
int read() | 读取 1个字符(返回int ,范围0-65535 ),文件末尾返回-1 | int ch = reader.read(); |
int read(char[] cbuf) | 读取字符存入数组 cbuf ,返回实际读取的字符数 | char[] buffer = new char[1024]; int len = reader.read(buffer); |
int read(char[] cbuf, int off, int len) | 从 off 位置开始读取 len 个字符存入数组 | reader.read(buffer, 0, 100); |
long skip(long n) | 跳过 n 个字符 | reader.skip(10); |
boolean ready() | 是否可读(不阻塞) | if (reader.ready()) { ... } |
void close() | 关闭流 | reader.close(); |
boolean markSupported() | 是否支持 mark() | if (reader.markSupported()) { ... } |
void mark(int readAheadLimit) | 标记当前位置 | reader.mark(1000); |
void reset() | 返回上次 mark() 的位置 | reader.reset(); |
7. 字符输出流
1. FileOutputStream
(文件字节输出流)
构造方法:
构造方法 | 说明 |
---|---|
FileOutputStream(String name) | 通过 文件名 创建输出流(文件不存在会自动创建) |
FileOutputStream(String name, boolean append) | append=true 表示 追加写入,否则覆盖 |
FileOutputStream(File file) | 通过 File 对象 创建输出流 |
FileOutputStream(File file, boolean append) | append=true 表示追加写入 |
FileOutputStream(FileDescriptor fdObj) | 通过 文件描述符 创建输出流 |
2. Writer
(输出字符流基类)
核心方法:
方法 | 说明 | 示例 |
---|---|---|
void write(int c) | 写入 1个字符(低16位) | writer.write('A'); |
void write(char[] cbuf) | 写入整个字符数组 | writer.write(buffer); |
void write(char[] cbuf, int off, int len) | 写入字符数组 cbuf 的 off 位置开始的 len 个字符 | writer.write(buffer, 0, 100); |
void write(String str) | 写入字符串 | writer.write("Hello"); |
void write(String str, int off, int len) | 写入字符串 str 的 off 位置开始的 len 个字符 | writer.write("Hello", 0, 3); (写入 "Hel" ) |
void flush() | 强制刷新缓冲区 | writer.flush(); |
void close() | 关闭流 | writer.close(); |
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class IOFile14 {public static void main(String[] args) {try(Writer f = new FileWriter("./test.txt")){String s = "你好,世界";f.write(s);char[] buffer = new char[]{'a','b','c'};f.write(buffer);}catch(IOException e){throw new RuntimeException();}}
}
初始时,文件 test.txt 中的内容为,当我们Writer 时,会将文件中的内容全部清空,运行完毕后,文件中只存在我们刚刚写入的内容
,如果想保存之间文件的内容,追加写入,可以使用 append = true;
8. 使用 Scanner 读取文件(本质是 InputStream)
1. Scanner 的构造方法(用于文件读取)
Scanner
可以通过多种方式构造,以下是 用于文件读取 的常见构造方法:
构造方法 | 说明 |
---|---|
Scanner(File source) | 从 File 对象创建 Scanner,读取文件内容 |
Scanner(File source, String charsetName) | 指定字符编码(如 "UTF-8" )读取文件 |
Scanner(InputStream source) | 从输入流(如 FileInputStream )读取 |
Scanner(InputStream source, String charsetName) | 从输入流读取,并指定字符编码 |
Scanner(Path source) | 从 Path 对象(NIO.2)读取文件 |
Scanner(Path source, String charsetName) | 从 Path 读取,并指定编码 |
2. Scanner 的核心方法(读取文件内容)
Scanner
提供了多种方法逐行、逐词或按数据类型读取内容:
方法 | 说明 | 示例 |
---|---|---|
boolean hasNextLine() | 是否还有下一行 | while (scanner.hasNextLine()) { ... } |
String nextLine() | 读取整行(包括换行符) | String line = scanner.nextLine(); |
boolean hasNext() | 是否还有下一个单词(默认按空格分隔) | while (scanner.hasNext()) { ... } |
String next() | 读取下一个单词 | String word = scanner.next(); |
int nextInt() | 读取下一个整数 | int num = scanner.nextInt(); |
double nextDouble() | 读取下一个浮点数 | double value = scanner.nextDouble(); |
boolean nextBoolean() | 读取下一个布尔值 | boolean flag = scanner.nextBoolean(); |
useDelimiter(String pattern) | 设置分隔符(正则表达式) | scanner.useDelimiter(",") (按逗号分隔) |
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;public class IOFile15 {public static void main(String[] args) {//从 ./test.txt 文件中读取文本内容。try(InputStream f = new FileInputStream("./test.txt")){Scanner scan = new Scanner(f);//使用刚才创建的输入流f初始化一个Scanner对象,用于读取文件内容。while(scan.hasNext()){// 检查是否还有更多内容可读String s = scan.next();//读取下一个"词"(默认以空白字符分隔)如果需要按行读取,应使用nextLine()System.out.println(s);//输出单词并换行}}catch(IOException e){throw new RuntimeException();}}
}
5. 练习
1. 给定一个文件名,去指定的目录中进行搜索,找到文件名匹配的结果,并打印出完整路径
import java.io.File;
import java.util.Scanner;public class IOFile16 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);System.out.print("请输入查找目录:");String rootPath = scan.nextLine();System.out.print("请输入要查找的文件名:");String fileName = scan.next();//根据路径,创建 File 实例File rootFile = new File(rootPath);//判断是否为目录if(!rootFile.isDirectory()){System.out.println("输入路径有误");return;}findFile(rootFile,fileName);}public static void findFile(File rootFile,String fileName){//列出当前目录中的所有目录及文件File[] files = rootFile.listFiles();//目录为空if(files==null){return;}for(File file:files){//System.out.println("当前路径为:"+file.getAbsoluteFile());//为目录,递归if(file.isDirectory()){findFile(file,fileName);}else if(file.isFile()){//为普通文件,比较if(file.getName().equals(fileName)){System.out.println("找到了,路径为:"+file.getAbsoluteFile());}}}}
}
2. 文件复制,把一个文件里的内容复制到另一个文件中
import java.io.*;
import java.util.Scanner;public class IOFile17 {public static void main(String[] args) throws IOException {Scanner scan = new Scanner(System.in);System.out.print("请输入要复制的文件名:");String fileName1 = scan.next();System.out.print("请输入存放复制内容的文件名:");String fileName2 = scan.next();File file1 = new File(fileName1);//判断文件是否存在if(!file1.isFile()){System.out.println("输入要复制文件名路径有误");return;}File file2 = new File(fileName2);//判断父目录是否存在if(!file2.getParentFile().isDirectory()){System.out.println("输入存放复制内容路径错误");return;}//复制try(InputStream f1 = new FileInputStream(file1);OutputStream f2 = new FileOutputStream(file2)){while(true){byte[] buffer = new byte[1024];int n = f1.read(buffer);if(n==-1){break;}f2.write(buffer,0,n);}}catch(IOException e){throw new RuntimeException();}}
}
3. 输入一个目录,输入一个要搜索的内容,在目录中搜索包含该内容的文件,打印路径
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;public class IOFile18 {public static void main(String[] args) {Scanner scan = new Scanner(System.in);System.out.print("请输入查找目录:");String rootPath = scan.nextLine();System.out.print("请输入要查找内容:");String s = scan.nextLine();//根据路径,创建 File 实例File rootFile = new File(rootPath);//判断目录是否存在if (!rootFile.isDirectory()) {System.out.println("输入目录错误");return;}//查找目标文件findFile(rootFile,s);}public static void findFile(File rootFile,String s){//列出当前目录中的所有目录及文件File[] files = rootFile.listFiles();if(files==null){return;}for(File file:files){//为目录,递归if(file.isDirectory()){findFile(file,s);}else if(file.isFile()){//为普通文件,查找目标内容findWhat(file,s);}}}public static void findWhat(File file,String s){try(InputStream f = new FileInputStream(file)){//存放文件内容StringBuilder stringBuilder = new StringBuilder();while (true){byte[] buffer = new byte[1024];int n = f.read(buffer);//读取if(n==-1){break;}String str = new String(buffer,0,n);stringBuilder.append(str);//将文件内容拼接}//判断是否包含文件内容if(stringBuilder.indexOf(s)!=-1){System.out.println("路径为:"+file.getAbsoluteFile());//打印文件路径}}catch (IOException e){throw new RuntimeException();}}
}