JAVA文件IO,File类,字符流,字节流
- 互联网
- 2025-07-21 19:24:38

文章目录 文件IO1. File2. IO流2.1 字符流2.1.1 Reader2.1.2 Writer 2.2 字节流2.2.1 InputStream2.2.2 FileInputStream2.2.3 利用Scanner进行字符读取2.2.4 OutputStream 文件IO
I: Input, 从硬盘往内存读数据
O: Output, 从内存往硬盘输出数据
1. FileJava 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件。
构造方法
方法说明File(File parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例File(String pathname)根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径File(String parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用路径表示方法
修饰符及返回值类型方法名称说明StringgetParent()返回 File 对象的父目录文件路径StringgetName()返回 FIle 对象的纯文件名称StringgetPath()返回 File 对象的文件路径StringgetAbsolutePath()返回 File 对象的绝对路径StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径booleanexists()判断 File 对象描述的文件是否真实存在booleanisDirectory()判断 File 对象代表的文件是否是一个目录booleanisFile()判断 File 对象代表的文件是否是一个普通文件booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返回 true booleandelete()根据 File 对象,删除该文件。成功删除后返回 truevoiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行String[]list()返回 File 对象代表的目录下的所有文件名File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象表示booleanmkdir()创建 File 对象代表的目录booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目录booleanrenameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作booleancanRead()判断用户是否对文件有可读权限booleancanWrite()判断用户是否对文件有可写权限代码示例
public static void main(String[] args) throws IOException { File file1 = new File("D/text.txt"); System.out.println(file1.getName()); System.out.println(file1.getParent()); System.out.println(file1.getPath()); System.out.println(file1.getAbsolutePath()); System.out.println(file1.getCanonicalPath()); System.out.println("==========================="); File file2 = new File("./text.txt"); System.out.println(file2.getName()); System.out.println(file2.getParent()); System.out.println(file2.getPath()); System.out.println(file2.getAbsolutePath()); System.out.println(file2.getCanonicalPath()); }输出
text.txt
D:\
D:\text.txt
D:\text.txt
D:\text.txt
===========================
.
.\text.txt
D:\JAVA\java\system_code.\text.txt
D:\JAVA\java\system_code\text.txt
public static void main(String[] args) throws IOException { File file = new File("./test.txt"); System.out.println(file.exists()); System.out.println(file.isFile()); System.out.println(file.isDirectory()); //创建文件 file.createNewFile();//若当前文件已经存在, 也不会重新创建一个 System.out.println(file.exists()); System.out.println(file.isFile()); System.out.println(file.isDirectory()); }输出
true
true
false
===========================
true
true
false
public static void main(String[] args) throws IOException { File file = new File("./text.txt"); System.out.println(file.exists()); file.delete(); System.out.println("文件已删除"); System.out.println(file.exists()); }输出
false
文件已删除
false
public static void main(String[] args) throws IOException { File file = new File("text.txt"); System.out.println(file.exists()); //等到程序结束前再删除 file.deleteOnExit(); System.out.println(file.exists()); }输出
true
true
public static void main(String[] args) { File file = new File("./testDir"); file.mkdir(); System.out.println(file.exists()); System.out.println(file.isDirectory()); File file1 = new File("./testDir/aaa/bbb/ccc"); file1.mkdirs(); System.out.println(file1.exists()); System.out.println(file1.isDirectory()); }输出
true
true
true
true
public static void main(String[] args) { File file = new File("./test.txt"); File file1 = new File("./testRename.txt"); System.out.println("file是否存在: " + file.exists()); System.out.println("file1是否存在: " + file1.exists()); System.out.println("renameTo执行是否成功: "+file.renameTo(file1)); System.out.println("file是否存在: " + file.exists()); System.out.println("file1是否存在: " + file1.exists()); }输出
file是否存在: true
file1是否存在: false
renameTo执行是否成功: true
file是否存在: false
file1是否存在: true
public static void main(String[] args) throws IOException { File file = new File("./test.txt"); File file1 = new File("./src/test2.txt"); System.out.println("file是否存在: " + file.exists()); System.out.println("file1是否存在: " + file1.exists()); System.out.println("file的路径" + file.getCanonicalPath()); System.out.println("renameTo执行是否成功: "+file.renameTo(file1)); System.out.println("file是否存在: " + file.exists()); System.out.println("file1是否存在: " + file1.exists()); System.out.println("file1的路径" + file1.getCanonicalPath()); }输出
file是否存在: true
file1是否存在: false
file的路径D:\JAVA\java\system_code\test.txt
renameTo执行是否成功: true
file是否存在: false
file1是否存在: true
file1的路径D:\JAVA\java\system_code\src\test2.txt
2. IO流将硬盘中的数据比喻为池中的水
往池中加水, 相当于数据从内存往硬盘中流动, 称作输出流
从池中放水, 相当于数据从硬盘往内存中流, 称作输入流
IO流可以分为 字节流 , 字符流 两大类
这些类都有各自不同的特性, 但是使用方法还是类似的:
构造方法: 打开文件
close方法: 关闭文件
close方法一定要执行到, 如果使用完不关闭, 就会导致文件资源泄露 (尤其是在7*24小时运转的服务器上) 进而导致文件都打不开, 使服务器宕机.
如何保证close方法一定能执行的到呢?
使用try-finally, 将close写入finally代码块
使用try with resources创建流对象. 例如
try (Reader reader = new FileReader("D:/test.txt"); Reader reader1 = new FileReader(""); Reader reader2 = new FileReader(""); ...) { //代码 }只要try代码块执行结束, 就会自动调用close方法.
如果衍生自InputStream或者Reader, 就可以使用read方法读文件
如果衍生自OutputStream或者Writer, 就可以使用write方法写文件
2.1 字符流字符流, 顾名思义, 以操作字符为单位, 针对文本文件
2.1.1 Readerread方法
方法作用返回值int read()一次读一个字符以int类型返回读到的字符. 如果返回值为-1, 表示文件已经读完, 或者读到EOF.int read(char cbuf[])一次读若干个字符, 并把读到的内容填充到cbuf[]中返回实际读到的字符个数int read(char cbuf[], int off, int len)从第off个字符开始, 将字符读入数组, 一共读len个读取的字符数,如果已到达流的结尾,则返回-1代码案例
public static void main(String[] args) throws IOException { try (Reader reader = new FileReader("D:/test.txt")) { while (true) { char[] buf = new char[1024]; int n = reader.read(buf); if(n == -1) { break; } for (int i = 0; i < n; i++) { System.out.print(buf[i] + " "); } } } } 2.1.2 Writerwrite方法
方法说明void write(int c)写入单个字符。void write(char cbuf[])写入字符数组。void write(char cbuf[], int off, int len)写入字符数组的一部分。cbuf -字符数组off -开始写入字符的偏移量len -要写入的字符数void write(String str)写入字符串void write(String str, int off, int len)写入字符串的一部分。str -字符串off -开始写入字符的偏移量len -写入字符的数目代码示例
public static void main(String[] args) throws IOException { try(Writer writer = new FileWriter("D:/test.txt")) { writer.write("hello java"); } }这里可能就会有疑问了, 文件里面之前的内容呢?
输出流对象(无论字节流还是字符流), 再打开文件之后, 清空文件内容.
如果不想被清空, 那就使用追加写方式打开文件.
Writer writer = new FileWriter("D:/test.txt", true)在构造方法上, 写一个true, 便可
public static void main(String[] args) throws IOException { try(Writer writer = new FileWriter("D:/test.txt", true)) { writer.write("hello world"); } } 2.2 字节流字节流, 顾名思义, 以操作字节为单位, 针对二进制文件
2.2.1 InputStream方法
返回值类型方法说明intread()读取一个字节的数据,返回 -1 代表已经完全读完了intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数; -1 代表以及读完了intread(byte[] b, int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了voidclose()关闭字节流说明
InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用FileInputStream
2.2.2 FileInputStream构造方法
方法说明FileInputStream(File file)利用 File 构造文件输入流FileInputStream(String name)利用文件路径构造文件输入流代码示例
public static void main(String[] args) { try(InputStream inputStream = new FileInputStream("D:/test.txt")) { while (true) { byte[] bytes = new byte[1024]; int n = inputStream.read(bytes); if (n == -1) { break; } for (int i = 0; i < n; i++) { System.out.printf("%x ", bytes[i]); } } } catch (IOException e) { throw new RuntimeException(e); } }读到的字符, 我们更期望的是把他转化成字符串, 更直观. 所以我们可以借助一些额外的工具类, 就可以完成从字节/字符到字符串的转换.
一. 是使用String的构造方法. 但这种方式不够优雅.
String s = new String(bytes, 0, n, "utf8"); System.out.println(s);二. 是Scanner.
2.2.3 利用Scanner进行字符读取我们来看一下Scanner的构造方法
其中, 构造方法的参数中有InputStream, 也就是说我们可以往里面传字节流. 实际上, 我们经常写的new Scanner(System.in)中的in也是一个字节流
其实在操作系统中, "文件"是一个广义的概念
System.in是一个特殊的文件, 对应到"标准输入"硬盘上的文件, 也是文件网卡(socket), 也是文件…Scanner都是一视同仁的, 只是把当前读到的字节数据进行转换, 不关心这个数据的来源.
那么上述读取文件的代码就可以这样写了
public static void main(String[] args) throws IOException { try(InputStream inputStream = new FileInputStream("D:/test.txt")) { Scanner scanner = new Scanner(inputStream); //Scanner scanner = new Scanner(inputStream, "utf8"); //从文件中读取 while (scanner.hasNext()) { String s = scanner.next(); System.out.print(s + " "); } } }但是Scanner只适合读取文本文件, 不适合读取二进制文件
2.2.4 OutputStream方法
返回值类型方法说明voidwrite(int b)将指定字节写入此输出流。voidwrite(byte[] b)将 b 这个字节数组中的数据全部写入 os 中voidwrite(byte b[], int off, int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个voidclose()关闭字节流voidflush()刷新此输出流并强制写出任何缓冲的输出字节。我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。
OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,
所以使用 FileOutputStream
OutputStream 的使用方法和Writer完全一样, 只不过不能写入字符, 字符串.
JAVA文件IO,File类,字符流,字节流由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“JAVA文件IO,File类,字符流,字节流”
下一篇
建筑红模板尺寸规格