File文件类
java使用File类表示操作系统上文件系统中的文件或目录。
换句话说,我们可以使用File操作硬盘上的文件或目录。
File可以描述文件或目录的名字,大小等信息不能对文件内容操作!
File类:描述文件系统中的一个文件或目录,我们可以通过File类来查看磁盘上的一个文件或目录,可以获取文件的信息:大小,文件名等,但是不能通过File获取文件内容。
我们还可以通过File类来创建文件或目录,删除文件或目录。
package day01;
import java.io.File;
import java.io.IOException;
/**
* File类
*
* @author Administrator
*
*/
public class DemoFile {
public static void main(String[] args) {
/**
* 实例化一个文件,代表给定路径的文件或目录
*
* 路径的描述不同的文件系统差异较大 linux和windows就不同! 最好使用相对路径,不要用绝对路径。
*/
/**
* "."代表的路径:当前目录 项目所处的目录 eclipse_workspace/project_name/
* File.separator目录分割符。推荐使用! Windows/ Linux\
*/
/**
* 创建该对象并不意味着硬盘上对应路径上就有该文件了 只是在内存中创建了该对象去代表路径指定的文件。当然这个路径对应的文件可能 根本不存在!
*/
// File file = new File("."+File.separator+"data.dat");
File file = new File("C:\\Users\\Administrator\\Desktop\\学习截图\\File类\\data.dat");
if (!file.exists()) {
/**
* 创建file代表的文件 调用该文件后,硬盘中就会存在该文件了! 这里要求强制捕获异常!createNewFile有throws声明
* 说明不是RunTimeException的子类
*/
try {
file.createNewFile();
System.out.println("创建文件成功!");
} catch (IOException e) {
e.printStackTrace();
System.out.println("创建文件失败了!");
}
}
}
}
package day01;
import java.io.File;
/**
* 使用File创建目录
* @author Administrator
*
*/
public class DemoFileDir {
public static void main(String[] args) {
try{
//在项目根目录下创建demo目录并创建子目录A
//路径 ./demo/A
// File dir = new File("."+File.separator+"demo"+File.separator+"A);
File dir = new File("C:\\Users\\Administrator\\Desktop\\学习截图\\File类\\demo\\A");
if(!dir.exists()){
//不存在则创建该目录
/**
* mkdir():只能在已有的目录基础上创建目录。
* mkdirs():可以创建所有必要的父目录并创建该目录
*/
// dir.mkdir();//没有子目录
dir.mkdirs();//有子目录
System.out.println("目录创建成功!");
}
}catch (Exception e){
System.out.println("目录创建失败了!");
}
}
}
package day01;
import java.io.File;
import java.io.IOException;
/**
* 在A目录下创建文件data.dat
* @author Administrator
*
*/
public class DemoCreateFile {
public static void main(String[] args) throws IOException {
/**
* 两种方式:
* 1:直接指定data.dat需要创建的位置,
* 并调用createNewFile()。前提是,目录都要存在!
* 2:先指定data.dat的目录,不存在的都创建好后再创建文件
*/
//1 ./demo/A/data.dat
// File file = new File("."+File.separator+"demo"+File.separator+
// "A"+File.separator+"data.dat");
// if(!file.exists()){
// //我们将异常抛出到main方法外,仅供演示!实际不能这么干!
// file.createNewFile();
// System.out.println("文件创建成功!");
// }
//2
/**
* 步骤:
* 1.创建一个File实例,data.dat即将存放的目录
* 2.若该目录不存在,则创建所有不存在的目录
* 3.再创建一个File实例,代表data.dat文件。创建是基于上一个代表
* 目录的File实例的
* 4.创建该文件data.dat
*/
//1
File dir = new File("."+File.separator + "demo"+File.separator+"A");
//2
if(!dir.exists()){
dir.mkdirs();//不存在则创建所有必须的父目录和当前目录
}
/**
* 3 File(File dir,String fileName)构造方法,在dir所代表的目录中表示fileName指定的文件
*/
File file = new File(dir,"data.dat");
if(!file.exists()){
file.createNewFile();
System.out.println("文件创建完毕!");
}
}
}
package day01;
import java.io.File;
/**
* 查看目录下的子目录或文件
* @author Administrator
*
*/
public class DemoSubFiles {
public static void main(String[] args) {
File dir = new File(".");
//是否为一个目录
if(dir.exists()&&dir.isDirectory()){
//获取当前目录的子项(文件或目录)
//在Linux中和命令ls效果相同。获取子项
File[] files = dir.listFiles();
//循环子项
for(File file : files){
//若这个子项是一个文件
if(file.isFile()){
System.out.println("文件:"+file.getName());
}else{
System.out.println("目录:"+file.getName());
}
}
}
}
}
package day01;
import java.io.File;
import java.io.IOException;
/**
* 文件工具类
*
* @author Administrator
*
*/
public class FileUtils {
/**
* 列出给定目录下的所有子项(包括子目录中的子项)的名字
*
* @param dir
* @throws IOException
*/
public static void listDirectory(File dir) throws IOException {
if (dir == null) {
throw new IllegalArgumentException(dir + "为空!");
}
/**
* 判断参数给定的目录是否存在。 要做对参数的合法性判断,避免程序出错
*/
if (!dir.exists()) {
/**
* 无效的参数异常 IllegalArgumentException也是RuntimeException子类
*/
throw new IllegalArgumentException("目录:" + dir + "不存在!");
}
/**
* 再次进行安全验证,查看是否为一个目录而不是文件!
*/
if (!dir.isDirectory()) {
throw new IllegalArgumentException(dir + "不是一个目录!");
}
// 获取当前目录下的所有子项
File[] files = dir.listFiles();
// 判断子项数组有效
if (files != null && files.length > 0) {
// 遍历该目录下的所有子项
for (File file : files) {
// 若子项是目录
if (file.isDirectory()) {
/**
* 当前方法的作用就是给定一个目录,输出目录下的所有子项,所以,若这个
* 还是一个目录,自然还可以通过当前方法输出其子项,这种在当前方法中 调用当前方法的行为被称为 递归
* 不到万不得已,尽量不使用递归,非常消耗资源
*/
listDirectory(file);
// 否则是一个文件,那么我们直接输出文件名
} else {
System.out.println(file);// 输出File的toString()
}
}
}
}
}
package day01;
import java.io.File;
/**
* 测试FileUtils
* @author Administrator
*
*/
public class TestFileUtils {
public static void main(String[] args){
try{
//输出当前项目下的所有文件
FileUtils.listDirectory(new File("."));
}catch (Exception e){
e.printStackTrace();
}
}
}
FileFilter:文件过滤器
FileFileter是一个接口,可以规定过滤条件,在获取某个目录时可以通过给定的删选条件来获取满足要求的子项。
回调模式:
我们定义一段逻辑。在调用其他方法时将该逻辑通过参数传入。这个方法在执行过程中会调用我们传入的逻辑来达成目的。这种现象就是回调模式。
最常见的应用环境:
按钮监听器
过滤器的应用
package day01;
import java.io.File;
import java.io.FileFilter;
/**
* 文件过滤器
* 用于在获取某个目录下的子项时筛选出符号条件的子项
* @author Administrator
*
*/
public class DemoFileFilter {
public static void main(String[] args) {
/**
* 定义一个文件过滤器,用于过滤.java文件
*/
FileFilter filter = new FileFilter(){
/**
* accept方法是用来定义过滤条件的
* 参数pathname是将被过滤的目录中的每个子项依此传入进行匹配
* 若我们认为该子项满足条件则返回true
*/
public boolean accept(File pathname){
//保留文件名以.java结尾的
return pathname.getName().startsWith(".");
}
};
File dir = new File(".");
//获取所有子项
// File[] sub = dir.listFiles();
//获取过滤器中满足条件的子项
File[] sub = dir.listFiles(filter);//回调模式
for(File file:sub){
System.out.println(file);
}
}
}
RandomAccessFile
作用:可以方便的读写文件内容。
计算机的硬盘在保存数据时都是byte by byte 的字节挨着字节。
RandomAccessFile
打开文件模式:
rw:打开文件后可进行读写操作。
r:打开文件后只读。
write(int data):写一个字节,写这个int值得第8位
write(byte[] data):将一组字节写入。
read():读一个字节,若已经读取到文件末尾,返回-1。
int read(byte[] buf):
尝试读取buf.length个字节。并将读取的字节存入buf数组。
返回值:实际读取的字节数。
RandomAccessFile是基于指针进行读写操作的,指针在哪里就从哪里读/写。
package day01;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
/**
* RandomAccessFile读写文件
* @author Administrator
*
*/
public class DemoRandomAccessFile {
public static void main(String[] args) throws IOException {
/**
* 向文件.\data.dat中写数据
* 步骤:
* 1:创建一个File对象用于描述该文件
* 2:不存在则创建该文件
* 3:创建RandomAccessFile,并将File传入。
* 使RandomAccessFile对File表示的文件进行读写操作
* 4:向文件中写入内容
*/
//1
File file = new File("data.dat");
//2
if(!file.exists()){
//创建该文件
file.createNewFile();
}
//对file文件可以进行读写操作
RandomAccessFile raf = new RandomAccessFile(file,"rw");
/**
* 4
* 写一个int最大值
* write(int)写一个字节
*/
int i = 0x7fffffff;//in最大值
//写int值最高的8位
raf.write(i>>>24);//00 00 00 7f
raf.write(i>>>16);//00 00 7f ff
raf.write(i>>>8); //00 7f ff ff
raf.write(i); //7f ff ff ff
//定义一个10字节数组
byte[] data = new byte[]{0,1,2,3,4,5,6,7,8,9};
//将这10个字节全部写入文件
raf.write(data);
//写到这里,当前文件应该有14个字节了
/**
* 写字节数组得重载方法。
* write(byte[] data,int offset,int length)
* 从data数组得offset位置开始写,连续写length个字节到文件中。
*/
raf.write(data ,2,5);//{2,3,4,5,6}
/**
* 011111111 11111111 11111111 11111111
* num: 011111111 00000000 00000000 00000000
* b: 000000000 00000000 00000000 01111111
*b<<24: 011111111 00000000 00000000 00000000
*/
System.out.println("当前指针位置:"+raf.getFilePointer());
raf.seek(0);//将指针移动到文件开始的位置
System.out.println("当前指针位置:"+raf.getFilePointer());
int num = 0;//准备读取得int值
int b = raf.read();//读取第一个字节7f
System.out.println("当前指针位置:"+raf.getFilePointer());
num = num|(b<<24);//011111111 00000000 00000000 00000000
b = raf.read();//读取第二个字节 ff
num = num|(b<<16);
b = raf.read();//读取第三个字节 ff
num = num|(b<<8);
b = raf.read();//读取第四个字节
num = num|b;
System.out.println("int最大值"+num);
raf.seek(0);//回到文件的开始位置
byte[] buf = new byte[1024];//1k的容量
int sum = raf.read(buf);//尝试读取1k的数据
System.out.println("总共读取了"+sum+"个字节");
System.out.println(Arrays.toString(buf));
}
}
package day01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 使用RandomAccessFile完成文件复制 思路:读取一个文件,将这个文件中的每一个字节写到另一个文件中就完成了复制功能
*
* @author Administrator
*
*/
public class CopyFile {
public static void main(String[] args) throws IOException {
/**
* 1.创建一个用于读取文件的RandomAccessFile用于读取被拷贝的文件
* 2.创建一个用于写入文件的RandomAccessFile用于写入拷贝的文件
* 3.读取被拷贝文件的所有字节并写到拷贝文件中
*/
//1
File srcFile = new File("1.txt");
RandomAccessFile src = new RandomAccessFile(srcFile,"r");
//2
File desFile = new File("1copt.txt");
desFile.createNewFile();//创建复制文件
RandomAccessFile des = new RandomAccessFile(desFile,"rw");
//3
// int data = 0;//用于保存每一个读取的字节
// //读取一个字节,只要不是-1(文件末尾),就进行复制工作
// while((data = src.read())!=-1){
// des.write(data);//将读取的字节写入
// }
/**
* 使用字节数组作为缓冲,批量读写进行复制操作
* 比一个字节一个字节读写效率高得多!
*/
byte[] buff = new byte[1024*100];//创建一个字节数组
int sum = 0;//每次读取的字节数
while((sum = src.read(buff))>0){
des.write(buff,0,sum);
}
src.close();
des.close();
System.out.println("复制完毕!");
}
}
WriteInt(111):将int值111转换为字节并写入磁盘。
基本类型序列化:将基本类型数据转换为字节数组的过程。
持久化:将数据写入磁盘的过程
package day01;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* RandomAccessFile的其他读写操作
* @author Administrator
*
*/
public class DemoRandomAccessFile2 {
public static void main(String[] args) throws IOException {
/**
* 创建RandomAccessFile的另一个构造方法
* 直接根据文件路径指定。前提是确保其存在!
*/
RandomAccessFile raf = new RandomAccessFile("data.dat","rw");
//写int最大值
raf.writeInt(Integer.MAX_VALUE);//一次写4个字节。写int值
//写long最大值
raf.writeLong(Long.MAX_VALUE);
//以UTF-8编码将字符串写入文件
raf.writeUTF("hello!");
raf.seek(0);
int intMax = raf.readInt();//连续读取4字节返回该int值
long longMax = raf.readLong();
String info = raf.readUTF();
System.out.println("int最大值"+intMax);
System.out.println("long最大值"+longMax);
System.out.println("字符串:"+info);
}
}