一 .File类
1.File类的概述
数据的存储:计算机中的硬盘和计算机中的内存
计算机中的硬盘:好处是可以持久化存储数据,当计算 机断电了,数据依然可以在下次开机的时候进行读取和 使用。弊端是相较于内存来说,读取和存储数据速度慢 一些.
计算机中的内存:好处是存储数据和读取数据的速度 会变的非常快。弊端是相较于硬盘来说,内存断电了或 者程序停止了存储在内存中的数据就会消失。
File类就是文件和目录路径名的抽象表示形式。主要用于 文件和目录的创建、查找和删除等操作。
2. File类的构造方法
/**
* 在Java中使用File的对象来表示我们系统的文件或者
文件夹
* File(String pathname)
* 参数pathname:文件或者文件夹在系统的路径
* File(String parent,String child):
* 父路径+子路径确定一个文件或者文件夹的路径
* File(File parent,String child):
* file形式的父路径+字符串形式的父路径确定一
个文件或者文件夹的路径
*
* 需求:根据 E:\test\a.txt 封装一个File对象
*/
public class DemoTest {
public static void main(String[] args) {
//第一种构造方式
File file01=new File("E:\\test\\a.txt");
System.out.println(file01);
//第二种构造方式 子路径父路径拼接在一起
File file02=new File("E:\\test","a.txt");
System.out.println(file02);
//使用File表示目录
File dir=new File("E:\\test");
System.out.println("目录是:"+dir);
//第三种构造
File file03=new File(dir,"a.txt");
System.out.println(file03);
//注意:File封装的对象仅仅是一个路径名。它可以是存在的,也可以是不存在的。
File file04=new File("E:\\test\\b.txt");
System.out.println(file04);
}
}
注意事项:File封装的对象仅仅是一个路径名。它可以是 存在的,也可以是不存在的。存在可以操作,不存在可以创建。
3.File类的判断方法
/**
* public boolean exists() :此File表示的文件
或目录是否实际存在。
* public boolean isFile() :此File表示的是否
为文件。
* public boolean isDirectory() :此File表示
的是否为目录。
*/
public class DemoTest {
public static void main(String[] args) {
File file01=new File("E:\\test\\a.txt");
File file02=new File("E:\\test\\b.txt");
System.out.println("file01存在吗?"+file01.exists());//true
System.out.println("file02存在吗?"+file02.exists());//false
System.out.println("-------------------------");
File dir01=new File("E:\\test");
File dir02=new File("E:\\hello");
System.out.println("dir01存在吗"+dir01.exists());//true
System.out.println("dir02存在吗"+dir02.exists());//false
System.out.println("-------------------------");
//判断是文件还是文件夹
System.out.println("file01是文件吗?"+file01.isFile());//true
System.out.println("file01是文件夹(目录)吗?"+file01.isDirectory());//false
System.out.println("dir01是文件吗?"+dir01.isFile());//false
System.out.println("dir01是文件夹(目录)吗?"+dir01.isDirectory());//true
}
}
注意事项:判断是文件或者是目录的时候,如果目标文件 不存在也会返回flase.
4.File类的获取方法
/**
* - public String getAbsolutePath() :返回此File的绝对路径名字符串。(带盘符的路径)
* - public String getPath() :将此File转换为路径名字符串。 (获取的是 封装路径)
* - public String getName() :返回由此File表示的文件或目录的名称。
* - public long length() :返回由此File表示的文件的长度。 不能获取目录的长度。
*/
public class DemoTest {
public static void main(String[] args) {
File file01=new File("E:\\test\\a.txt");
System.out.println("获取封装路径:"+file01.getPath());
System.out.println("获取绝对路径:"+file01.getAbsolutePath());
System.out.println("获取文件的名字:"+file01.getName());
System.out.println("获取文件里面有多少个字节:"+file01.length());
}
}
5,相对路径和绝对路径
public class DemoTest {
public static void main(String[] args) {
//问题:能否完成 将当前模块下 a.txt文件封装 a.txt
File file01=new File( "D:\\develop\\lzw\\java_0709\\a.txt");
//封装的路径是 盘符开头的 这种封装方式采用的 绝对路径方式(带盘符的形式)
System.out.println("获取封装路径:"+file01.getPath());
System.out.println("获取绝对路径:"+file01.getAbsolutePath());
//相对路径 相对 project而言
//相对于 project而言 我们的路径是 当前模块\a.txt
File file02=new File( "java_0709\\a.txt");
System.out.println("获取封装路径:"+file02.getPath());
System.out.println("获取绝对路径:"+file02.getAbsolutePath());
/* 当操作的文件是 本模块中的文件的 时候 采用相对路径
当操作的文件是 非本模块中文件的时候 采用绝对路径
*/
}
}
6.File类的创建和删除方法
/**
* - public boolean createNewFile():当且仅当
具有该名称的文件尚不存在时,创建一个新的空文件。
* - public boolean mkdir():创建一个单级文件夹
* - public boolean mkdirs():创建一个多级文件夹。
*
* 如果文件夹或者文件已经存在,则会返回false
*
* - public boolean delete():删除由此File表示的文件或目录。
* 删除文件夹的时候,如果文件夹中还有文件是不会删除成功的.
*/
public class DemoTest {
public static void main(String[] args) throws IOException {
//在 当前模块下创建一个文件 b.txt
File file01 = new File("java_0709\\b.txt");
/*
java.io.IOException: 系统找不到指定的路径。
File file02 = new File("java_0709A\\b.txt");
file02.createNewFile();
*/
//创建文件方法
boolean lean01 = file01.createNewFile();
System.out.println("是否创建成功:"+lean01);
//创建一个文件夹
File dir01 = new File("java_0709\\A");
boolean lean02 = dir01.mkdir();
System.out.println("是否创建成功:"+lean02);
//创建多级目录
File dir02 = new File("java_0709\\B\\C");
boolean lean03 = dir02.mkdirs();
System.out.println(lean03);
//删除文件和文件夹 慎用
System.out.println("删除b.txt文件:"+file01.delete());
System.out.println("删除A文件夹:"+dir01.delete());
File dir03 = new File("java_0709\\B");
System.out.println("删除B文件夹:"+dir03.delete());
}
}
7.File类的遍历方法
public class DemoTest {
public static void main(String[] args)
throws IOException {
File srcDir = new File("java_0709\\A");
//获取文件夹下的子目录和子文件的名字
String[] list = srcDir.list();
for (String str : list) {
System.out.println(str);
}
System.out.println("------------------------");
//获取文件夹下子目录和子文件的 file对象形式
File[] files = srcDir.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
}
}
注意事项:如果文件夹路径不存在或者没有访问权限, 以上2个方法获取的时候会返回null,容易出现空指针异 常。所以大家在遍历获取到的子文件和子目录之前,应该 做非空判断
二.方法递归
1.递归的概述
public class DemoTest {
public static void main(String[] args)
throws IOException {
method(100);
}
public static void method(int num){
System.out.println("调我呀");
num--;
if(num==0){
return;
}
method(num);
}
}
2.递归求和
需求:定义方法,计算1 ~ n的累加和
/**
* 1-n的和
* getSum(n-1)+n
* 1-5的和
* 1+2+3+4+5 getSum(4)+5
* 1-4的和
* 1+2+3+4 getSum(3)+4
* 1-3的和
* 1+2+3 getSum(2)+3
* 1-2的和
* 1+2 getSum(1)+2
* 1的和
* 1
*/
public class DemoTest {
public static void main(String[] args)
throws IOException {
int method = getSum(5);
System.out.println(method);
}
public static int getSum(int n){
if(n==1){
return 1;
}
return getSum(n-1)+n;
}
// public static int getSum(int n){
// int sum=0;
// for(int i=1;i<=n;i++){
// sum+=i;
// }
//
// return sum;
// }
}
3.递归获取文件夹下所有文件
/**
* 需求:设计一个方法,可以遍历某个文件夹下所有的文件
包含子目录中的文件
* 并把文件的绝对路径打印出来
*/
public class DemoTest {
public static void main(String[] args)
throws IOException {
File dir = new File("java_0709\\A");
printDir(dir);
}
public static void printDir(File dir){
//被传入的文件夹
//获取 当前dir下所有的文件和文件夹
File[] files = dir.listFiles();
//进行遍历 拿到每个文件和文件夹 对象file
for (File file : files) {
//file是文件还是文件夹 都有
if(file.isFile()){// 文件
System.out.println("文件的路径是:"+file.getAbsolutePath());
}else {
//file是一个文件夹 怎么办? 继续找'
printDir(file);
}
}
}
}
三.IO概述
1.IO流介绍
以前我们是通过变量,数组,或者集合存储数据,都是不能永久化存 储 , 因为数据都是存储在内存中,只要代码运行结束,所有数据都会丢失。
2.IO的分类
3.IO的顶层父类
四.字节流
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的 形式保存,都一个一个的字节,那么传输时一样如此。所以,字节 流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无 论使用什么样的流对象,底层传输的始终为二进制数据。
1.字节输出流OutputStream
2.FileOutputStream类
public class DemoTest {
public static void main(String[] args) throws
IOException {
//1.创建字节输出流
OutputStream os = new FileOutputStream("java_0724_0708\\hello.txt");
//2.操作,往文件写数据
os.write('b');
//os.write(97); 注意:写出的整数,实际写出的是整数在码表上对应的字符。
//3.关闭流,释放资源
os.close();
}
}
public class DemoTest {
public static void main(String[] args) throws Exception {
//1.创建流对象
FileOutputStream fis= new
FileOutputStream("java_0724_0708\\hello.txt");
//2.操作,写字节数组
//byte[] bs={97,98,99,100,101};
String str="你好";
byte[] bytes = str.getBytes();//[-28, -67, -96, -27, -91, -67]
fis.write(bytes);
//3.关闭流,释放资源
fis.close();
}
}
public class DemoTest {
public static void main(String[] args) throws
Exception {
//1.创建流对象
FileOutputStream fis= new
FileOutputStream("java_0724_0708\\hello.txt");
//2.操作 写字节数组
String str="你好";
//[-28, -67, -96, -27, -91, -67]
//utf8编码一个中文占3个字节,gbk编码一个中文占2个字节
fis.write(str.getBytes(),0,6);
//3.关闭流 释放资源
fis.close();
}
}
3.数据换行与追加
public class DemoTest {
public static void main(String[] args) throws Exception {
//1.创建流对象
FileOutputStream fos= new
FileOutputStream("java_0724_0708\\hello.txt",true);
//2.操作
fos.write("张三".getBytes());
fos.write("\r\n".getBytes());
fos.write("李四".getBytes());
fos.write("\r\n".getBytes());
fos.write("王五".getBytes());
fos.write("\r\n".getBytes());
fos.write("赵六".getBytes());
//3.关闭流 释放资源
fos.close();
}
}
4.字节输入流InputStream
5.FileInputStream类
注意:当你创建一个流对象时,必须传入一个文件路径。该路径 下,如果没有该文件,会抛出FileNotFoundException
6.读取字节
int read(),每次可以读取一个字节的数据,提升为int类型,读取到 文件末尾,返回-1。
public class DemoTest {
public static void main(String[] args) throws Exception {
//1.创建流对象 当关联的文件不存在时:运行时异常
//FileInputStream fis=new
FileInputStream("java_0724_0708\\a.txt");
FileInputStream fis=new
FileInputStream("java_0724_0708\\hello.txt");
//2.操作 读取数据
int read01 = fis.read();
System.out.println(read01);//65 读出来的是文件中数据的码表值。
// char c = (char) fis.read();
// System.out.println(c);
int read02 = fis.read();
System.out.println(read02);
int read03 = fis.read();
System.out.println(read03);
int read04 = fis.read();
System.out.println(read04);// -1 当读取不到数据
时,返回:-1
//3.关闭流 释放资源
fis.close();
}}
public class DemoTest {
public static void main(String[] args) throws Exception {
//1.创建流对象 当关联的文件不存在时:运行时异常
//FileInputStream fis=new
FileInputStream("java_0724_0708\\a.txt");
FileInputStream fis=new
FileInputStream("java_0724_0708\\hello.txt");
//2.操作 读取数据
// while(true){
// int data = fis.read();
// if(data==-1){
// break;
// }
// System.out.println(data);
// }
// int data = fis.read();
// while(data!=-1){
// System.out.println(data);
// data=fis.read();
// }
int data;
while((data = fis.read())!=-1){
System.out.println(data);
}
//3.关闭流 释放资源
fis.close();
}
}
public class DemoTest {
public static void main(String[] args) throws
Exception {
//创建字节输入流,关联源文件(读)
FileInputStream fis=new
FileInputStream("E:\\上课资料\\0725_Java_0708\\课堂笔记
\\1.webp");
//创建字节输出流,关联目标文件(写)
FileOutputStream fos=new
FileOutputStream("java_0724_0708\\1.webp");
long begin = System.currentTimeMillis();
//循环:读数据、写数据
int data;
while((data=fis.read())!=-1){
//把读取的数据写入到目标文件中
fos.write(data);
}
long end = System.currentTimeMillis();
System.out.println("共消耗:"+(end-begin));
//释放资源
fis.close();
fos.close();
}
}
7.IO资源的处理
public class DemoTest {
public static void main(String[] args){
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//1.创建字节输入流 关联源文件
fis=new FileInputStream("E:\\1.mp4");
//2.创建字节输出流 关联目标文件
fos= new
FileOutputStream("java_0725_0708\\1.mp4");
//获取当前时间的毫秒值
long begin = System.currentTimeMillis();
//3.循环读写
int data;
while((data=fis.read()) !=-1){
//把读取到的数据写入到目标文件中
fos.write(data);
}
long end = System.currentTimeMillis();
System.out.println("共消耗:"+(endbegin));
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.释放资源
try {
if(fis !=null){
fis.close();
}
if(fos!=null){
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
格式 :
try (创建流对象语句1 ; 创建流对象语句2 ...) {
// 读写数据
} catch (IOException e) {
处理异常的代码...
}
举例 :
try (FileInputStream fis1 = new
FileInputStream("day11_demo\\a.txt") ;
FileInputStream fis2 = new
FileInputStream("day11_demo\\b.txt") )
{
// 读写数据
} catch (IOException e) {
处理异常的代码...
}
public class DemoTest {
public static void main(String[] args){
//创建字节输入流,关联源文件(读)
//创建字节输出流,关联目标文件(写)
try (FileInputStream fis=new
FileInputStream("E:\\1.mp4");
FileOutputStream fos=new
FileOutputStream("java_0725_0708\\1.mp4");){
long begin = System.currentTimeMillis();
//循环:读数据、写数据
int data;
while((data=fis.read())!=-1){
//把读取的数据写入到目标文件中
fos.write(data);
}
long end = System.currentTimeMillis();
System.out.println("共消耗:"+(endbegin));
}catch (IOException e){
e.printStackTrace();
}
}
}
8.读字节数组
public class DemoTest {
public static void main(String[] args) throws IOException {
//创建字节输入流
FileInputStream fis = new
FileInputStream("java_0724_0708\\hello.txt");
//定义字节数组
byte[] buf = new byte[5];
//第1次读取数据
int len = fis.read(buf);
System.out.println("第1次实际读取到的字节数据个数:" + len);
System.out.println("第1次读取到的字节数据:" +
Arrays.toString(buf));
System.out.println("第1次读取的数据:" + new
String(buf, 0, len));//byte[] -> String
//第2次读取数据
len = fis.read(buf);
System.out.println("第2次实际读取到的字节数据个数:" + len);
System.out.println("第2次读取到的字节数据:" + Arrays.toString(buf));拷贝文件优化
System.out.println("第2次读取的数据:" + new String(buf, 0, len));
//第3次读取数据
len = fis.read(buf);
System.out.println("第3次实际读取到的字节数据个数:" + len);
System.out.println("第3次读取到的字节数据:" + Arrays.toString(buf));
System.out.println("第3次读取的数据:" + new String(buf, 0, len));
//String(byte[])
//String(byte[] , 开始索引 , 获取长度)
// 把byte数组中从 开始索引 位置,向后获取指定长度的
字节数据,转换为String
//释放流
fis.close();
}
}
拷贝文件优化
public class DemoTest {
public static void main(String[] args){
//创建字节输入流,关联源文件(读)
//创建字节输出流,关联目标文件(写)
try (FileInputStream fis=new
FileInputStream("E:\\1.mp4");
FileOutputStream fos=new
FileOutputStream("java_0725_0708\\1.mp4");){
long begin = System.currentTimeMillis();
//循环:读数据、写数据
//字节数组
byte[] buf = new byte[1024]; //一次读取1Kint len;
while((len=fis.read(buf))!=-1){
//向目标文件中写入实际读取到的字节数据
fos.write(buf, 0, len);
}
long end = System.currentTimeMillis();
System.out.println("共消耗:"+(endbegin));
}catch (IOException e){
e.printStackTrace();
}
}
}
五.字节缓冲流
public class DemoTest {
public static void main(String[] args){
//创建字节输入流,关联源文件(读)
//创建字节输出流,关联目标文件(写)
String src="E:\\1.mp4";
String dest="java_0725_0708\\1.mp4";
try (BufferedInputStream bis=new
BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bos=new
BufferedOutputStream(new FileOutputStream(dest));){
long begin = System.currentTimeMillis();
//循环:读数据、写数据
//字节数组
byte[] buf = new byte[1024]; //一次读取1K
int len;
while((len=bis.read(buf))!=-1){
//向目标文件中写入实际读取到的字节数据
bos.write(buf, 0, len);
}
long end = System.currentTimeMillis();
System.out.println("共消耗:"+(endbegin));
}catch (IOException e){
e.printStackTrace();
}
}
}
六.Properties集合
1.Properties类的概述
java.util.Properties 继承于Hashtable,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符 串。
2.Properties类的构造方法
public Properties() :创建一个空的属性列表。
3.Properties类存储方法
public class DemoTest {
public static void main(String[] args){
// 创建属性集对象
Properties properties = new Properties();
// 添加键值对元素
properties.setProperty("张三", "北京");
properties.setProperty("李四", "上海");
properties.setProperty("王五", "深圳");
properties.setProperty("赵六", "广州");
// 打印属性集对象
System.out.println(properties);
// 通过键,获取属性值
System.out.println(properties.getProperty("张三"));
System.out.println(properties.getProperty("李四"));
System.out.println(properties.getProperty("王五"));
System.out.println(properties.getProperty("赵六"));
// 遍历属性集,获取所有键的集合
Set<String> strings =
properties.stringPropertyNames();
// 打印键值对
for (String key : strings ) {
System.out.println(key+" --
"+properties.getProperty(key));
}
}
}
4.Properties类与流相关的方法
作用:通过流对象,可以关联到配置文件上,这样就能够加载配置 文件中的数据了。
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建对象
Properties prop=new Properties();
//读取 db.properties属性配置文件
FileInputStream fis=new
FileInputStream("java_0709\\db.properties");
prop.load(fis);
// 关闭流,释放资源
fis.close();
System.out.println(prop);
}
}
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建对象
Properties prop = new Properties();
//存储元素
prop.setProperty("name","zhangsan");
prop.setProperty("age","18");
//把集合中的数据,写入到配置文件
FileOutputStream fos=new
FileOutputStream("java_0709\\info.properties");
prop.store(fos,"lzw");
// 关闭流
fos.close();
}
}
5.ResourceBundle工具类
public class DemoTest {
public static void main(String[] args) throws
IOException {
//获取对象 (作用:读取项目工程的src目录下
的.properties配置文件)
ResourceBundle rb =
ResourceBundle.getBundle("db");//只需要指定配置文件的名字
即可
//获取配置文件中的value值
String username = rb.getString("username");
String password = rb.getString("password");
System.out.println(username);
System.out.println(password);
}
}
七.字符集
读取hello.txt中 "你好" 两个汉字
public class DemoTest {
public static void main(String[] args) throws
IOException {
//字节输入流(读取中文数据)
FileInputStream fis = new
FileInputStream("java_0709/hello.txt");
//读取字节数据
System.out.println((char)fis.read());
System.out.println((char)fis.read());
//释放流
fis.close();
}
}
因为字节流读中文,每次只能读一部分所以出现了乱码。
public class DemoTest {
public static void main(String[] args) throws
IOException {
//字节输入流(读取中文数据)
FileInputStream fis = new
FileInputStream("java_0709/hello.txt");
//读取字节数据
byte[] buf=new byte[3];
fis.read(buf);
ystem.out.println(new String(buf));
fis.read(buf);
System.out.println(new String(buf));
//释放流
fis.close();
}
}
八.字符流
当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中 文字符时,可能不会显示完整的字符,那是因为一个中文字符可能 占用多个字节存储。所以Java提供一些字符流类,以字符为单位读 写数据,专门用于处理文本文件。
1.字符输出流【Writer】
2.FileWriter类
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建流对象
//如果文件不存在,就创建。但是要保证父级路径存在。如
果文件存在就清空。 FileWriter fw=new
FileWriter("java_0709\\hello.txt");
//操作 写出数据
//public void write(int c):写出int类型的整数,
实际写出的是整数在码表上对应的字母
fw.write(97);
fw.write('b');
fw.write("\r\n"); //写出换行符号
//public void write(char[] cbuf)
char[] cs=
{'槟','榔','加','烟','法','力','无','边'};
fw.write(cs);
fw.write("\r\n"); //写出换行符号
//public abstract void write(char[] b, int
off, int len)
fw.write(cs,0,4);
fw.write("\r\n"); //写出换行符号
//public void write(String str)
fw.write("槟榔生吞, 道法乾坤");
fw.write("\r\n"); //写出换行符号
//public void write(String str,int off,int
len)
fw.write("槟榔配酒,永垂不朽",0,4);
//关闭流
fw.close();
}
}
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建流对象 追加写入
FileWriter fw=new
FileWriter("java_0709\\hello.txt",true);
//操作 写出数据
fw.write("槟榔加烟又加酒,阎王在向你招手");
//关闭流
fw.close();
}
}
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建流对象 追加写入
FileWriter fw=new
FileWriter("java_0709\\hello.txt");
//操作 写出数据
fw.write("槟榔加烟又加酒,阎王在向你招手");
/*问题: 以上代码无法把数据写入文件中
原因:因为内置缓冲区的原因,如果不关闭输出流或者不刷新
缓存区,那么无法写出字符到文件中。
解决: 关闭流,或者刷新缓存区
*/
//刷新流
fw.flush();
//关闭流
fw.close();
}
}
3. 字符输入流【Reader】
public class DemoTest {
public static void main(String[] args) throws
IOException {
//创建流对象
FileReader fr=new
FileReader("java_0709\\hello.txt");
//操作 读数据
int read = fr.read();
/*
System.out.println(read);
System.out.println((char)read);
*/
int len;
while( (len=fr.read())!=-1 ){
System.out.println((char)len);
}
//关闭流
fr.close();
}
}
public class DemoTest {
public static void main(String[] args) throws IOException {
//创建流对象
FileReader fr=new
FileReader("java_0709\\hello.txt");
//操作 读数据
char[] cbuf=new char[5];
// int len=fr.read(cbuf);
// System.out.println("第1次读取到的字符数据个数:"+len);
// System.out.println("第1次读取到的字符数据:"+new String(cbuf,0,len));
//
// len=fr.read(cbuf);
// System.out.println("第2次读取到的字符数据个数:"+len);
// System.out.println("第2次读取到的字符数据:"+new String(cbuf,0,len));
//
// len=fr.read(cbuf);
// System.out.println("第3次读取到的字符数据个数:"+len);
// System.out.println("第3次读取到的字符数据:"+new String(cbuf,0,len));
//
// len=fr.read(cbuf);
// System.out.println("第4次读取到的字符数据个数:"+len);
// System.out.println("第4次读取到的字符数据:"+new String(cbuf,0,len));int len;
while((len=fr.read(cbuf))!=-1){
String str = new String(cbuf,0,len);
System.out.println(str);
}
//关闭流
fr.close();
}
}