包括File类简介、查看文件或目录、新建文件或目录、删除文件或目录、查看目录内容、FileFilter接口、顺序读写方法、基于缓存的写方法、基于缓存的读方法、随机读写方法。
(1)java.io.File用于表示文件(目录),可以通过File类在程序中操作硬盘上的文件和目录
(2)File的每一个实例可以表示文件系统中的一个文件或目录
(3)使用File可以:
(4)不能对文件的内容进行访问
方法 | 功能 |
---|---|
long length() | 返回文件的大小(字节) |
long lastModified() | 返回文件最后一次被修改的时间 |
String getName() | 返回文件或目录的名称 |
String getPath() | 返回一个路径名字的字符串 |
boolean exists() | 判断文件或目录是否存在 |
boolean isFile() | 判断是否是一个标准文件 |
boolean isDirectory() | 判断是否是目录 |
boolean canRead() | 判断是否可读 |
boolean canWrite() | 判断是否可写 |
//项目所在路径下需存在demo.txt文件
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileDemo {
public static void main(String[] args) {
File file = new File("."+File.separator+"demo.txt"); //跨平台使用,避免耦合度,写相对路径(相对文件地址),File.separator(常量)(windows代表\;linux中代表/)
//获取名字
String name = file.getName();
System.out.println("name:"+name);
//大小(占用的字节量)
long length = file.length();
System.out.println("大小:"+length+"字节");
//是否为文件
boolean isFile = file.isFile();
System.out.println("是文件:"+isFile);
//是否为目录
boolean isDir = file.isDirectory();
System.out.println("是目录:"+isFile);
//是否为隐藏文件
boolean isHidden = file.isHidden();
System.out.println("是否隐藏:"+isHidden);
//最后修改时间
long time = file.lastModified();
Date date = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日 HH:mm:ss");
System.out.println(sdf.format(date));
//是否可写
boolean canWrite = file.canWrite();
System.out.println("可写:"+canWrite);
//是否可读
boolean isWrite = file.canWrite();
System.out.println("可读"+isWrite);
}
}
方法 | 功能 |
---|---|
long mkdir() | 创建指定目录 |
long mkdirs() | 创建指定目录,包括创建必须但不存在的父目录 |
String createNewFile() | 创建一个新的空文件 |
创建文件代码示例:
import java.io.File;
import java.io.IOException;
/**
* 创建一个文件
*/
public class FileDemo1 {
public static void main(String[] args) throws IOException {
/*
在当前目录下创建文件test.txt
默认路径就是当前目录,即“./”,所以可以不写
*/
File file = new File("test.txt");
if(!file.exists()){ //boolean exists()判断该文件是否真实存在
file.createNewFile(); //不存在创建文件
System.out.println("创建成功!");
}else{
System.out.println("文件已经存在!");
}
}
}
创建目录代码示例:
import java.io.File;
public class FileDemo3 {
public static void main(String[] args) {
/*
创建一个新目录
*/
File file = new File("demo"); //创建demo目录
if(!file.exists()){
file.mkdir();
System.out.println("创建目录成功!");
}else{
System.out.println("目录已存在!");
}
/*
创建多级目录
在当前目录下创建./a/b/c/d/e/f
*/
File file1 = new File("a"+File.separator+"b"+File.separator+"c"+File.separator+"d"+File.separator+"e"+File.separator+"f");
if (!file1.exists()){
file1.mkdirs(); //在创建当前目录的同时将所有不存在的父目录一起创建出来
System.out.println("创建成功!");
}
}
}
方法 | 功能 |
---|---|
boolean delete() | 删除文件或目录 |
删除文件代码示例:
import java.io.File;
/**
* 删除一个文件
*/
public class FileDemo2 {
public static void main(String[] args) {
File file = new File("test.txt"); //删除当前目录中的test.txt文件
if(file.exists()){
file.delete();
System.out.println("删除成功!");
}else{
System.out.println("文件不存在!");
}
}
}
删除目录代码示例:
import java.io.File;
/**
* 删除给定的文件或目录
*/
public class Test {
public static void main(String[] args) {
File file = new File("a");
delete(file);
}
public static void delete(File file){
if(file.isDirectory()){
//将其所有子项删除
File[] subs = file.listFiles();
for(File sub:subs){
delete(sub); //递归(整个流程都需要在走一遍):方法内部执行自己方法本身
}
}
file.delete();
}
}
delete方法可以删除一个目录,但是前提是该目录必须是一个空目录
方法 | 功能 |
---|---|
String[] list() | 返回目录中的文件和目录的名称所组成字符串的数组 |
String[] listFiles() | 返回目录中的文件 |
import java.io.File;
/**
* 获取一个目录中的所有子项
*/
public class FileDemo6 {
public static void main(String[] args) {
/*
* 获取当前目录中的所有子项
*/
File file = new File(".");
/*
boolean isFile()判断是否为一个文件
boolean isDirectory()
*/
if (file.isDirectory()){
/*
* File[] listFiles()获取所有子项
*/
File[] subs = file.listFiles();
for (File sub:subs){
if (sub.isFile()){
System.out.print("是文件:");
}else {
System.out.print("是目录:");
}
System.out.println(sub);
}
}
}
}
用于路径名的过滤器,此接口的实例可传递给File类的listFiles(FileFilter)方法
import java.io.File;
import java.io.FileFilter;
/**
* 获取一个目录中符合条件的部分子项
* 使用重载的listFiles方法,需要传入一个额外的文件过滤器
* 文件的过滤器是一个接口:FileFilter
*/
public class FileDemo7 {
public static void main(String[] args) {
File file = new File(".");
/*
获取名字以“.”开头的子项
*/
File[] subs = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
System.out.println("正在过滤"+pathname.getName());
return pathname.getName().startsWith(".");
}
});
for(File sub:subs){
System.out.println(sub.getName());
}
}
}
(1)、Java文件模型
在硬盘上文件是byte by byte存储的,是数据的集合
(2)、打开文件
有两种模式“rw”(读写)、“r”(只读)
RandomAccessFile raf = new RandomAccessFile(file,“rw”);
打开文件时候默认文件指针在开头pointer=0
(3)、写入方法
raf.write(int)可以将整数的“低八位”写入到文件中,同时指针自动移动到下一个位置,准备再次写入
(4)、读取文件
int b = raf.read()从文件中读取一个byte(8位)填充到int的低八位,高24位为0,返回值范围正数:0~255,如果返回-1表示读取到了文件末尾!每次读取后自动移动文件指针,准备下次读取
(5)、文件读写完一定关闭文件
如果不关闭,可能遇到一些意想不到的错误,根据具体操作平台不同会有不同。在使用过程中,切忌文件读写完成后要关闭文件
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* java.io.RandomAccessFile用来读写文件数据
* RAF是基于指针进行读写的,即RAF总是在指针指向的位置读写字节,并且读写后指针会自动向后移动
* RAF既可以读取文件数据也可以向文件中写入数据
*/
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
/*
RandomAccessFile(String path,String mode)
RandomAccessFile(File file,String mode)
第二个参数为模式:常用的有 r:只读模式 rw:读写模式
注:当文件不存在时会自动创建,但目录不存在时不会自动创建目录
*/
RandomAccessFile raf = new RandomAccessFile("demo.dat","rw");
/*
void write(int d)
写出给定的int值对应的2进制的低八位
vvvvvvvv
1:00000000 00000000 00000000 00000001
-1:11111111 11111111 11111111 11111111
255:00000000 00000000 00000000 11111111
256:00000000 00000000 00000001 00000000
a:97
*/
raf.write(97);
System.out.println("写入完毕!"); //多次运行是从头开始写,不会在之前内容后添加
raf.close();
}
}
方法 | 功能 |
---|---|
void write(byte[] b) | 从当前指针开始,将b.length个字节从指定字节数组写入到文件中 |
void write(byte[] b,int off,int len) | 指针从off处开始,将len个字节从指定数组中写入到文件中 |
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* java.io.RandomAccessFile用来读写文件数据
* RAF是基于指针进行读写的,即RAF总是在指针指向的位置读写字节,并且读写后指针会自动向后移动
* RAF既可以读取文件数据也可以向文件中写入数据
*/
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
/*
RandomAccessFile(String path,String mode)
RandomAccessFile(File file,String mode)
第二个参数为模式:常用的有 r:只读模式 rw:读写模式
注:当文件不存在时会自动创建,但目录不存在时不会自动创建目录
*/
RandomAccessFile raf = new RandomAccessFile("demo.dat","rw");
/*
void write(int d)
写出给定的int值对应的2进制的低八位
vvvvvvvv
1:00000000 00000000 00000000 00000001
-1:11111111 11111111 11111111 11111111
255:00000000 00000000 00000000 11111111
256:00000000 00000000 00000001 00000000
a:97
*/
raf.write(97);
System.out.println("写入完毕!"); //多次运行是从头开始写,不会在之前内容后添加
raf.close();
}
}
方法 | 功能 |
---|---|
int read(byte[] b) | 读取文件中的byte数据填充到buf数组中尽可能多的读取数据填充,返回值是读取的byte数量,返回值区间:(0,buf.legth)>0;如果返回-1表示读取到文件末尾了 |
int read(byte[] b,int off,int len) | 将最多len个字节从文件读入字节数组 |
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 读取文件数据
*/
public class RandomAccessFile1 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("demo.dat","r");
/*
int read()
读取一个字节,并以10进制的int型返回
若返回值为-1,则表示读取到了文件末尾
*/
int d = raf.read();
System.out.println(d);
raf.close();
}
}
方法 | 功能 |
---|---|
void seek(long pos) | 设置到此文件开头的指针偏移量,从该位置开始读取或写入操作 |
ins skipBytes(int n) | 尝试跳过输入的n个字节以丢弃跳过的字节 |
import java.io.IOException;
import java.io.RandomAccessFile;
/**
*
* RAF提供了方便读写基本类型数据的方法
*/
public class RandomAccessFileDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf1.dat","rw");
/*
long getFilePointer()
获取当前RAF的指针位置
*/
System.out.println("指针位置:"+raf.getFilePointer());
/*
向文件中写入一个int最大值
vvvvvvvv
01111111 11111111 11111111 11111111
*/
int max = Integer.MAX_VALUE;
raf.write(max>>>24);
raf.write(max>>>16);
raf.write(max>>>8);
raf.write(max);
raf.writeInt(max);
raf.writeLong(123L);
raf.writeDouble(123.123);
System.out.println("指针位置:"+raf.getFilePointer());
//EOFException:end of file
//int i = raf.readInt(); //指针在最后一位,读的话,因为指针在最后一位没有数据,所以会报EOFException异常
//System.out.println(i);
/*
void seek(long pos)
*/
raf.seek(0);
System.out.println("指针位置:"+raf.getFilePointer());
int i = raf.readInt();
System.out.println(i);
raf.seek(8);
long l = raf.readLong();
System.out.println(l);
double d = raf.readDouble();
System.out.println(d);
raf.seek(0);
l = raf.readLong();
System.out.println(l);
raf.close();
}
}
案例一:复制文件
import java.io.IOException;
import java.io.RandomAccessFile;
public class CopyDemo {
public static void main(String[] args) throws IOException {
/*
创建一个RAF读取原文件,再创建一个RAF向目标文件中写出
顺序从原文件中读取每一个字节并写入到目标文件中即可
*/
RandomAccessFile src = new RandomAccessFile("image.png","r");
RandomAccessFile desc = new RandomAccessFile("image_py.png","rw");
int d = -1;
long start = System.currentTimeMillis();
while ((d=src.read())!=-1){
desc.write(d);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:"+(end-start)+"毫秒");
src.close();
desc.close();
}
}
案例二:提高读写效率
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 若想提高读写效率,可以通过提高每次读写的数据量来减少读写的次数
*/
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("image.png","r");
RandomAccessFile desc = new RandomAccessFile("image01.png","rw");
/*
int read(byte[] data)
一次性尝试读取给定的字节数组总长度的字节量并存入到该数组中,返回值为实际读取到的字节量
若返回值为-1,则表示本次没有读取到任何数据(文件末尾)
*/
//10k
byte[] buf = new byte[1024*10];
int len = -1;
long start = System.currentTimeMillis(); //记录写入开始时间
while ((len = src.read(buf))!=-1){
/*
void write(byte[] data)
一次性将给定的字节数组中的所有字节写出
void write(bytr[] d,int start,int len)
将给定数组从下标start处开始的连续len个字节一次性写出
*/
desc.write(buf,0,len);
}
long end = System.currentTimeMillis(); //记录写入结束时间
System.out.println("写出完毕!耗时:"+(start-end)+"ms");
src.close();
desc.close();
}
}