Java学习笔记(37)-File类

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);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值