一、文件的一些知识
1、概念
狭义的文件:硬盘上的 文件 和 目录(文件夹)。
广义的文件:计算机中的很多 软硬件资源。操作系统中,把很多硬件设备和软件资源抽象成了文件,按照文件的方式统一管理。(如:网卡。操作系统把网卡也当成文件)
本文章只讨论狭义的文件。
2、文件的路径
绝对路径:以 C: D: c: d: 这样的盘符开头的路径
相对路径:以当前所在的目录(工作目录)为基准,以 . 或者 .. 开头(. 有时候可以省略)的路径( . 表示当前目录, .. 表示回退到前一个目录)
如:文件a 的路径是 D:/tmp/a 那么,
如果工作目录是 D:/ 相对路径就是 ./tmp/a
如果工作目录是 D:/tmp 相对路径就是 ./a
如果工作目录是 D:/tmp/b 相对路径就是 ../a
3、文件的分类
(1)文本文件:存的是文本,字符串,用记事本打开能看懂
(2)二进制文件:存的是二进制数据,用记事本打开看不懂,是乱码
二、Java对于文件系统的操作
Java标准库,提供了 File 这个类,用来对文件系统进行操作(文件的创建,删除,重命名....等)。
1、构造方法:
File(File parent,String child)
File(String pathname)
File(String parent,String child)
参数是绝对路径,相对路径都可以,parent 表示当前文件所在的目录,child表示文件名
2、方法
(1)
返回类型 | 方法 | 说明 |
String | getParent() | 返回 File的 目录 |
String | getName() | 返回 File的 文件名 |
String | getPath() | 返回 File的 路径 |
String | getAbsolutePath() | 返回 File的 (和路径拼接的)绝对路径 |
String | getCanonicalPath() | 返回 File的 (正确的)绝对路径 |
public static void main(String[] args) throws IOException {
//不要求d:/这里真的有个test.txt
File file = new File("d:/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.getCanonicalPath());
}
public static void main(String[] args) throws IOException {
//不要求d:/这里真的有个test.txt
File file = new File("./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.getCanonicalPath());
}
(2)
返回类型 | 方法 | 说明 | |
boolean | createNewFile() | 真的创建一个文件 | |
boolean | exists() | 判断文件是否真实存在 | |
boolean | isFile() | 判断文件是否是一个普通文件 | |
boolean | isDirectory() | 判断文件是否是一个目录 | |
boolean | delete() | 删除一个文件 | |
void | deleteOnExit() | 程序退出的时候会自动删除这个文件 | |
boolean | mkdir() | 真的创建一个目录(只能创建一级目录) | |
boolean | mkdirs() | 创建多级目录 |
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
//真的创建一个文件
file.createNewFile();
//判断文件是否真实存在
System.out.println(file.exists());
//判断文件是否是一个普通文件
System.out.println(file.isFile());
//判断文件是否是一个目录
System.out.println(file.isDirectory());
//删除这个文件
file.delete();
}
public static void main(String[] args) {
File dir = new File("./test");
//真的创建一个目录,只能创建一级目录
dir.mkdir();
File dir2 = new File("./aaa/bbb/ccc");
//创建多级目录
dir2.mkdirs();
}
三、 Java对于文件内容的操作
Java标准库,提供了 字节流和字符流 两种类,用来对文件内容进行操作(文件的读和写),称为“流对象”(我们把读写文件的对象称为流对象)。
字节流:以字节为单位,读写数据,适合操作二进制数据。 InputStream FileInputStream 和 OutputStream FileOutputStream
字符流:以字符为单位,读写数据,适合操作文本数据。 Reader FileReader 和 Writer FileWriter
使用步骤:
1、打开文件(也就是构造对象)这个文件存在才能构造成功
2、读文件(针对 InputStream/Reader)或 写文件(针对 OutputStream/Writer)
3、关闭文件(close)
1、InputStream —— 往内存中读
返回类型 | 方法 | 说明 |
int | read() | 一次读取一个字节并把读到的返回,返回-1说明读完了 |
int | read(byte[] b) | 把读到的内容尽可能填充到参数的这个字节数组中(使用参数来接收内容,尽可能把数组填满), 返回值是实际读取的字节数,返回-1 代表读完了 |
int | read(byte[] b,int off,int len) | 和2类似,只不过是往数组的一部分区间里尽可能填充,
最多读取
len - off
字节的数据到
b
中,放在从
off
开始,返
回实际读取的字节数,返回
-1
代表读完了
|
void | close() | 关闭字节流 |
不带参数的read:
一次读取一个字节,并把读到的字节返回,返回-1说明文件读完了。
public static void main(String[] args) throws IOException {
//1、构造对象,也就是打开文件
InputStream inputStream = new FileInputStream("d:/test.txt");
//2、读取文件
while(true){
//一次读取一个字节,返回读取到的字节
int b = inputStream.read();
if(b == -1){
break;
}
System.out.printf("%x\n",(byte)b);
}
// 3、关闭文件
inputStream.close();
}
带一个参数的read:
参数是一个 byte类型的数组,用来存放读到的内容,每一次读都会尽可能的读数组大小的字节来把数组填满。如果不够,有多少就读多少,会返回实际读取的字节数。文件读完了,会返回-1.
public static void main(String[] args) throws IOException {
InputStream inputStream = new FileInputStream("d:/test.txt");
while(true){
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
System.out.println("len:"+len);
if(len == -1){
break;
}
//此时,读取的结果就被方法buffer中了
for (int i = 0; i < len; i++) {
System.out.printf("%x\n",buffer[i]);
}
}
inputStream.close();
}
2、OutputStream —— 往硬盘中写
返回类型 | 方法 | 说明 |
void | write(int b) | 一次写一个字节 |
void | write(byte[] b) | 把字符数组b里的内容写进去 |
int | write(byte[] b, int off,
int len)
| 从字符数组b的off位置开始往文件里写,写len个字节 |
void | close() | 关闭字节流 |
对于OutputStream来说,默认情况下,打开一个文件,会先清空文件的原有内容。
而且,如果读的文件不存在,在父路径正确的情况下,会自己创建一个文件。
如果没有执行到close,一直打开文件不关闭,可能会出现文件描述符表被占满的情况。
下面这个写法更推荐:
public static void main(String[] args) throws IOException {
try(OutputStream outputStream = new FileOutputStream("d:/test.txt")){
outputStream.write(97);
outputStream.write(98);
outputStream.write(99);
outputStream.write(100);
}
}
这个写法虽然没有显示的写close,实际上是会执行的。 只要 try 语句块执行完毕,就可以自动执行到 close。这个语法在Java中被称为 try with resources
3、Reader
和字节流用法差不多
public static void main(String[] args) {
try(Reader reader = new FileReader("d:/test.txt")){
while(true){
int ch = reader.read();
if(ch == -1){
break;
}
System.out.println(""+(char)ch);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
4、Writer
和字节流用法差不多
对于Writer来说,默认情况下,打开一个文件,会先清空文件的原有内容。
而且,如果读的文件不存在,在父路径正确的情况下,会自己创建一个文件。
public static void main(String[] args) {
try(Writer writer = new FileWriter("d:/test.txt")){
writer.write("hello world");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
四、练习
1、查询指定目录(包括它的子目录)下有没有要删除的普通文件,有的话就删除
import java.io.File;
import java.util.Scanner;
//指定目录下删除指定文件
public class IODemo10 {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("请输入一个目录:");
String dir = scanner.next();
File root = new File(dir);
if(!root.isDirectory()){
System.out.println("输入有误");
return;
}
System.out.println("请输入要删除的文件名");
String delete = scanner.next();
search(root,delete);
}
private static void search(File root, String delete) {
System.out.println(root.getAbsolutePath());
if(root == null){
return;
}
File[] files = root.listFiles();
for (File file:files) {
if(file.isDirectory()){
//如果是目录
search(file,delete);
}else{
//如果是文件
if(file.getName().contains(delete)){
System.out.println("确定要删除"+file.getAbsolutePath()+"这个文件吗?");
String choice = scanner.next();
if(choice.equals("Y")||choice.equals("y")){
file.delete();
System.out.println("删除成功!");
}else{
System.out.println("删除取消!");
}
}
}
}
}
}
2、文件的复制:把一个文件拷贝成另一个文件
把第一个文件按照字节依次读取,写到第二个文件中。
第二个文件不存在,会自己创建。
import java.io.*;
import java.util.Scanner;
//文件的复制
public class IODemo11 {
public static void main(String[] args) {
//输入两个路径:源 和 目标(从哪里考,拷贝到哪里)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入源路径:");
String src = scanner.next();
File srcFile = new File(src);
System.out.println("请输入目标路径:");
String desc = scanner.next();
File descFile = new File(desc);
if(!srcFile.isFile()){
System.out.println("源路径有误!");
return;
}
if(descFile.isFile()){
System.out.println("目标路径有误!");
return;
}
//开始拷贝
try(InputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(descFile)){
//进行读文件操作
while(true){
int b = inputStream.read();
if(b == -1){
break;
}
outputStream.write(b);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}