File
概述:
想要实现IO流操作,就必须要知道硬盘上文件的表现形式
Java提供了一个类让我们操作硬盘上的文件:File。File也就是文件的表现形式
File:文件和目录(文件夹)路径名的抽象表示。
File类的构造方法
代码举例:
import java.io.File;
public class Demo1 {
public static void main(String[] args) {
// 根据一个路径得到一个对象
File file = new File("D:\\IdeaProjects\\a.txt");
System.out.println(file);
// 根据父子路径得到对象
File file1 = new File("D:\\IdeaProjects", "b.txt");
System.out.println(file1);
// 将父路径粉装成一个File,再根据父子路径得到对象
File file2 = new File("D:\\IdeaProjects");
File file3 = new File(file2, "c.txt");
System.out.println(file3);
}
}
结果:这里得到的结果都是绝对路径
File类的成员方法
创建功能:
代码举例:
import java.io.File;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) {
File file = new File("D:\\IdeaProjects\\demo");
// 封装成File对象,不需要文件或者目录是否已经存在,它只是将一个路径抽象的用File表示
// 在指定路径下创建一个文件夹demo
System.out.println(file.mkdir());
// 在demo下创建一个文件a.txt,这里需要对编译时期异常做处理
// 将目标文件封装成一个File
File file1 = new File("D:\\IdeaProjects\\demo\\a.txt");
try {
System.out.println(file1.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
// 创建多级文件夹
File file2 = new File("D:\\IdeaProjects\\demo2\\demo3\\demo4");
System.out.println(file2.mkdirs());
// 在一个不存在的目录下创建一个文件
File file3 = new File("D:\\IdeaProjects\\demo5\\b.txt");
try {
System.out.println(file3.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果:
在相对应硬盘文件夹中会产生对应操作的结果:
注意:若是想在某个目录下创建文件,前提是该目录必须存在。且需要清楚到底需要创建文件夹还是文件。
删除功能
代码举例:
import java.io.File;
import java.io.IOException;
public class Demo4 {
public static void main(String[] args) {
// 创建一个文件
File file = new File("D:\\IdeaProjects\\a.txt");
try {
System.out.println(file.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
// 删除文件
System.out.println(file.delete());
// 删除多级文件夹。必须保证被删除的文件夹内容为空
File file1 = new File("D:\\IdeaProjects\\demo2\\demo3\\demo4");
System.out.println(file1.delete());//删除demo4
File file2 = new File("D:\\IdeaProjects\\demo2\\demo3");
System.out.println(file2.delete());//删除demo3
File file3 = new File("D:\\IdeaProjects\\demo2");
System.out.println(file3.delete());//删除demo2
}
}
结果:
重命名功能
代码举例:
import java.io.File;
public class Demo4 {
public static void main(String[] args) {
File file = new File("D:\\dlam.jpg");
File file1 = new File("D:\\哆啦A梦.jpg");
System.out.println(file.renameTo(file1));
}
}
输出结果:true,相应的文件被更改名字
判断功能
代码举例:对之前在demo文件夹中创建的a.txt文件进行判断,其属性为可读可写没隐藏
import java.io.File;
public class Demo5 {
public static void main(String[] args) {
File file = new File("D:\\IdeaProjects\\demo\\a.txt");
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.exists());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isHidden());
}
}
结果:
获取功能
代码举例:
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo6 {
public static void main(String[] args) {
File file = new File("D:\\IdeaProjects\\demo\\a.txt");
System.out.println(file.getAbsolutePath());
System.out.println(file.getPath());
System.out.println(file.getName());
System.out.println(file.length());
System.out.println(file.lastModified());
// 该时间戳直接输出的结果无法理解,需要与日期类做转换
// 分配一个 Date对象,并将其初始化为表示自称为“时代”的标准基准时间以后的指定毫秒数,即1970年1月1日00:00:00 GMT。
Date date = new Date(file.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = sdf.format(date);
System.out.println(format);
}
}
结果:
高级获取功能
代码举例:
import java.io.File;
public class Demo7 {
public static void main(String[] args) {
File file = new File("D:\\IdeaProjects");
String[] list = file.list();
for(String s : list){
System.out.println(s);
}
System.out.println("-------------");
File[] files = file.listFiles();
for (File f : files){
System.out.println(f);
}
}
}
结果:
分析:将D盘封装成一个File对象,再获取该目录下的所有文件和文件夹组成的File数组,遍历数组得到每一个File对象,对每一个对象进行判断是否是文件,若是则判断是否以.jpg结尾,是就输出
代码实现:
import java.io.File;
public class Demo8 {
public static void main(String[] args) {
File file = new File("D:\\");
File[] files = file.listFiles();
for(File f : files){
if(f.isFile()){
if(f.getName().endsWith(".jpg")){//判断文件名称是否以.jpg结尾
System.out.println(f.getName());
}
}
}
}
}
结果:D盘下只有一个.jpg文件
另一种实现方法:
文件名称过滤器的实现思想和代码:
这两个代码都是在获取文件夹和文件组成的数组时,只获取满足条件的数据,不需要遍历,只要获取完直接输出就是满足条件的数据
源码中过滤器是一个接口,其中有一个布尔类型的accept方法,所以在调用时需要重写accept方法
代码实现:
import java.io.File;
import java.io.FilenameFilter;
public class Demo9 {
public static void main(String[] args) {
File file = new File("D:\\");
// 使用匿名内部类创建过滤器对象
String[] list = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// return false;
// 目录下的文件或文件夹获不获取,取决于返回值
// 通过输出测试:dir是文件所在绝对路径,name是文件名称
File file1 = new File(dir, name);
boolean b = file1.isFile();
boolean b1 = name.endsWith(".jpg");
return b
}
});
for (String s : list){
System.out.println(s);
}
}
}
结果:同上述输出结果一样
递归
概述:方法定义中调用方法本身的现象
斐波那契数列(兔子问题)举例:从第三天开始,每天兔子的数量是前两天数量之和,求第20天兔子的数量。
/*
递归
斐波那契数列(兔子问题)
*/
public class FDemo9 {
public static void main(String[] args) {
int rabbit = Fibonacci(20);
System.out.println(rabbit);
}
public static int Fibonacci(int i){
if(i==1 | i==2){
return 1;
}
else{
return Fibonacci(i-1)+Fibonacci(i-2);
}
}
}
结果:
递归删除带内容的目录
代码实现:
import java.io.File;
/*
递归删除带内容的目录
分析:
1、获取File对象
2、获取该目录下所有的文件和文件夹组成的File对象数组
3、遍历数组得到每一个File对象
4、判断这个File对象是否是文件夹
是:返回第二步
不是:直接删除
*/
public class FDemo3 {
public static void main(String[] args) {
File file = new File("D:\\IdeaProjects\\Data15\\aaa");
deleteFile(file);
}
public static void deleteFile(File file){
File[] files = file.listFiles();
for (File f : files){
if(f.isDirectory()){
deleteFile(f);
}else{
System.out.println(f.getName()+"---"+f.delete());
}
}
System.out.println(file.getName()+"---"+file.delete());
}
}
结果:
IO流
IO流用来处理设备之间的数据传输
IO流的分类:
流向:
输入流 读取数据,从硬盘中读取数据到Java程序中
输出流 写出数据,从Java程序中输出数据到硬盘中
数据类型:
字节流
字节输入流 读取数据 InputStream
字节输出流 写出数据 OutputStream
字符流
字符输入流 读取数据 Reader
字符输出流 写出数据 Writer
字节流:
写数据:
OutputStream FileOutputStream 创建文件输出流以写入由指定的 File对象表示的文件。
需求:往D:\IdeaProjects\demo下的a.txt中输入一行"yyds"。
这里最好使用字符流来操作,但这里使用字节流来操作
这里使用OutputStream,他是一个抽象类,不能直接实例化。
所以需要他的一个子类FileOutputStream
FileOutputStream的构造方法:
代码实现:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class IOdemo1 {
public static void main(String[] args) throws Exception{
File file = new File("D:\\IdeaProjects\\demo\\a.txt");
FileOutputStream fos = new FileOutputStream(file);
// 若这里目标文件没有,则会自动创建
fos.write("yyds".getBytes());
// 若此时继续执行一遍,会将yyds覆盖掉
//释放资源
//close()关闭此文件输出流并释放与此流相关联的任何系统资源。
fos.close();
}
}
输出结果是什么都没有,但此时a.txt文件中以及有了yyds的内容
代码中提到:操作完写数据操作后需要释放资源,否则会一直占用栈内存,若后续还有很多操作,则可能会造成内存溢出。
字节输出流写数据的几种方法:
代码举例:
import java.io.FileOutputStream;
public class IOdemo2 {
public static void main(String[] args) throws Exception {
//创建字节输出流对象
FileOutputStream fos = new FileOutputStream("D:\\IdeaProjects\\demo\\a.txt");
//public void write(int b)
//97,底层存储的二进制,97对应的ASCII码的字符是a
fos.write(97);
fos.write(48);
fos.write(65);
//public void write(byte[] b)
byte[] byts = {97, 98, 99, 100, 101};
fos.write(byts);
//public void write(byte[] b,int off,int len)
//从位于偏移量 off的指定字节数组写入 len字节到该文件输出流。
fos.write(byts, 1, 3);
//释放资源
fos.close();
}
}
输出结果:需要在a.txt中查看:
当在释放资源后,再次使用FileOutputStream创建一个新的对象时,再向其中添加内容时,之前的内容会被覆盖。
实现追加与换行:
代码举例:
import java.io.FileOutputStream;
public class IOdemo3 {
public static void main(String[] args) throws Exception{
FileOutputStream fos = new FileOutputStream("D:\\IdeaProjects\\demo\\a.txt",true);
// 实现换行,只需要加入换行符即可
fos.write("\r\n今天下雪了\r\n".getBytes());
fos.write("但没有积雪".getBytes());
fos.close();
}
}
输出结果:
什么情况下,用字节流还是字符流,如果你操作的是记事本打开能看懂的数据,就用字符流,如果看不懂就用字节流
如果你不知道用什么流,就用字节流,字符流是建立在字节流的基础上出现的。