[Java]文件操作

一、文件

狭义的文件:电脑磁盘上的文件和目录

广义的文件:电脑所以的软硬件资源,操作系统将很多软硬件资源都抽象成了文件,按照文件的方式统一管理。

以下提及的文件都是狭义上的文件。

这些文件总的可以分为两类,二进制文件和文本文件。

要区分这两类文件的最简单的办法就是使用记事本打开这些文件,如果乱码则是二进制文件,如果能看懂则是文本文件。

二、路径

想要操作文件,就必须知道文件的路径,文件的路径分为绝对路径和相对路径。

绝对路径:以盘符开头的文件路径。如:

“D:/AAA/CCC”

上面这个绝对路径就是值D盘下的AAA文件下的ccc文件。

相对路径:以.或者..开头的文件路径。相对路径的基准就是当前工作路径。如:

“./AAA/CCC”或者“../AAA/CCC”

.和..的区别就是.是代指当前的工作路径,..代指当前路径的上一级路径。

正斜杠和反斜杠:/(正斜杠)和\(反斜杠)的区别,/正斜杠是任何系统都支持的文件层级分割符,反斜杠是windows支持的,windows既支持正斜杠,也支持反斜杠,但是建议使用正斜杠。因为在代码编写时,反斜杠是转义字符,单个的反斜杠不是分割符的意思,必须使用两个反斜杠"//"才能表达分割符的意思,在编写代码时使用反斜杠,容易造成错误。

三、File类

Java库中使用File类来表示一个文件,File类是java.io包中的一个类。文件类的的每个操作都是针对文件对象这个整体,不对文件单独的内容产生作用。

(一)创建文件对象

文件类有三个构造函数

文件的路径使用字符串的方法表示

(1)File(String Path);//传入一个文件所在的路径,创建的文件对象操作的就是这个路径对应的文件

(2)File(String parent,String Child);//parent表示文件的父目录,child表示文件的子路径,parent和child共同构成了完整的路径。

(3)File(File parent,String child)//parent是前面已经前面代码创建好了的一个文件对象,代表文件的父目录,child代表文件的子路径。

下面是使用三种构造方法实例化File的代码:

//对绝对路径为"D:/text.txt"的文件进行构造
//一个Path参数的构造,也是最常用的方法
File file1=new File("D:/text.txt");
//两个路径参数的构造
File file2=new File("D:/","text.txt");
//一个File参数一个路径参数的构造
File file3=new File("D:/");
File file=new File(File3,"text.txt");

File类是Java用来描述特定路径下的某个文件的对象,File类对象能否创建和系统中是否有这个文件并没有关系,对象是只是用来描述这个文件的特征的,特征就包括这个文件是否存在,创建出来File对象也不会像c或c++一样在文件系统中创建出来这个文件。

(二)File对象的使用

File对象可以描述这个文件的特征,这些特征就有文件路径,文件是否存在,File指向的是一个目录还是一个文件等。下面是获得这些信息的方法

(1)获得文件路径

String getPath() 返回 File 对象的文件路径
String getAbsolutePath() 返回 File 对象的绝对路径
String getCanonicalPath() 返回 File 对象的修饰过的绝对路径

(2)文件是否存在

boolean exists() 判断 File 对象描述的文件是否真实存在

(3)File指向的文件是否是目录或者是否是文件

boolean isDirectory() 判断 File 对象代表的文件是否是一个目录
boolean isFile() 判断 File 对象代表的文件是否是一个普通文件

(4)判断当前用户对文件是否可读或者可写

boolean canRead() 判断用户是否对文件有可读权限
boolean canWrite() 判断用户是否对文件有可写权限

(5)如果File指向的是一个目录,返回这个目录下的文件名

String[] list() 返回 File 对象代表的目录下的所有文件名,以String的形式

(6)如果File指向的是一个目录,返回这个目录下的文件,以File对象的形式

File[] listFiles() 以file对象的形式返回目录下的所有文件

---------------------------------------------------------------------------------------------------------------------------------

File对象还可以对指向的路径文件进行操作,包括,创建文件,创建成目录,删除文件或者目录

(7)如果不存在这个文件或者目录,就创建文件或者目录,返回true,否则就什么也不干,返回false

boolean createNewFile()//根据 File 对象,自动创建一个空文件。成功创建后返回 true

boolean mkdir() 创建 File 对象代表的目录
boolean mkdirs()创建 File 对象代表的目录,如果必要,会创建中间目录

(8)删除文件或者目录

 boolean delete() 根据 File 对象,删除该文件。成功删除后返回 true
void deleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行

(9)文件的转移(特殊情况下就是改名)

boolean renameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作

