1.文件路径概述
/**
目标:能够辨别相对路径和绝对路径
讲解:
1. 文件路径的分类
相对路径
绝对路径
2. 绝对路径概述
以盘符开始的路径,在系统中具有唯一性。
比如:
C:/aaa/bbb/a.txt
D:/aaa/bbb/a.txt
3. 相对路径概述
没有以盘符开始,相对于某个位置而言,不具有唯一性。
比如:E:/aaa/zzz a.png
注意:如果在代码中使用的路径是相对路径,则默认相对位置是:当前项目的根目录
比如:aaa.txt ==> 默认在当前项目的根目录查找该文件
比如:aaa/bbb/ccc.png ==> 会在项目根目录下先查找aaa文件夹,然后查找bbb文件夹,最后查找ccc.png
小结:
如何判断文件路径是相对路径还是绝对路径?
判断是否以盘符开始,是则绝对路径,否则是相对路径:相对当前项目根目录
*/
public class Demo01 {
}
## 2.File类构造方法
```java
package com.itheima._02File类构造方法;
import java.io.File;
/**
目标:掌握File类常用的构造方法
讲解:
1. File类的作用
文件和目录路径名的抽象表示形式。
作用:用来操作硬盘上的文件或文件夹,比如获得文件名字,文件大小...
2. File类常用构造方法
public File(String pathname)
根据文件路径字符串创建文件对象
public File(String parent,String child)
根据父路径字符串和子类路径字符串创建文件对象
public File(File parent,String child)
根据父路径文件对象和子类路径字符串创建文件对象
小结:
1. File的作用:用来操作文件或文件夹
2. File类常用的构造方法
File(String path)
File(String parent,String child)
File(File parent,String child)
*/
public class Demo02 {
public static void main(String[] args) {
// 根据文件路径字符串创建文件对象:绝对路径
File f1 = new File("C:/aaa/a.txt");
// 根据文件路径字符串创建文件对象:相对路径
File f2 = new File("a.txt");
System.out.println(f1);
System.out.println(f2);
System.out.println("-------------------");
// 根据父路径字符串和子类路径字符串创建文件对象
// 绝对路径
File f3 = new File("d:/ddd/eee/","a.png");
System.out.println(f3);
// 相对路径:ddd/eee/a.png
File f4 = new File("ddd/eee/","a.png");
File f5 = new File("ddd/eee/a.png");
System.out.println(f4);
System.out.println(f5);
System.out.println("--------------------");
// 根据父路径文件对象和子类路径字符串创建文件对象
File f6 = new File(new File("d:/ddd/eee/"),"a.png");
System.out.println(f6);
}
}
3.File常用方法-获取功能
package com.itheima._03File类常用方法._01获取功能;
import java.io.File;
/**
目标:掌握File类获取文件信息的相关方法
讲解:
1. File类与获取文件信息相关的方法
public String getAbsolutePath() :
获得文件的绝对路径字符串
public String getPath() :
获得文件路径字符串(创建文件对象时指定的路径字符串)
public String getName() :
获得文件或文件夹名称
public long length() :
获得文件的大小,单位:字节
如果文件不存在,则返回值为0
只能获得文件的大小,不能获得文件夹大小
如果文件对象关联的是文件夹则返回值是一个不确定的值
public File getParentFile();
获得父路径文件对象
*/
public class Demo031 {
public static void main(String[] args) {
// 创建文件对象
File f = new File("/Users/pkxing/Documents/aaa.jpg");
// 获得文件绝对路径字符串
// /Users/pkxing/Documents/IDEAProject/119期就业班/a.txt
System.out.println(f.getAbsolutePath());
// 获得文件路径字符串
System.out.println(f.getPath());
// 获得文件或文件夹名称
System.out.println(f.getName()); // a.txt
// 获得文件大小
System.out.println(f.length()); // 736
// 获得父路径文件对象
System.out.println(f.getParentFile());
}
}
4.判断功能
package com.itheima._03File类常用方法._02判断功能;
import java.io.File;
/**
目标:掌握File类与判断功能相关的方法
讲解:
1. File类与判断相关的方法
boolean exists();
判断文件或文件夹是否存在,存在返回true,否则false
boolean isDirectory();
判断文件对象关联的是否是文件夹,是返回true,否则false
如果文件或文件夹不存在在返回false
boolean isFile();
判断文件对象关联的是否是文件,是返回true,否则false
小结:
1. 说出exists()方法作用:判断文件夹或文件是否存在
2. 说出isDirectory()方法作用:判断是否是文件夹
3. 说出isFile()方法作用:判断是否是文件
*/
public class Demo032 {
public static void main(String[] args) {
// 创建文件对象
File f = new File("/Users/pkxing/documents/aaaa");
System.out.println(f.exists()); // true
System.out.println(f.isDirectory()); // true
System.out.println(f.isFile()); // false
}
}
5.创建功能
package com.itheima._03File类常用方法._03创建功能;
import java.io.File;
import java.io.IOException;
/**
目标:能够使用File类提供的方法创建文件和文件夹
讲解:
1. File类与创建文件和文件夹相关的方法
boolean createNewFile()
创建文件,创建成功返回true,否则false
如果文件已经存在,则直接返回false,不会创建了
只能用来创建文件,不能创建文件夹
boolean mkdir() ==> make directory
创建单级文件夹,创建成功返回true,否则false
如果文件夹存在则直接返回false,不会创建了
只能创建文件夹,不能创建文件
boolean mkdirs()
创建单级或多级文件夹,创建成功返回true,否则false
如果文件夹存在则直接返回false,不会创建了
只能创建文件夹,不能创建文件
小结:
1. 创建普通文件的方法
boolean createNewFile()
2. 创建文件夹的方法
boolean mkdirs()
*/
public class Demo033 {
public static void main(String[] args) throws IOException {
// 创建文件对象
File f = new File("ee");
// 创建文件
// System.out.println(f.createNewFile());
// 创建单级文件夹
// System.out.println(f.mkdir());
// 创建多级文件夹
System.out.println(f.mkdirs());
}
}
6.删除功能
package com.itheima._03File类常用方法._04删除功能;
import java.io.File;
/**
目标:能够使用File类提供的方法删除文件或文件夹
讲解:
1. File类与删除文件和文件夹相关的方法
boolean delete()
删除文件或文件夹:删除成功返回true,否则false
如果文件不存在,直接返回false
如果是文件夹则只能删除空文件夹
小结:
1. 删除文件和文件夹使用哪个方法
delete
*/
public class Demo034 {
public static void main(String[] args) {
// 创建文件对象
File f = new File("/Users/pkxing/documents/Java学科");
// 删除文件
System.out.println(f.delete());
}
}
7.遍历功能
package com.itheima._03File类常用方法._05遍历功能;
import java.io.File;
import java.util.stream.Stream;
/**
目标:能够掌握File目录的遍历
讲解:
File类与目录遍历相关的方法
* File[] listFiles()
* 获得当前文件夹下的所有文件
小结:
1. 说出String[] list()的作用:获得当前文件夹下的所有文件,返回字符串数组
2. 说出File[] listFiles()的作用:获得当前文件夹下的所有文件,返回文件数组
*/
public class Demo034 {
public static void main(String[] args) {
// 创建文件对象:关联文件夹
File dir = new File("/Users/pkxing/documents/aaa.jpg");
if (dir.isDirectory()){
// 获得文件夹下的所有文件
File[] files = dir.listFiles();
System.out.println(files);
// 遍历文件数组
for (File file : files) {
System.out.println(file);
}
// 遍历输出
// Consumer接口抽象方法:void accept(T t)
/*Stream.of(files).forEach(file->{
System.out.println(file.getName());
});*/
}
}
}
8.File类静态成员变量
package com.itheima._04File类静态成员变量;
import java.io.File;
import java.io.FileReader;
/**
目标:了解File类两个静态成员变量
讲解:
1. File类两个常见的静态成员变量
static String pathSeparator
* 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
* 不同的操作系统有不同路径分隔符
* MAC或Linux是 :
* Windows是 ;
static String separator
* 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
* 不同的操作系统有不同名称分隔符
* MAC或Linux是 /
* Windows是 \
小结:
1. pathSeparator的作用:路径分隔符
2. separator的作用:名称分隔符
*/
public class Demo04 {
public static void main(String[] args)throws Exception {
System.out.println(File.pathSeparator);
System.out.println(File.separator);
FileReader fr = new FileReader("day09_课堂代码/a.txt");
System.out.println(fr.read());
fr.close();
}
}
9.递归概述
package com.itheima._05递归概述;
/**
目标:能够理解递归的概念
讲解:
1. 什么是递归
方法自身调用自身则称为递归
2. 递归的分类
间接递归:A方法调用B方法,B方法调用C方法,C方法调用A方法
直接递归:A方法调用A方法
3. 递归的注意事项
* 递归要有出口:结束递归的条件
* 递归次数不要太多
小结:
1. 说出什么是递归
方法自身调用自身
2. 说出递归的两个注意事项
要有结束递归的条件
递归次数不能太多
*/
// 间接递归演示 : java.lang.StackOverflowError 栈内存溢出错误
public class Demo05 {
private static int index = 0;
// A方法调用B方法,B方法调用C方法,C方法调用A方法
public static void main(String[] args) {
System.out.println("main..." + index++); // 0
testA();
System.out.println("main..." + index++);
}
public static void testA(){
if (index >= 4) return;
System.out.println("testA..." + index++); // 1
testB();
System.out.println("testA..." + index++);
}
public static void testB(){
System.out.println("testB..." + index++); // 2
testC();
System.out.println("testB..." + index++);
}
public static void testC(){
System.out.println("testC..." + index++); // 3
testA();
System.out.println("testC..." + index++);
}
}
package com.itheima._05递归概述;
// 直接递归演示 : java.lang.StackOverflowError 栈内存溢出错误
public class Demo06 {
private static int index = 0;
public static void main(String[] args) {
System.out.println("main..." + index++);
testA();
System.out.println("main..." + index++);
}
public static void testA(){
if (index >= 4) return;
System.out.println("testA..." + index++);
testA();
System.out.println("testA..." + index++);
}
}
10.递归练习
package com.itheima._06递归练习;
/**
需求:使用递归求1到n的和
讲解:
1. 使用递归实现功能的步骤:
1. 定义方法:确定返回值和参数列表
2. 找递归的规律
3. 找递归的出口
2. 分析查找递归规律
n = 5;
sum(5) = 1 + 2 + 3 + 4 + 5 = sum(4) + 5;
n = 4;
sum(4) = 1 + 2 + 3 + 4 = sum(3) + 4;
n = 3;
sum(3) = 1 + 2 + 3 = sum(2) + 3;
n = 2;
sum(2) = 1 + 2 = sum(1) + 2
n = 1;
sum(1) = 1;
n > 1:
sum(n) = sum(n-1) + n;
3. 画图分析递归执行流程
*/
public class Demo061 {
public static void main(String[] args) {
System.out.println(sum(5));
System.out.println(sum(1));
}
// 1. 定义方法:确定返回值和参数列表
public static int sum(int n){
if (n == 1) return 1;
return sum(n-1) + n;
}
}
package com.itheima._06递归练习;
/**
需求:使用递归求n!
n! = 1 * 2 * 3 *...n
讲解:
1. 使用递归实现功能的步骤:
1. 定义方法:确定返回值和参数列表
2. 找递归的规律
3. 找递归的出口
2. 分析查找递归规律
*/
public class Demo062 {
public static void main(String[] args) {
System.out.println(jc(5)); // 120
}
// 1. 定义方法:确定返回值和参数列表
public static int jc(int n){
if (n == 1) return 1;
return jc(n-1) * n;
}
}
package com.itheima._06递归练习;
import java.io.File;
/**
需求:搜索c:\abc目录中的.java文件。
讲解:
1. 使用递归实现功能的步骤:
1. 定义方法:确定返回值和参数列表
2. 找递归的规律
3. 找递归的出口
2. 实现步骤分析
1. 获得目标文件夹下的所有文件:得到文件数组
2. 遍历文件数组获得每个文件对象
3. 判断是否是文件,判断是java文件
4. 如果是文件夹则递归调用当前方法
*/
public class Demo063 {
public static void main(String[] args) {
// 创建文件对象:关联目标文件夹
File dir = new File("/Users/pkxing/documents/119期就业班");
printJavaFile(dir);
}
// 1. 定义方法:确定返回值和参数列表
/**
* 将指定文件夹下的所有java文件打印输出
* @param dir 目标文件夹
*/
public static void printJavaFile(File dir){
// 1. 获得目标文件夹下的所有文件:得到文件数组
File[] files = dir.listFiles();
// 2. 遍历文件数组获得每个文件对象
for (File file : files) {
// 3. 判断是否是文件
if (file.isFile()){
// 判断是java文件
if (file.getName().endsWith(".java")){
System.out.println(file);
}
} else {
// 4. 如果是文件夹则递归调用当前方法
printJavaFile(file);
}
}
}
}
11.IO流简介
package com.itheima._07IO流简介;
/**
目标:能够说出IO流的作用
讲解:
1. 为什么要学习IO流
目前数据使用集合和数组,集合或数组保存在内存中的,内存是临时性存储,
一旦电脑断电或程序重新启动,数据就没有了。
如果需要保证数据永久存储,就希望将数据存储到硬盘的文件中。
通过IO流我们就可以将数据保存到文件中,也可以从文件中读取数据到程序中。
2. IO流的作用
保存数据:将内存中的数据保存硬盘上的文件中
读取数据:将文件中的数据读取到程序中
3. 什么是IO
Input:输入: 文件到内存中
Output:输出:内存到文件中
小结:
IO流的作用是什么
保存数据到文件中
读取数据到内存中
*/
public class Demo07 {
}
12.IO流分类
package com.itheima._08IO流分类;
/**
目标:能够说出IO流的分类
讲解:
1. IO流的分类
按照流向分类
输入流:将文件中数据读取到内存中
输出流:将内存中数据保存文件中
按照数据类型分类
字节流:以字节为单位进行读写数据
字符流:以字符为单位进行读写数据
字节输入流(InputStream):以字节为单位进行读取数据
字节输出流(OutputStream):以字节为单位进行输出数据
字符输入流(Reader):以字符为单位进行读取数据
字符输出流(Writer):以字符为单位进行输出数据
2. 如何判断流是字符流还是字节流
* 根据类的名称判断,如果是以Stream结尾,则就是字节流,否则都是字符流。
小结:
1. IO流按流向分为哪2类?
输入流
输出流
2. IO流按数据类型分为哪2类?
字节流
字符流
*/
public class Demo08 {
}
13.数据本质
package com.itheima._09数据本质;
/**
目标:能够说出数据的本质是什么
讲解:
1. 科普计算机小常识
* 计算机只能识别0和1
* 任何数据存储在内存中都是0和1(二进制数据)
* 任何数据在传输过程中都是二进制数据
01010110010 ==> 机器语言
mov # ==> 汇编语言
java/c/c++ ==> 高级语言
2. 编码和解码概述
编码:将字符转换为二进制数据的过程
比如:a ==> 码表 ==> 97 ==> 01010110
解码:将二进制数据转换为字符的过程
比如:01010110 ==> 97 ==> 码表 ==> a
小结:
1. 数据的本质是什么:二进制数据
*/
public class Demo09 {
}
14.字节输出流
package com.itheima._10字节输出流;
/**
目标:掌握OutputStream类的作用和方法
讲解:
1. OutputStream类概述
Output:输出
Stream:流
是字节输出流:以字节为单位输出数据
是一个抽象类,不能直接创建对象,只能创建子类对象
是所有字节输出流的父类
2. OutputStream类常用方法
void close() 关闭流释放资源
void write(byte[] b)
输出一个字节数组内容到文件中
void write(byte[] b, int off, int len)
输出字节输出的一部分内容到文件中
void write(int b)
输出一个字节到文件中
3. OutputStream类常用子类
FileOutputStream
小结:
1.OutputStream类的作用:以字节为单位输出数据到文件中
2.OutputStream类用来输出数据的方法
write
*/
public class Demo101 {
}
package com.itheima._10字节输出流;
import java.io.File;
import java.io.FileOutputStream;
/**
目标:使用FileOutputStream类向文件输出字节
讲解:
1. FileOutputStream类概述
继承OutputStream,字节输出流:以字节为单位输出数据到文件中
2. FileOutputStream类常用构造方法
FileOutputStream(String filename)
* 根据文件路径字符串创建字节输出流对象
FileOutputStream(File file)
* 根据文件对象创建字节输出流对象
* 如果目标文件不存在,则会自动创建
3. FileOutputStream类使用步骤
1. 创建字节输出流并关联目标文件
2. 调用字节输出流对象的write方法输出数据
3. 调用字节输出流对象的close方法关闭流释放资源
小结:
使用FileOutputStream类向文件输出字节的步骤
1. 创建流关联目标文件
2. 调用write方法输出数据
3. 调用close方法关闭流释放资源
*/
public class Demo102 {
public static void main(String[] args) throws Exception {
// 1. 创建字节输出流并关联目标文件
FileOutputStream fos = new FileOutputStream(new File("a.txt"));
// 2. 调用字节输出流对象的write方法输出数据
fos.write(97); // a
fos.write(98); // b
// 300 ==> 00000000 00000000 00000001 00101100
// 44 ==> 00101100
fos.write(300); // ,
fos.write(44); // ,
// 3. 调用字节输出流对象的close方法关闭流释放资源
fos.close();
}
}
package com.itheima._10字节输出流;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
目标:使用FileOutputStream类向文件输出字节数组
讲解:
1. OutputStream类与写出字节数组相关的方法
void write(byte[] buf) 输出整个字节数组的内容
void write(byte[] buf,int off,int length) 输出字节数组的部分内容
小结:
使用FileOutputStream类向文件输出字节数组的步骤
1. 创建流关联目标文件
2. 调用write方法传递字节数组
3. 调用close方法关闭流释放资源
*/
public class Demo103 {
public static void main(String[] args) throws Exception{
// 1. 创建流关联目标文件
OutputStream fos = new FileOutputStream("b.txt");
// 2. 调用write方法输出字节数组
// 2.1 定义字节数组
byte[] buf = {97,98,99,100,101};
// 2.2 输出整个字节数组内容
fos.write(buf); // abcde
// 2.3 输出字节数组的部分内容
fos.write(buf, 1, 3); // bcd
// 2.3 定义字符串
String str = "你好师姐";
// 将字符串转换为字节数组
byte[] bytes = str.getBytes();
fos.write(bytes);
// 3. 调用close方法关闭流释放资源
fos.close();
}
}
package com.itheima._10字节输出流;
import java.io.FileOutputStream;
/**
目标: 使用FileOutputStream实现追加写出数据
讲解:
1. FileOutputStream类与追加写出数据相关的构造方法
FileOutputStream(String file,boolean append)
FileOutputStream(File file,boolean append)
* append:true 追加输出,不会清空目标文件的内容
* append:false 不追加输出,会清空目标文件的内容,再输出数据,默认值
2. 如何实现换行输出
输出一个换行符:
\r 回车符
\n 换行符
\r\n 换行符(推荐使用)
小结:
1. 如何追加输出数据
在创建流的构造方法中通过第二参数指定true即可
2. 如何实现换行输出数据
输出一个换行符:\r\n
*/
public class Demo104 {
public static void main(String[] args)throws Exception {
// 创建流关联目标文件
FileOutputStream fos = new FileOutputStream("b.txt", true);
// 输出数据
fos.write("你好\r\n".getBytes());
// 输出一个换行符
// fos.write("\r\n".getBytes());
// 关闭流释放资源
fos.close();
}
}
package com.itheima._10字节输出流;
import java.io.File;
import java.io.FileOutputStream;
/**
目标:理解IO流使用的注意事项
注意事项小结
1. 创建流关联目标文件必须是普通文件不能关联文件夹
* java.io.FileNotFoundException: /Users/pkxing/documents/aaa (Is a directory)
2. 流一旦关闭就不能再使用了
*/
public class Demo105 {
public static void main(String[] args) throws Exception {
// 创建流关联文件
FileOutputStream fos = new FileOutputStream("/Users/pkxing/documents/aaa.txt");
// 输出数据
fos.write("aaa".getBytes());
// 关闭流
fos.close();
// 输出数据
// Stream Closed:流已经关闭了
fos.write("bbb".getBytes());
}
}
15.字节输入流
package com.itheima._11字节输入流;
/**
目标:掌握InputStream类的作用和方法
讲解:
1. InputStream类概述
Input:输入
Stream:字节流
是一个字节输入流:以字节为单位从文件中读取数据到内存中
是一个抽象流,不能创建对象,只能创建子类对象
是所有字节输入流的父类
2. InputStream类常用子类
FileInputStream
3. InputStream类常用方法
void close() 关闭流释放资源
int read()
从流关联的目标文件中读取一个字节
返回实际读取到的字节数
如果读取到文件末尾,返回值为-1
int read(byte[] b)
从流关联的目标文件中读取一个字节数组
返回实际读取到字节个数
如果读取到文件末尾,返回值为-1
int read(byte[] b, int off, int len)
从流关联的目标文件中读取一个字节数组
返回实际读取到字节个数
如果读取到文件末尾,返回值为-1
小结:
1.InputStream类的作用:以字节为单位读取数据
2.InputStream类用来读取数据的方法
read
*/
public class Demo111 {
}
package com.itheima._11字节输入流;
import java.io.FileInputStream;
/**
目标:使用FileInputStream类从文件中读取一个字节数据
讲解:
1. FileInputStream类概述
继承InputStream:以字节为单位读取数据
2. FileInputStream类构造方法
FileInputStream(String pathname)
FileInputStream(File file)
根据文件路径字符串或文件对象创建字节输入流对象
如果目标文件不存在则直接抛出异常
3. FileInputStream类读取数据使用步骤
1. 创建字节输入流关联目标文件
2. 调用字节输入流的read方法:从文件中读取数据
3. 调用字节输入流的close方法:关闭流释放资源
小结:
使用字节输入流从文件中读取数据的步骤:
1. 创建字节输入流关联目标文件
2. 调用字节输入流的read方法:从文件中读取数据
3. 调用字节输入流的close方法:关闭流释放资源
*/
public class Demo112 {
public static void main(String[] args) throws Exception {
// 1. 创建字节输入流关联目标文件
FileInputStream fis = new FileInputStream("a.txt");
// 2. 调用字节输入流的read方法:从文件中读取数据
/* int len = fis.read(); // 97
System.out.println("len = " + (char)len); // a
len = fis.read();
System.out.println("len = " + (char)len); // b
len = fis.read();
System.out.println("len = " + (char)len); // c
len = fis.read();
System.out.println("len = " + len); // -1*/
// 使用循环改进
// 定义整型变量:接收实际读取到的字节数
int len = -1;
// 使用循环读取数据
// abc
while((len = fis.read()) != -1){
System.out.print((char) len);
}
// 3. 调用字节输入流的close方法:关闭流释放资源
fis.close();
}
}
package com.itheima._11字节输入流;
import java.io.FileInputStream;
/**
目标:使用FileInputStream类从文件中读取字节数组
讲解:
1. InputStream类与读取字节数组相关的方法
int read(byte[] buf)
* 从流关联的目标文件中读取数据到字节数组中
* 返回实际读取到的字节个数
* 如果读取到文件末尾-1
2. 字节输入流读取字节数组的步骤
1. 创建流关联目标文件
2. 创建字节数组:用来存储读取到的数据
3. 调用字节输入流的read方法读取数据到字节数组中
4. 关闭流释放资源
小结:
1. 使用FileInputStream从文件中读取字节数组的步骤
1. 创建流关联目标文件
2. 创建字节数组:用来存储读取到的数据
3. 调用字节输入流的read方法读取数据到字节数组中
4. 关闭流释放资源
*/
public class Demo113 {
public static void main(String[] args) throws Exception{
// 1. 创建流关联目标文件
FileInputStream fis = new FileInputStream("a.txt");
// 2. 创建字节数组:用来存储读取到的数据
byte[] buf = new byte[1024];
// 1025 1024
// 定义变量接收实际读取到的字节个数
int len = -1;
while ((len = fis.read(buf)) != -1){
System.out.print(new String(buf,0,len)); // 1024
}
// 4. 关闭流释放资源
fis.close();
}
// 没有使用循环
public static void test01() throws Exception{
// 1. 创建流关联目标文件
FileInputStream fis = new FileInputStream("a.txt");
// 2. 创建字节数组:用来存储读取到的数据
byte[] buf = new byte[2];
// 3. 调用字节输入流的read方法读取数据到字节数组中
int len = fis.read(buf);
System.out.println("len = " + len); // 2
System.out.println("buf = " + new String(buf)); // ab
// 再读取一次
len = fis.read(buf);
System.out.println("len = " + len); // 2
System.out.println("buf = " + new String(buf)); // cd
// 再读取一次
len = fis.read(buf);
System.out.println("len = " + len); // 1
System.out.println("buf = " + new String(buf)); // ed
// 再读取一次
len = fis.read(buf);
System.out.println("len = " + len); // -1
System.out.println("buf = " + new String(buf)); // ed
// 4. 关闭流释放资源
fis.close();
}
}
package com.itheima._11字节输入流;
/**
目标:能够理解读取数据read(byte[] b)方法的原理
讲解:
1. 画图分析read(byte[] b)方法读取数据的原理
小结:
read(byte[] b)方法的原理:
每次从流关联的目标文件中读取数据到指定的字节数组中,
每次都是将读取到数据从数组的索引0位置开始存储
*/
public class Demo114 {
}
16.字节流复制文件
package com.itheima._12字节流复制文件;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
目标:能够使用字节流实现文件的复制:将"d:/aaa/a.png" 复制到 "e:/bbb/a.png"
讲解:
1. 画图分析文件复制流程
2. 文件复制实现步骤
1. 创建字节输入流关联源文件:必须要存在
2. 创建字节输出流关联目标文件:可以没有
3. 使用字节输入流循环读取源文件数据
4. 使用字节输出流将数据输出到目标文件中
5. 关闭流释放资源
小结:
1. 字节流复制文件的步骤
1. 创建字节输入流关联源文件:必须要存在
2. 创建字节输出流关联目标文件:可以没有
3. 使用字节输入流循环读取源文件数据
4. 使用字节输出流将数据输出到目标文件中
5. 关闭流释放资源
*/
public class Demo12 {
public static void main(String[] args) throws Exception {
// 1. 创建字节输入流关联源文件:必须要存在
FileInputStream fis = new FileInputStream("/Users/pkxing/documents/aaa.mp4");
// 2. 创建字节输出流关联目标文件:可以没有
FileOutputStream fos = new FileOutputStream("/Users/pkxing/documents/bbb.mp4");
// 3. 使用字节输入流循环读取源文件数据
// 创建字节数组:用来存储读取的数据
byte[] buf = new byte[1024];
// 定义整型变量:接收实际读取到的字节个数
int len = -1;
while ((len = fis.read(buf)) != -1){
// 4. 使用字节输出流将数据输出到目标文件中
fos.write(buf,0,len);
}
// 5. 关闭流释放资源
fis.close();
fos.close();
}
}
17.字节流操作字符问题
package com.itheima._13字节流操作字符问题;
import java.io.FileInputStream;
/**
目标:了解字节流不方便读取字符数据
小结:
字节流读取字符很不方便。容易出现乱码问题
*/
public class Demo13 {
public static void main(String[] args)throws Exception{
// 创建字节输入流
FileInputStream fis = new FileInputStream("a.txt");
int len = -1;
// 读取数据
while((len = fis.read()) != -1){
// a你好
// 你 : -100 -123 111
// 汉字:GBK码表: 一个汉字占两个字节
// 汉字:UTF8码表: 一个汉字占三个字节
System.out.print((char)len); // a
}
// 关闭流释放资源
fis.close();
}
}
以下解决
18.字符输入流
package com.itheima._14字符输入流;
/**
目标:掌握Reader类的作用和方法
讲解:
1. Reader类概述
是所有字符输入流父类,是一个抽象类
以字符为单位读取数据
2. Reader类常用子类
FileReader
3. Reader类常用方法
void close() 关闭流释放资源
int read()
从流关联的目标文件中读取一个字符
返回实际读取到的字符数
如果读取到文件末尾,返回值-1
int read(char[] cbuf)
从流关联的目标文件中读取数据到指定的字符数组
返回实际读取到字符个数
如果读取到文件末尾,返回值-1
int read(char[] cbuf, int off, int len)
从流关联的目标文件中读取数据到指定的字符数组
返回实际读取到字符个数
如果读取到文件末尾,返回值-1
小结:
Reader类作用:以字符为单位读取数据
读取数据的方法:read
*/
public class Demo141 {
}
package com.itheima._14字符输入流;
import java.io.FileReader;
/**
目标:使用字符输入流FileReader读取文本数据
讲解:
1. FileReader类概述
继承Reader:字符输入流,以字符为单位读取数据
2. FileReader类常用构造方法
FileReader(String path)
FileReader(File file)
根据文件路径字符串或文件对象创建字符输入流
如果目标文件不存在,则抛出异常
3. 字符输入流的使用步骤
1. 创建流关联目标文件
2. 调用read方法读取数据
3. 调用close方法关闭流释放资源
小结:
FileReader读取数据的步骤
1. 创建流关联目标文件
2. 调用read方法读取数据
3. 调用close方法关闭流释放资源
*/
public class Demo142 {
public static void main(String[] args) throws Exception{
// 一次读取一个字符
// readChar();
// 一次读取一个字符数组
readCharArray();
}
/*
一次读取一个字符数组
*/
private static void readCharArray()throws Exception {
// 1. 创建流关联目标文件
FileReader fr = new FileReader("a.txt");
// 2. 读取一个字符数组
/*// a你好
char[] buf = new char[2];
int len = fr.read(buf); // 好你
System.out.println("len = " + len); // 2
System.out.println("buf = " + new String(buf)); // a你
len = fr.read(buf); // 好
System.out.println("len = " + len); // 1
System.out.println("buf = " + new String(buf)); // 好你
len = fr.read(buf);
System.out.println("len = " + len); // -1
System.out.println("buf = " + new String(buf)); // 好你*/
// 2. 创建字符数组:用来存储读取到的数据
char[] buf = new char[1024];
// 定义变量接收实际读取到的字符个数
int len = -1;
while ((len = fr.read(buf)) != -1){
System.out.print(new String(buf,0,len));
}
// 3. 调用close方法关闭流释放资源
fr.close();
}
/*
一次读取一个字符
*/
private static void readChar() throws Exception{
// 1. 创建流关联目标文件
FileReader fr = new FileReader("a.txt");
// 2. 调用read方法读取数据
// a你
/*System.out.println((char) fr.read()); // a
System.out.println((char) fr.read()); // 你
System.out.println(fr.read()); // -1*/
// 定义变量:接收读取到的字符数
int len = -1;
// 使用循环读取
while((len = fr.read()) != -1){
System.out.print((char) len);
}
// 3. 调用close方法关闭流释放资源
fr.close();
}
}
19.字符输出流
package com.itheima._15字符输出流;
/**
目标:掌握Writer类的作用和方法
讲解:
1. Writer类概述
是一个抽象类,不能直接创建对象,只能创建子类对象
是所有字符输出流的父类:以字符为单位输出数据
2. Writer类常用子类
FileWriter
3. Writer类常用方法
void close();
void write(char[] cbuf)
输出一个字符数组
void write(char[] cbuf, int off, int len)
输出字符数组的一部分
void write(int c)
输出一个字符
void write(String str)
输出一个字符串
void write(String str, int off, int len)
输出字符串的一部分
小结:
Writer类的作用:以字符为单位输出数据到文件中
输出数据的方法:write
*/
public class Demo151 {
}
package com.itheima._15字符输出流;
import java.io.FileWriter;
/**
目标:能够使用字符输出流FileWriter往文件中输出字符数据
讲解:
1. FileWriter类概述
继承Writer,字符输出流:以字符为单位输出数据
2. FileWriter类常用构造方法
FileWriter(String path)
FileWriter(String path,boolean append)
FileWriter(File file)
FileWriter(File file,boolean append)
根据文件路径字符串或文件对象创建字符输出流
append:true 追加输出,false,不追加
3. 字符输出流使用步骤
1. 创建流关联目标文件
2. 调用write方法输出数据
3. 调用close方法关闭流释放资源
小结:
FileWriter 输出数据的步骤
1. 创建流关联目标文件
2. 调用write方法输出数据
3. 调用close方法关闭流释放资源
*/
public class Demo152 {
public static void main(String[] args) throws Exception{
// 输出字符数组
// writeCharArray();
// 输出字符串
writeString();
}
// 输出字符串
private static void writeString() throws Exception {
// 1. 创建流关联目标文件
FileWriter fw = new FileWriter("d.txt",true);
String str = "你好世界te(str);";
// 2. 调用write方法输出数据
// 输出整个字符串
fw.write(str);
// 输出字符串部分内容
fw.write(str, 1, 2);
fw.write("\r\n");
// 3. 调用close方法关闭流释放资源
fw.close();
}
/**
* 输出字符数组
*/
private static void writeCharArray() throws Exception{
// 1. 创建流关联目标文件
FileWriter fw = new FileWriter("d.txt");
char[] buf = {'你','好','师','妹'};
// 2. 调用write方法输出数据
// 输出整个字符数组
fw.write(buf);
// 输出字符数组部分内容
fw.write(buf, 1, 2);
// 3. 调用close方法关闭流释放资源
fw.close();
}
}
20.close和flush方法区别
package com.itheima._16close和flush方法区别;
import java.io.FileWriter;
/**
目标:能够阐述flush方法和close方法的区别(面试题)
讲解:
1. flush方法和close方法的区别
flush方法:用来刷新缓冲区,流还可以继续使用
close方法:关闭流释放资源,流一旦就不能使用,内部会调动flush方法。
2. 演示flush方法和close方法
小结:
1. flush和close方法的区别
flush方法:用来刷新缓冲区,流还可以继续使用
close方法:关闭流释放资源,流一旦就不能使用,内部会调动flush方法。
*/
public class Demo161 {
public static void main(String[] args) throws Exception{
// 创建字符输出流
FileWriter fw = new FileWriter("e.txt");
// 输出数据
fw.write("你好");
// 刷新缓冲区:将数组的内容输出目标文件中
fw.flush();
fw.write("世界");
// 关闭流释放资源
fw.close();
}
}
21.总结
package com.itheima._17教学目标小结;
import java.util.concurrent.locks.ReentrantLock;
/**
教学目标
- 能够说出File对象的创建方式
File(String path)
File(String parent,String child)
File(File parent,String child)
- 能够使用File类常用方法
getName
getAbsolutePath
getPath
length
getParentFile
exists
isDirectory
isFile
createNewFile
mkdirs
mkdir
delete
listFiles
- 能够辨别相对路径和绝对路径
绝对路径:以盘符开始
相对路径:没有以盘符开始,相当于当前项目根目录
- 能够遍历文件夹
1. File dir = new File("目标文件夹");
2. File[] files = dir.listFiles();
3. for(File f:files) { }
- 能够解释递归的含义:方法A调用方法A
- 能够使用递归的方式计算5的阶乘:参考代码
- 能够说出使用递归会内存溢出隐患的原因
因为方法一直进栈导致栈内存不够
- 能够说出IO流的分类和功能
字节输入流
字节输出流
字符输入流
字符输出流
保存数据和读取数据
- 能够使用字节输出流写出数据到文件
1. 创建流关联目标文件
2. 调用write方法输出数据
3. 调用close方法关闭流
- 能够使用字节输入流读取数据到程序
1. 创建流关联目标文件
2. 调用read方法读取数据
3. 调用close方法关闭流
- 能够理解读取数据read(byte[])方法的原理
将读取到文件数据存储到字节输出中
每次从索引0位置开始存储读取到数据
- 能够使用字节流完成文件的复制
参考代码
- 能够使用FileWriter写数据到文件
1. 创建流关联目标文件
2. 调用write方法输出数据
3. 调用close方法关闭流
- 能够说出FileWriter中关闭和刷新方法的区别
flush方法:用来刷新缓冲区,流还可以继续使用
close方法:关闭流释放资源,流一旦就不能使用,内部会调动flush方法
- 能够使用FileWriter写数据的5个方法
write(int ch)
write(char[] buf)
write(char[] buf,int off,int len)
write(String str)
write(String str,int off,int len)
- 能够使用FileWriter写数据实现换行和追加写
追加:指定构造方法第二个参数为true
换行:输出一个\r\n
- 能够使用FileReader读数据
1. 创建流关联目标文件
2. 调用read方法读取数据
3. 调用close方法关闭流
- 能够使用FileReader读数据一次一个字符数组
学生反馈
- Java中线程池运行原理, 通过集合、映射或数组方式获取流, 这俩方面有点迷
知识回顾
1. 如何实现线程安全
同步代码块:synchronized(锁对象){ 操作共享资源的代码 }
同步方法:修饰符 synchronized 返回值类型 方法名(){ 操作共享资源的代码 }
Lock接口:常用子类:ReentrantLock
void lock() 获取锁
void unlock() 释放锁
2. 如何提交任务到线程池
* 创建线程池对象并指定线程数量
* ExecutorService tp = Executors.newFixedThreadPool(3);
* 提交Runnable任务:创建Runnable接口实现类对象重写run方法:封装任务代码
* 提交Callable任务:创建Callable接口实现类对象重写call方法:封装任务代码
* tp.submit(Runnable r 或 Callable c);
* 销毁线程池:tp.shutdown();
3. Lambda表达式格式和使用条件
* 作用:简化匿名内部类的语法
* 使用前提条件:接口类型且有且只有一个抽象方法
* 标准格式:(参数列表)->{ 方法体 }
* 参数列表:就是接口抽象方法的参数列表
* 方法体:就是接口抽象方法的方法体:对抽象方法的实现
* 省略格式:变量名 -> 一条语句
* 只有一个参数:可以省略小括号
* 只有一条语句:可以大括号
4. Stream流常用方法
* 作用:对集合或数组中元素进行加工处理。
* 如何获得Stream流对象
* Stream stream = 单列集合对象.stream();
* Stream stream = Stream.of(数组)
* 常用方法:
* forEach:遍历流中元素并传递消费者
* 参数:Consumer接口实现类对象,Consumer是一个函数式接口,抽象方法:void accept(T t);
* filter:对流元素进行过滤,通过Predicate接口封装过滤条件
* Predicate是一个函数式接口,抽象方法:boolean test(T t)
* limit: 获取前n个
* skip:跳过前n个
* map: 将流的元素从一种数据类型转换为另一中数据类型
* Function是一个函数式接口,抽象方法:R apply(T t)
* count:获得流元素个数
* concat:流合并
* collect:收集流中元素(数组或集合中)
* stream.collect(Collectors.toList())
* stream.collect(Collectors.toSet())
* stream.toArray()
* stream.toArray(String[]::new)
今天内容
1. File类
常用方法
2. 递归
概念和注意事项
3. IO流(4个类)
* 实现数据的保存和读取操作
* 知道如何选择
重点:
1. File常用方法
2. 能够使用IO读写数据:一次读取一个数组,一个输出一个数组
*/
public class Demo17 {
}