文件IO
文件 、IO
1. 认识输入输出
2. 认识文件
操作系统角度的文件 -> 软件资源 + 硬件资源 -> 文件
此处文件指 -> 保持在硬盘上的都是文件 -> 目录文件 (文件夹) + 普通文件 (文本文件.txt 、二进制文件.exe )
文本文件.txt -> 文本数据, 二进制数据组成的合法字符串
二进制文件.exe -> 就是二进制数据
如何区分 文本文件与二进制文件 -> 用记事本 (文本编辑器) 打开看看, 没乱码就是文本文件
3. 认识路径
路径的用处 -> 找文件
绝对路径, 此电脑 (忽略) -> D:/目录1/xxx.txt
相对路径 ->
4. 用 java代码操作文件
-> 针对文件系统进行操作 (创建 删除 重命名文件、创建目录)
创建文件:
查看代码
package io;
import java.io.File;
import java.io.IOException;
public class demo1 {
public static void main(String[] args) throws IOException {
// 指定路径创建
//File file = new File("D:\\我的\\IDEA 项目\\test.txt");
//File file = new File("../test.txt");
// 当前路径下没 test.txt -> file.createNewFile() 创建 test.txt 文件
File file = new File("./test.txt");
// 创建 test.txt 文件
file.createNewFile();
System.out.println(file.getParent()); // 打印在哪个目录下
System.out.println(file.getName()); // 打印文件名
System.out.println(file.getPath()); // 打印相对路径
System.out.println(file.getCanonicalPath()); // 打印绝对路径
System.out.println(file.exists());
System.out.println(file.isFile());
System.out.println(file.isDirectory());
}
}
删除文件:
查看代码
package io;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class demo2 {
public static void main(String[] args) throws IOException {
File f = new File("./test.txt");
System.out.println(f.exists());
if (!f.exists()) {
f.createNewFile();
}
// 删除文件
//f.delete();
System.out.println(f.exists());
// 进程结束的时候删除文件
f.deleteOnExit();
System.out.println(f.exists());
Scanner scanner = new Scanner(System.in);
scanner.next();
}
}
文件重命名, 移动文件
查看代码
import java.io.IOException;
public class demo4 {
public static void main(String[] args) {
File f1 = new File("./t2.txt");
// 移动到 testDir 目录下
File f2 = new File("./testDir/t2.txt");
f1.renameTo(f2);
}
public static void main1(String[] args) throws IOException {
File file1 = new File("./t1.txt");
File file2 = new File("./t2.txt");
if (!file1.exists()) file1.createNewFile();
// 重命名 t1 -> t2
file1.renameTo(file2);
System.out.println(file1.getName());
}
}
创建目录:
查看代码
package io;
import java.io.File;
public class demo3 {
public static void main(String[] args) {
// 创建一级目录
//File file = new File("./testDir");
//file.mkdir();
// 创建多级目录
File file = new File("./a/b/c");
file.mkdirs();
System.out.println(file.exists());
System.out.println(file.isFile());
System.out.println(file.isDirectory());
}
}
-> 针对文件内容操作 (读写文件)
以字节为单位读取:
package io;
import java.io.*;
public class demo5 {
public static void main1(String[] args) throws IOException {
File f = new File("d:/test.txt");
try (InputStream inputStream = new FileInputStream(f);) {
while (true) {
// 一次最多读1024个字节 ( 根据byte数组长度 ), 把读到的东西放到 byte 数组中
// n -> 读到的字节个数
byte[] bytes = new byte[1024];
int n = inputStream.read(bytes);
if (n == -1) {
break;
}
for (int i = 0;i < n;i++) {
System.out.printf("0x%x ",bytes[i]);
}
}
}
}
public static void main(String[] args) throws IOException {
// 打开文件
try (InputStream inputStream = new FileInputStream("d:/test.txt");) {
while (true) {
// 一次读取 1字节
int v = inputStream.read();
if (v == -1) {
break;
}
System.out.printf("0x%X ",v);
}
}
}
}
注意打开文件后, 一定要关闭文件
以字节为单位写文件:
package io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class demo6 {
public static void main(String[] args) throws IOException {
// 不想清空内容, 可以以追加写方式打开 -> 加参数 true
try (OutputStream outputStream = new FileOutputStream("d:/test.txt",true)) {
outputStream.write(100); // 一次写一个字节
}
}
public static void main2(String[] args) throws IOException {
// 以默认写操作打开文件, 会直接清空文件内容
try (OutputStream outputStream = new FileOutputStream("d:/test.txt")) {
outputStream.write(97); // 一次写一个字节
outputStream.write(98);
outputStream.write(99);
}
}
}
以字符为单位读:
package io;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class demo7 {
public static void main(String[] args) throws IOException {
try(Reader reader = new FileReader("d:/test.txt");) {
while (true) {
int c = reader.read(); // 读取一个字符, 一次读2个字节
if (-1 == c) {
break;
}
System.out.println((char) c);
}
}
}
}
以字符为单位写:
package io;
import java.io.*;
public class demo7 {
public static void main(String[] args) throws IOException {
try(Writer writer = new FileWriter("d:/test.txt",true)) {
writer.write("你好");
}
}
}
5. 3个使用案例
案例1:
扫描指定目录, 找到包含输入关键词的文件,并输出绝对路径
查看代码
package io;
import java.io.File;
import java.util.Scanner;
public class demo8 {
public static void main(String[] args) {
// 1. 输入路径
Scanner scanner = new Scanner(System.in);
System.out.println("输入要搜索的目录: ");
String rootPath = scanner.next();
// 2. 检查路径是否合法
File rootDir = new File(rootPath);
if (!rootDir.isDirectory()) {
System.out.println("输入路径非法");
return;
}
// 3. 输入查询关键词
System.out.println("输入要查询的词: ");
String keyWord = scanner.next();
// 4. 搜索
searchFile(rootDir,keyWord);
}
public static void searchFile(File rootDir,String keyWord) {
File[] files = rootDir.listFiles();
// 目录为空, 直接返回
if (files == null) {
return;
}
for (File file: files) {
if (file.isFile()) {
if (file.getName().contains(keyWord)) {
System.out.println("找到匹配结果: " + file.getAbsolutePath());
}
}else if (file.isDirectory()) {
searchFile(file,keyWord);
}
}
}
}
查看代码
package io;
import java.io.*;
import java.util.Scanner;
public class demo9 {
public static void main(String[] args) {
// 1. 输入
Scanner scanner = new Scanner(System.in);
System.out.println("输入要复制的文件路径: ");
String srcPath = scanner.next();
File srcFile = new File(srcPath);
if (!srcFile.isFile()) {
System.out.println("这路径没这文件");
return;
}
System.out.println("输入要复制到的目标路径: ");
String dstPath = scanner.next();
File dstFile = new File(dstPath);
// 这是判断 目标目录的上级目录 是否存在
if (!dstFile.getParentFile().isDirectory()) {
System.out.println("输入路径非法");
return;
}
// InputStream & OutputStream 没文件, 就先创建文件 -> 打开
try (InputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(dstFile)){
while (true) {
byte[] bytes = new byte[1024];
int n = inputStream.read(bytes);
if (n == -1) {
return;
}
outputStream.write(bytes,0,n);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
找出所以这个目录下, 所有包含关键词的文件
查看代码
package io;
import java.io.*;
import java.util.Scanner;
public class Demo13 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要搜索的路径: ");
String path = scanner.next();
System.out.println("请输入要查询的词: ");
String searchWord = scanner.next();
File rootFile = new File(path);
if (!rootFile.isDirectory()) {
System.out.println("当前输入的路径非法!");
return;
}
search(rootFile, searchWord);
}
private static void search(File rootFile, String searchWord) {
File[] files = rootFile.listFiles();
if (files == null) {
// 空目录, 递归的结束条件.
return;
}
for (File f : files) {
if (f.isFile()) {
// 读取文件内容并搜索.
matchWord(f, searchWord);
} else if (f.isDirectory()) {
// 递归的搜索子目录
search(f, searchWord);
}
}
}
// 负责针对一个文件进行读取和判定.
private static void matchWord(File f, String searchWord) {
try (Reader reader = new FileReader(f)) {
// 把读到的结果, 最终构造到一个 StringBuilder 里.
StringBuilder stringBuilder = new StringBuilder();
while (true) {
int c = reader.read();
if (c == -1) {
break;
}
stringBuilder.append((char)c);
}
// 循环结束, 此时文件所有的内容, 就都进入 stringBuilder 了
if (stringBuilder.indexOf(searchWord) >= 0) {
// 找到了.
System.out.println("找到了匹配的结果: " + f.getAbsolutePath());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}