要求调用这个方法的File对象指向的文件必须存在,dest文件不能存在,将文件名改为dest文件名

四、文件内容的读取

文件被分为字符文件和字节文件,文件的读取也被分为字符流读取和字节流读取。

字符流读取文件数据的单位是字符。字节流读取的单位是字节。

(一)读字节文件

读取文件的步骤一般分为三个步骤

打开文件,读取文件,关闭文件

(1)打开文件

字节文件内容的读取inputStream类,这个类是一个抽象类,现在是对文件进行读取,所以使用FileInputStream来实例化,FileInputStream有两个构造函数,构造参数分别是File对象或者路径

FileInputStream(File file) 利用 File 构造文件输入流
FileInputStream(String name) 利用文件路径构造文件输入流

创建文件流读取对象就是打开这个文件,下面是创建代码:

InputStream in=new FileInputStream("./text.txt");
//创建了一个文件读取流,这个文件的路径是当前工作目录下的text文件

创建输入流对象传入的路径或者file对象必须是真实存在的文件。 

(2)读取文件

读取字节文件有三个读取方法

int read() 读取一个字节的数据,返回值为读取到的值,返回 -1 代表已经完全读完了
int read(byte[] b);读取 b.length 字节的数据到 b 中,返回实际读到的数量,如果剩余的字节数比数组长度小,则返回实际读到的数据个数,如果剩余的字节数为0,则一个都没读到,此时不返回0,返回-1;
int read(byte[] b,int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;返回-1 代表一个都没读到。

无参读取只读取一个字节数据,为什么不使用byte类型作为返回值,要使用int类型作为返回值?

因为byte类型能表示的数据范围都是合法的数据范围,如果使用byte作为返回值,将没有数据能表示读完了这一状态,所以使用范围更大的int。

另外,你可能会觉得,byte也可以表示-1啊,为什么-1就能作为读完了的标识呢,如果读到的这个一个字节的数据刚好就等于-1,那此时算读完了还是没读完呢?

这个问题也是使用int作为返回值的妙用,因为一个字节的-1是八位的11111110,但在int是四个字节,所以int读取出来的就是00 00 00 1E(16进制),是一个正数,将这个int正数转换成byte的时候,才会由正数变成负数。当真正读到末尾时,返回值将是int的-1,也就是FF FF FF FE(16进制)。

(3)关闭文件

文件的关闭就是流对象的关闭,需要流对象调用close方法。

(4)为什么文件需要关闭?
这是因为,每个线程对打开的文件都要进行记录,记录被打开的文件的数据结构叫文件描述符表(相当一个数组,容量一般都是几百),这个数组是有空间的,且不能扩容,所以每个线程能打开的文件个数是有限的,文件描述符表满了就无法打开文件了,所以需要close关闭文件,关闭文件之后,文件描述符表就会将这个文件从表中移除。

其实java中也有gc(garbage collection,垃圾回收)来处理未被close的文件,但是gc有可能会来不及自动清理,所以还是自己手动关闭好一点。

(二)写字节文件

写字节文件要用到抽象类OutStream,以及子类FileOutStream,写文件分为打开文件,写文件,关闭文件三个步骤。outStream是字节流,所以字节流是完

(1)打开文件

创建输出文件流就是打开文件,打开文件还是有两种参数,File对象和路径。

OutStream out=new FileOutStream(File file);

OutStream out=new FileOutStream(String Path);

输出流打开文件,不要求文件一定存在,如果文件不存在,那就自动创建这个文件。如果文件存在,则自动清空文件所有内容。

(2)写文件

写文件也有三个写的方法,返回值都为空。

 (3)关闭文件

调用close方法。

(三)读字符文件

(1)打开字符文件

读字符文件流的抽象类是Reader,实例列是FileReader,构造方法和前两个字符流一样

(2)读取字符文件

返回值和参数都和字节文件差不多。

(四)写字符文件

(1)打开字符文件

字符文件写使用的抽象类是Writer,实例类是FileWriter

(2)写文件

因为是字符文件,所有Java中多了字符串参数。 

五、为什么读文件使用input,写文件使用out?

这是从计算机结构得来的,规定从CPU往外就是out,从cpu往外就是input。

六、自动关闭流对象的写法

关闭文件可能会因为各种各样的原因,导致本该执行close的语句,没有执行到,到时文件没能被及时关闭,使用try(){}写法,将流文件的创建放在()中,可以在执行完try代码块后自动执行关闭操作。这样的流对象必须要实现了closeable接口。

 七、Scanner实例化要关闭的原因

Scanner对象在使用完毕后,也要关闭,这是因为,Scanner对象在实例化的时候传入的System.in对象就是一个流对象,Scanner对象close实质上就是流对象在close。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值