Java 基础之文件处理
创始人
2024-05-11 18:22:15
0

1. Stream 流

2. File 和 IO

Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标:

2.1 控制台输入

Java 的控制台输入由 System.in 完成, 将 System.in 包装在一个 BufferedReader 对象中来创建一个字符流,创建后可使用 read() 方法读取一个 字符,读取字符串使用 readLine()

import java.io.*;public class BufferedReaderTest {public static void main(String[] args) throws IOException {char c;BufferedReader br = new BufferedReader(new InputStreamReader(System.in));System.out.println("输入字符,按 'q' 退出:");do {// 读取字符c = (char) br.read();   // 每次只能读取一个字符System.out.println(c);} while (c != 'q');}
}

输出:

输入字符,按 'q' 退出:
a
ab
bc
cjava
j
a
v
aq
q

注意:read() 方法读取一个字符,就会返回一个整数,直至输入流结束,返回 -1,此时会抛出 IOException,因此要 throws

2.2 控制台输出

控制台的输出可以由 print() 和 println() 、write() 完成,都是来自 PrintStream 类,不过 write() 方法不常用:

// void write(int byteval),write() 方法将 byteval 的低八位字节写到流中
System.out.println("abc");
int b;
b = 'A';
System.out.write(b);
System.out.write('\n');

2.3 文件读写

输入流和输出流的类层次图

2.3.1 FileInputStream

该流用于读取文件数据,创建方法:

// 方法一
InputStream f = new FileInputStream("xxx.txt");// 方法二
File f = new File("xxx.txt");
InputStream in = new FileInputStream(f);

文件对象常用方法

方法描述
public void close() throws IOException{}关闭文件输入流并释放与此流相关的所有系统资源,抛出 IOException
protected void finalize()throws IOException {}清除与该文件的连接,确保在不引用时调用 close() 方法,抛出 IOException
public int read(int r)throws IOException{}从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1
public int read(byte[] r) throws IOException{}从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1
public int available() throws IOException{}返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class FileInputStreamTest {public static void main(String[] args) throws IOException {readFile();}public static void readFile() throws IOException {int name;// 创建文件对象InputStream input = new FileInputStream("F:\\JavaStudy\\Source\\FileTest\\src\\people.txt");do {name = input.read(); // 循环调用 read(),直至返回 -1System.out.println(name);} while (name != -1);   // name = -1 时文件读取完毕input.close();  // 关闭}
}

运行结果:

114
111
115
101
13
10
108
105
108
97
13
10
106
111
104
110
-1

read() 方法每次只会读取一个字节,直至读取完毕,返回 -1(可以根据此来作为循环退出条件),另外需要记得关闭文件对象!

使用 for 循环读取:

public static void readFile() throws IOException {int name;// 创建文件对象InputStream input = new FileInputStream("F:\\JavaStudy\\Source\\FileTest\\src\\people.txt");
//        do {
//            name = input.read(); // 循环调用 read(),直至返回 -1
//            System.out.println(name);
//        } while (name != -1);for (; ; ) {name = input.read(); // 循环调用 read(),直至返回 -1if (name == -1) {break;}System.out.println(name);}input.close();  // 关闭}

使用 try...finally 保证任何时候都会关闭文件对象:

public static void readFileTest() throws IOException {InputStream input = null;try {input = new FileInputStream("F:\\JavaStudy\\Source\\FileTest\\src\\people.txt");int n = 0;while (n != -1) {n = input.read();System.out.println(n);}} finally {if (input != null) {input.close();}}}

Java7 后,省略写法:

public void readFile() throws IOException {try (InputStream input = new FileInputStream("F:\\JavaStudy\\Source\\FileTest\\src\\people.txt")) {int n;while ((n = input.read()) != -1) {System.out.println(n);}} // 编译器在此自动为我们写入finally并调用close()
}

缓冲(一次读取多个字节)

read() 方法只能一次读取一个字节,但是可以将读取的字节放入一个缓冲的 bytes[] 数组中,这样返回值不再是字节的 int 值,而是返回实际读取了多少个字节。如果返回-1,表示没有更多的数据了:

public static void readFileCache() throws IOException {try (InputStream input = new FileInputStream("F:\\JavaStudy\\Source\\FileTest\\src\\people.txt")) {
//            定义 1000 个字节大小的缓冲区byte[] buffer = new byte[1000];int n;while ((n = input.read(buffer)) != -1) {System.out.println("已读取:" + n + " 字节!");     // 已读取:16 字节!}}}

2.3.2 FileOutputStream

FileOutputStream 用来创建一个文件并向文件中写数据,若目标文件不存在,那么该流会创建该文件:

// 方法一
OutputStream f = new FileOutputStream("C:/java/hello")// 方法二
File f = new File("C:/java/hello");
OutputStream fOut = new FileOutputStream(f);

常用方法

方法说明
close()关闭文件对象,释放系统资源
finalize()清除与该文件的连接,确保在不再引用文件输入流时调用其 close 方法。抛出 IOException 异常
write(int w)将指定的字节写入到输出流中
write(byte[] w)将指定数组中的 w.length 长度的字节写入到输出流中
flush()将缓冲区内容写入输出流中

flush()

当向磁盘、网络写入数据时,并不是输出一个字节就立即写入,而是先把输出存入内存中(相当于缓冲区),当到达一定量后(缓冲区满了)再写入磁盘或网络,这能提高写入效率,减少 IO 消耗;flush() 可以强制将缓冲区内容输出,一般情况下我们不需要手动去 flush(会自动 flush),除非一些特殊情况需要,比如缓冲区大小 4K,但是输出的字节大小不足 4k,这是就需要手动去 flush()

一次写入多个字节 xx.getBytes() 转换为 byte[]

public static void writeFile() throws IOException {try (OutputStream output = new FileOutputStream("F:\\JavaStudy\\Source\\FileTest\\src\\result.txt")) {output.write("Hello".getBytes("UTF-8"));}
}

2.4 File 类

关于文件和 IO 的类:

  • File
  • FileReader
  • FileWriter

创建目录

File 类中两个方法:

  • mkdir():创建一个目录,成功返回 true,否则返回 false(表示指定的路径已存在或整个路径不存在)
  • mkdirs():递归创建目录(多个)
import java.io.File;public class FileTest {public static void main(String[] args) {String path = "F:\\JavaStudy\\Source\\FileTest\\src\\newFile";File d = new File(path);d.mkdir();}
}

读取目录

  • isDirectory():是否是一个目录,是返回 true
  • list():返回目标目录中所有文件夹和文件
import java.io.File;public class FileTest {public static void main(String[] args) {String path = "F:\\JavaStudy\\Source\\FileTest\\src";File f1 = new File(path);if (f1.isDirectory()) {System.out.println(path + " 是一个目录!");String[] file_arrs = f1.list();for (int i = 0; i < file_arrs.length; i++) {File f2 = new File(file_arrs[i]);if (f2.isDirectory()) {System.out.println(file_arrs[i] + " 是一个目录!");} else {System.out.println(file_arrs[i] + " 是一个文件!");}}} else {System.out.println(path + " 是一个文件!");}}
}

运行结果:

F:\JavaStudy\Source\FileTest\src 是一个目录!
BufferedReaderTest.java 是一个文件!
FileInputStreamTest.java 是一个文件!
FileTest.java 是一个文件!
newFile 是一个文件!
people.txt 是一个文件!
result.txt 是一个文件!

删除文件或目录

delete() 方法删除目录时,需保证该目录下没有其他文件,否则会删除失败:

import java.io.File;public class FileTest {public static void main(String[] args) {
//        删除目录或文件deleteDirectoryOrFile();}public static void deleteDirectoryOrFile() {String path = "F:\\JavaStudy\\Source\\FileTest\\src\\newFile";File f1 = new File(path);
//        直接删除失败
//        f1.delete();deleteDirectory(f1);}public static void deleteDirectory(File f1) {File[] files = f1.listFiles();if (files != null) {for (File f : files) {if (f.isDirectory()) {deleteDirectory(f);} else {f.delete();}}}f1.delete();}
}

其他方法

canRead()  // 是否可读
canWrite() // 是否可写
canExecute()    // 是否可执行
length()    // 文件字节大小
listFiles() // 列出目录下的文件和子目录名

2.5 Path 类

Path 类与 File 类功能相似,但操作更简单,位于 java.nio.file 包中:

public static void getPath() {Path p1 = Paths.get(".", "project", "java_study");  // 构造一个Path对象System.out.println(p1); //  .\project\java_study// 转换为绝对路径 F:\JavaStudy\Source\.\project\java_studyPath p2 = p1.toAbsolutePath();System.out.println(p2);// 转换为规范路径 F:\JavaStudy\Source\project\java_studyPath p3 = p2.normalize();System.out.println(p3);// 转换为File对象  F:\JavaStudy\Source\project\java_studyFile f = p3.toFile();System.out.println(f);// 遍历Pathfor (Path p: Paths.get("..").toAbsolutePath()) {System.out.println("===>" + p);/*===>JavaStudy===>Source===>..*/}}

2.6 Scanner 类

Scanner 类可以获得用户输入:

Scanner scan = new Scanner(System.in);

常用方法

  • next()、nextLine():获取输入的字符串
  • hasNext()、hasNextLine():是否还有数据输入
  • nextInt()、nextFloat():接收数字

2.6.1 接收字符串

next 方法

import java.util.Scanner;public class ScannerTest {public static void main(String[] args) {Scanner scan = new Scanner(System.in);System.out.println("请输入:");if (scan.hasNext()) {String str1 = scan.next();System.out.println(str1);}scan.close();}
}

运行结果:

请输入:
Hello World			// 输入的字符串
Hello				// 只输出了 Hello,没有输出 World

nextLine()

import java.util.Scanner;public class ScannerTest {public static void main(String[] args) {Scanner scan = new Scanner(System.in);System.out.println("请输入:");if (scan.hasNextLine()) {String str2 = scan.nextLine();System.out.println(str2);}scan.close();}
}

运行结果:

请输入:
Hello World
Hello World

next() 与 nextLine() 区别

  • next()
    • 对录入的字符串遇到 空格就会停止录入,会截断空格后的字符串
    • 在录入字符串时,会在尾部加一个 \r\n,若 nextnextLine 之前录入就会导致 nextLine 录入了 \r\n
  • nextLine()
    • 会把整行字符串全部录入,录入字符串时推荐使用
    • 回车为结束符,可获得空白

2.6.2 接收数字

import java.util.Scanner;public class ScannerTest {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int m = 0;float n = 0;System.out.println("请输入一个整数:");if (scan.hasNextInt()) {m = scan.nextInt();System.out.println(m);}System.out.println("请输入一个小数:");if (scan.hasNextFloat()) {n = scan.nextFloat();System.out.println(n);}scan.close();}
}

运行结果:

请输入一个整数:
36000
36000
请输入一个小数:
3.6
3.6

2.6.3 示例

接收多个输入,并求和

import java.util.Scanner;public class ScannerTest {public static void main(String[] args) {Scanner scan = new Scanner(System.in);// 求和int a = 0;System.out.println("请输入一个整数(输入非整数结束程序运行):");while (scan.hasNextInt()) {a = a + scan.nextInt();System.out.println("请继续输入:");}System.out.println("总和:" + a);scan.close();}
}

运行结果:

请输入一个整数(输入非整数结束程序运行):
1
请继续输入:
2
请继续输入:
3
请继续输入:
4
请继续输入:
a
总和:10

2.6.4 接收文件流

Scanner sc=new Scanner(new File("test.txt"));
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;public class ScannerFileTest {public static void main(String[] args) throws FileNotFoundException {Scanner scan = new Scanner(new File("F:\\JavaStudy\\Source\\FileTest\\src\\people.txt"));while (scan.hasNextLine()) {System.out.println("接收到一个字符串:" + scan.nextLine());}}
}

运行结果:

接收到一个字符串:rose
接收到一个字符串:lila
接收到一个字符串:john

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...