一、文件的概念
狭义的文件:保存在硬盘上的文件。
广义的文件:操作系统进行管理的一种机制,很多软件/硬件资源抽象成“文件”来进行表示。
注:当前这篇文章主要讨论狭义文件。
下面这张图片里面有一些文件,在计算机专业术语中称做:目录

一台计算机中能保存很多文件,区分/识别一个文件就需要通过文件的路径来进行识别。
二、路径
路径: 定位到文件的一系列过程。在计算机中目录套目录,形成了树形结构,从树根开始,到最终的文件,都需要经过哪些目录,把这些目录记录下来,就构成了路径。
斜杠 / : 在主流的操作系统中都是使用/来分割的。但是windows是例外,windows / 和 \(反斜杠 ) 都支持(windows默认使用\)
2.1绝对路径
从根节点开始,逐级表示出来
示例:找e盘lx2下的test.txt文件的路径

绝对路为: e:\前端开发\实验二\lx2\test.txt
2.2相对路径
需要明确一个基准路径,以这个基准来找对应的文件。
示例:找e盘lx2下的test.txt文件的相对路径

假设基准为:e:\前端开发\实验二\lx2,那么test.txt的相对路径就是:./test.txt (.表示当前所在的目录位置)
假设基准为:e:\前端开发\实验二,那么test.txt的相对路径就是:./lx2/test.txt
假设基准为:e:\前端开发\实验二\lx2\photo,那么test.txt的相对路径就是:…/test.txt(..表示当前路径的上一层路径)
如果在代码中写一个相对路径,基准路径是谁呢?
不确定,取决于程序的运行方式,在idea中直接运行,基准路径就是项目的目录,如果打一个jar包,单独运行jar包,当前在哪个目录下执行运行命令(java -jar jar包名),基准目录就是哪个目录。
三、文件的种类
从开发的角度把文件分为两大类
- 1.文本文件
- 2.二进制文件
在实际开发中判断一个文件是否是文本,最简单的方法是用记事本打开,打开之后不是乱码,能看懂文本,就是文本文件,如果是乱码,看不懂,就是二进制文件。
示例:二进制文件 图片,音频,视频,可执行程序,word,docx 都是典型的二进制文件。
示例:文本文件 txt纯文本, .java, .c都是典型的文本文件。
四、java中操作文件
java中通过java.io.file 类来对⼀个⽂件(包括目录)进行抽象的描述。注意,有file对象,并不代表真实存在该文件。
4.1 file类
file类是 java 标准库(java.io 包)中定义的一个类。它用来表示文件或目录的路径,并提供操作这些路径的方法。
1. 属性表格
| 修饰符及类型 | 属性 | 说明 |
|---|---|---|
static string | pathseparator | 依赖于系统的路径分隔符,string 类型的表示 |
static char | pathseparator | 依赖于系统的路径分隔符,char 类型的表示 |
参数string文件的路径使用绝对路径/相对路径均可。
2. 构造方法表格
| 签名 | 说明 |
|---|---|
file(file parent, string child) | 根据父目录 + 孩子文件路径,创建一个新的 file 实例 |
file(string pathname) | 根据文件路径创建一个新的 file 实例,路径可以是绝对路径或者相对路径 |
file(string parent, string child) | 根据父目录 + 孩子文件路径,创建一个新的 file 实例,父目录用路径表示 |
3. 方法表格
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
string | getparent() | 返回 file 对象的父目录文件路径 |
string | getname() | 返回 file 对象的纯文件名称 |
string | getpath() | 返回 file 对象的文件路径 |
string | getabsolutepath() | 返回 file 对象的绝对路径 |
string | getcanonicalpath() | 返回 file 对象的修饰过的绝对路径 |
boolean | exists() | 判断 file 对象描述的文件是否真实存在 |
boolean | isdirectory() | 判断 file 对象代表的文件是否是一个目录 |
boolean | isfile() | 判断 file 对象代表的文件是否是一个普通文件 |
boolean | createnewfile() | 根据 file 对象,自动创建一个空文件。成功创建后返回 true |
boolean | delete() | 根据 file 对象,删除该文件。成功删除后返回 true |
void | deleteonexit() | 根据 file 对象,标注文件将被删除,删除动作会到 jvm 运行结束时才会进行 |
string[] | list() | 返回 file 对象代表的目录下的所有文件名 |
file[] | listfiles() | 返回 file 对象代表的目录下的所有文件,以 file 对象表示 |
boolean | mkdir() | 创建 file 对象代表的目录 |
boolean | mkdirs() | 创建 file 对象代表的目录,如果必要,会创建中间目录 |
boolean | renameto(file dest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操作 |
boolean | canread() | 判断用户是否对文件有可读权限 |
boolean | canwrite() | 判断用户是否对文件有可写权限 |
4.2方法的使用
1.得到文件的基本信息操作
package demo1;
import java.io.file;
import java.io.ioexception;
public class test {
public static void main(string[] args) throws ioexception {
// 此处传入的是绝对路径,getpath得到的就是绝对路径
file file = new file("e:/前端开发/实验二/lx2/test.txt");
system.out.println("父目录文件路径: "+file.getparent());
system.out.println("文件名称: "+file.getname());
system.out.println("文件路径"+file.getpath());
system.out.println("文件的绝对路径"+file.getabsolutepath());
// 简化了绝对路径中的 . 和 ..
system.out.println("简化过后的绝对路径"+file.getcanonicalfile());
}
}打印结果:

2.显示目录下的文件操作
import java.io.file;
import java.util.arrays;
public class test {
public static void main(string[] args) {
file file = new file("e:/");
//list 只是列出当前目录的子元素,无法列出子目录中的具体内容
string[] list = file.list();
system.out.println(arrays.tostring(list));
system.out.println("================");
// file 对象代表的目录下的所有文件,以 file 对象表示
file[] list2 = file.listfiles();
system.out.println(arrays.tostring(list2));
}
}打印结果:

3.创建目录
当前文件夹下为空,我们可以通过mkdir()创建目录

public class test {
public static void main(string[] args) {
file file = new file("e:/新建文件夹/text");
system.out.println(file.mkdir());
}
}
打印结果:

可以发现刚刚的文件夹下新建了一个名为text的目录

4.总结
1.文件是存储在硬盘上的。
2.目录也是文件,操作系统通过树形结构组织目录和文件的
3.通过路径定位到具体的文件
4.文件分为:文本文件和二进制文件
五、文件内容操作
java中针对文件内容的操作,主要是通过一组流来实现的。
计算机中的流和水流非常相似:把数据看作连续不断的字节序列,就像水管里流动的水。
水流的特点:你可以用一桶接满(一次取100升),也可以用两个50升的桶分两次接,或者用10个10升的桶……总之,只要最终总量是100升,取水方式可以任意拆分。
文件流同理:计算机把文件内容视为一段连续字节流(byte stream)。读取时,你可以一次 read(100) 全读完,也可以循环10次、每次 read(10),甚至一次读1字节、读100次。只要每次读的大小之和等于100,并且按顺序读取,都能正确拿到全部数据。
因此,计算机中针对读写文件,也是使用流(stream)。
5.1流的分类
流有几十种,可以分为两个类别:
- 1.字节流:
读写文件以字节为单位,是针对二进制文件使用的
inputstream 输入 从文件读数据
outputstream 输出 往文件写数据
- 2.字符流:
读写文件以字符为单位,是针对文本文件使用的
reader 输入
writer 输出
输入输出是什么意思?
看数据的流向,从硬盘到cpu (输入),从cpu到硬盘(输出)
5.2 inputstream概述
1.方法
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| int | read() | 读取一个字节的数据,返回 -1 代表已经完全读完了 |
| int | read(byte[] b) | 最多读取 b.length 字节的数据到 b 中,返回实际读到的数据;-1 代表已经读完了 |
| int | read(byte[] b, int off, int len) | 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数据;-1 代表已经读完了 |
| void | close() | 关闭字节流 |

2.使用
三个步骤:
1.打开文件
2. 读
3. 关闭
先创建一个名字为:text.txt的文件,内容为hello

import java.io.fileinputstream;
import java.io.ioexception;
import java.io.inputstream;
public class test {
public static void main(string[] args) throws ioexception {
// inputstream是抽象类,不能直接new
// 创建对象成功就相当于去打开文件
// try with resources 只要出现try代码块就会自动调用close
try(inputstream inputstream = new fileinputstream("./text.txt")){
while (true){
int i = inputstream.read();
if(i ==-1){
break;
}
system.out.println(i);
}
}
}
}
打印结果:hello这几个字母对应的ascii表中的值

把text.txt中的文本内容改成:你好

如果文件中包含 非 ascii 字符(如中文 “你”、“好”、表情符号等),这些字符在 utf-8 编码下通常占多字节
一次读一个字节:
import java.io.fileinputstream;
import java.io.ioexception;
import java.io.inputstream;
public class test {
public static void main(string[] args) throws ioexception {
// inputstream是抽象类,不能直接new
// 创建对象成功就相当于去打开文件
// try with resources 只要出现try代码块就会自动调用close
try(inputstream inputstream = new fileinputstream("./text.txt")){
while (true){
// 一次读一个字节
int i = inputstream.read();
if(i ==-1){
break;
}
// 这里打印十六进制 一个十六进制数字是4个比特位,两个十六进制数字就是1一个字节,所以选择用十六进制来进行打印核对
system.out.printf("%x\n",i);
}
}
}
}
打印结果:

发现和上面的你好的utf-8的码表对应上了。
一次读多个字节
public class test {
public static void main(string[] args) throws ioexception {
try(inputstream inputstream = new fileinputstream("./text.txt")) {
//一次读多个字节 数组的长度自行定义
byte[] data = new byte[3];
// 此处的读操作尽可能让数组填满,
// 填不满的话,能填几个是几个
while (true){
// 此处的n是实际读到的字节数
int n = inputstream.read(data);
if(n == -1){
// 读完了
break;
}
for(int i = 0; i<n;i++){
system.out.printf("%x\n",data[i]);
}
system.out.println("===========");
}
}
}
}
打印结果:一次读三个字节

5.3 outputstream概述
1.方法
| 修饰符及返回值类型 | 方法签名 | 说明 |
|---|---|---|
| void | write(int b) | 写入一个字节的数据 |
| void | write(byte[] b) | 将 b 这个字节数组中的数据全部写入输出流中 |
| void | write(byte[] b, int off, int len) | 将 b 这个字节数组中从 off 开始的数据写入输出流中,一共写 len 个 |
| void | close() | 关闭字节流 |
| void | flush() | 重要:我们知道 i/o 的速度是很慢的,所以,很多 outputstream 为了减少设备操作的次数,在写数据的时候会先将数据暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中。这个区域一般称为缓冲区。但这会造成一个结果:我们写的数据很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置调用 flush()(刷新)操作,将数据刷到设备中。 |

这里的参数是int,主要是因为希望参数的取值范围为:0~255,因为java中没有unsiged类型。
2.使用
示例:在output.txt文本文件中写入abc
首先这里面没有output.txt文本文件,等下我们可以观察是否新建了一个output.txt文本文件并写入abc

通过代码来实现
import java.io.*;
public class test {
public static void main(string[] args) {
try(outputstream outputstream = new fileoutputstream("output.txt")){
outputstream.write(97);
outputstream.write(98);
outputstream.write(99);
} catch (ioexception e) {
e.printstacktrace();
}
}
}
运行结果:新建了一个output.txt文本文件并写入了abc

对于outputstream来说,如果文件不存在,会尝试创建文件并写入
outputstream是会清处上一次的内容,打开文件的一瞬间,就被清除了
示例:把刚刚的output.txt中的acb改为大写的abc
import java.io.*;
public class test {
public static void main(string[] args) {
try(outputstream outputstream = new fileoutputstream("output.txt")){
byte[] bytes = {65,66,67};
outputstream.write(bytes);
} catch (ioexception e) {
e.printstacktrace();
}
}
}
运行结果

5.4reader的使用

示例:
把text.txt文件中的abc读出来
import java.io.filereader;
import java.io.ioexception;
import java.io.reader;
public class test {
public static void main(string[] args) {
try(reader reader = new filereader("text.txt")){
while (true){
int n = reader.read();
if(n == -1){
break;
}
system.out.println((char ) n);
}
} catch (ioexception e) {
e.printstacktrace();
}
}
}
打印结果

5.5writer的使用
将writer.txt中写入hello world
import java.io.filewriter;
import java.io.ioexception;
import java.io.writer;
public class test {
public static void main(string[] args) {
try(writer writer = new filewriter("./writer.txt")){
writer.write("hello world");
} catch (ioexception e) {
e.printstacktrace();
}
}
}
打印结果

在原来的hello world 的基础上再追加写hello world
public static void main(string[] args) {
//追加再写一次hello world
try(writer writer = new filewriter("./writer.txt",true)){
writer.write("hello world ");
} catch (ioexception e) {
e.printstacktrace();
}
}
}
打印结果

以上就是java文件操作与io流详解(file类+字节流+字符流)的详细内容,更多关于java文件操作与io流的资料请关注代码网其它相关文章!
发表评论