一、文件
(1)概述
(2)构造器创建File对象
构造器 | 说明 |
---|---|
File(File parent,String filed) | 获取已有的文件对象中的某一文件对象 |
File(String pathname) | 通过文件路径名查找文件对象 |
File(String parent,String filed) | 根据父路径查找文件对象后,通过子文件名查找文件对象 |
File(String Uri) | 通过网络路径查找文件对象 |
使用示例
public class FileDemo {
public static void main(String[] args) {
/*创建File对象的方式(绝对路径)
* 1、使用分隔符为 \\ 形式的地址
* 2、使用分隔符为 / 形式的地址
* 3、File.separator 自动获取系统分隔符,跨平台时推荐(mac、linux、windows等系统)
* */
/*绝对路径创建*/
File file = new File("E:\\360MoveData\\Users\\zain\\Desktop\\text.txt");
File file1 = new File("E:/360MoveData/Users/zain/Desktop/text.txt");
File file2 = new File("E:"+File.separator+"360MoveData"+File.separator+"Users"+File.separator+"zain"+File.separator+"Desktop"+File.separator+"text.txt");
/*返回字节数*/
System.out.println(file.length());
// file.delete(); //删除磁盘中的文件
/*相对路径创建:主要定位于模块中的文件*/
File file3 = new File("JavaSEpro/src/demo.txt");
System.out.println(file3.length());
}
}
(3)常用API
获取类、判断类API
方法 | 说明 |
---|---|
boolean isDirectory() | 判断File是否为文件夹 |
boolean isFile() | 判断File是否为文件 |
boolean exists() | 判断File是否存在 |
String getAbsolutePath() | 获取File对象的绝对路径 |
String getPath() | 获取自定义的路径 |
String getName() | 获取File对象的文件名 |
long lastModified() | 返回文件最后修改的时间戳 |
创建类、删除类API
方法 | 说明 |
---|---|
boolean createNewFile() | 创建新的空文件夹 |
boolean mkdir() | 只创建一级文件夹 |
boolean mkdirs() | 创建多级文件夹 |
boolean delete() | 删除文件或空文件夹 |
注意:多级指的是 a/b/c/d 这样类型的多级文件夹
遍历文件夹API
方法 | 说明 |
---|---|
String[] list() | 获取当前目录下的一级文件名称 |
File[] listFiles() | 获取当前目录下的所有的一级文件对象 |
遍历文件夹示例
public class FileDemo {
public static void main(String[] args) {
//1、定位目录
File dir = new File("D:\\JavaBase\\JavaSEpro");
//2.1、获取目录下的一级文件名称
String[] names = dir.list();
System.out.println(Arrays.toString(names));
/*2.2、获取目录下的一级文件对象*/
File[] files = dir.listFiles();
}
}
/*打印结果*/
[.idea, JavaSEpro.iml, lib, log, out, src]
listFiles 方法注意事项
二、递归
(1)概念: 方法直接调用自己或间接调用自己的形式称为方法递归(recursion),作为一种算法在程序设计语言中广泛使用。
(2)形式:
(3)方法递归存在的问题: 递归若没有控制终止,会出现递归死循环,导致栈内存溢出现象。
(4)递归解决问题的思路: 复杂问题拆解为相似的规模较小的问题求解。
(5)递归的步骤
(6)递归的示例
/**
需求:使用递归,计算1-n的阶乘
通用公式:f(n) = f(n-1)*n;
跳出点:f(1)
递归方向,自上而下
*/
public class FileDemo {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
System.out.println(factorial(i));
}
}
public static int factorial(int num){
if (num == 1) return 1;
return factorial(num - 1) * num;
}
}
/*打印结果*/
1
2
6
24
120
(7)常见案例(规律化递归)
(a)计算1-n的和
/**
通用公式:f(n)=f(n-1) + n;
终结点:f(1)
递归方向:自上而下
*/
public static int sum(int num) {
if (num == 1) return 1;
return sum(num-1) + num;
}
(2)猴子吃桃
/**
问题:第一天摘下n个桃子,当即吃了一半多一个。
第二天又吃了前天剩余数量的一半多一个。
以后每天都是吃前天剩余数量的一半多一个。(递归条件)
等到第10天的时候发现桃子只有1个了。(终点)
现求第一天摘了几个桃子。
递归分析: 当天的个数 = 前天个数/2 - 1; <=> f(n+1) = 2f(n) + 2;
*/
public static int calMount(int day){
if (day == 10) return 1;
return 2*calMount(day+1) + 2;
}
(8)常见案例(非规律化递归)
(a)查找文件
查找的文件是detail下的Test.java文件,以下是目录图
/**
* 文件搜索
* 需求:文件搜索,从项目中,搜索某个文件名称并输出绝对路径
* 分析:
* 1、定位项目位置
* 2、遍历文件,判断是否为文件
* 3、若是文件,则按照规则判定
* 4、若是文件夹,递归文件夹的内容
*/
public static void main(String[] args) {
searchFile(new File("D:\\JavaBase\\JavaSEpro\\src"));
}
public static void searchFile(File dir) {
File[] files = dir.listFiles();
for (File file : files != null ? files : new File[0]) {
if (file.isFile()){
if (file.getName().equals("Test.java")){
System.out.println(file.getAbsolutePath());
return;
}
}
else searchFile(file);
}
}
(b)啤酒问题
/**
* 需求:啤酒2元1瓶,4个盖子换1瓶,2个空瓶换一瓶,问10元能喝多少瓶,剩余多少空瓶和盖子。
*/
public class FileDemo {
public static int nowMount = 0; //现有啤酒数
public static int emptyBottle = 0; //空瓶数
public static int lid = 0; //盖子数
public static void main(String[] args) {
int money = 10;
//初始化
nowMount = buy(money);
lid = nowMount;
emptyBottle = nowMount;
//兑换
warp();
System.out.println(nowMount+","+lid+","+emptyBottle);
//打印结果
15,3,1
}
/*啤酒 2元-> 1瓶*/
public static int buy(int money){
return (int)Math.floor(money/2.0);
}
/*盖子 * 4 -> 1瓶,空瓶 * 2 -> 1瓶 */
public static void warp(){
if (lid >= 4) {
int bottle = lid / 4;
nowMount += bottle; //盖子换酒
emptyBottle += bottle; //空酒瓶
//剩余盖子
lid %= 4;
lid += bottle;
warp();
}
if (emptyBottle >= 2){
int bottle = emptyBottle / 2;
nowMount += bottle; //空瓶换酒
lid += bottle; //盖子
//剩余空酒瓶
emptyBottle %= 2;
emptyBottle += bottle;
warp();
}
}
}
三、字符集
1、什么是字符集?
2、常用字符集
(1)ASCII字符集
(2)GBK字符集
(3)Unicode码表
3、字符集的编码与解码操作
(1)String编码
方法 | 说明 |
---|---|
byte[] getBytes() | 使用默认字符集将该String编码为一系列字节,结果存储到新的字节数组 |
byte[] getBytes(String charsetName) | 使用指定字符集将该String编码为一系列字节,结果存储到新的字节数组 |
(2)String解码
构造器 | 说明 |
---|---|
String(byte[] bytes) | 使用默认字符集解码指定字节数组来构造新的String |
String(byte[] bytes,String charsetName) | 使用指定字符集解码指定字节数组来构造新的String |
编码与解码的示例
public class StringDemo {
public static void main(String[] args) {
String str = "ASCII我不想用。";
/*编码*/
byte[] bytes = str.getBytes();
System.out.println(Arrays.toString(bytes));
/*解码*/
String newString = new String(bytes);
System.out.println(newString);
}
}
/*打印结果*/
[65, 83, 67, 73, 73, -26, -120, -111, -28, -72, -115, -26, -125, -77, -25, -108, -88, -29, -128, -126]
ASCII我不想用。
四、IO流
(1)概念: 称为输入输出流。
符号 | 说明 |
---|---|
I | 表示input,是数据从硬盘文件读入内存的过程,称之为输入,负责读 |
O | 表示output,是内存程序的数据从内存到写出到硬盘文件的过程,称之输出,负责写 |
(2)作用: 用来读写数据。
(3)IO流的分类方法
(4)IO流体系
(5)字节流
(a)文件字节流FileInputStream
构造器 | 说明 |
---|---|
FileInputStream(File file) | 创建字节输入流管道与源文件对象接通 |
FileInputStream(String pathname) | 创建字节输入流管道与源文件路径接通 |
方法 | 说明 |
---|---|
int read() | 每读取一个字节返回,无字节可读返回 -1 |
int read(byte[] buffer) | 每读取一个字节数组返回,无字节可读返回 -1 |
使用示例
public class StreamDemo {
public static void main(String[] args) {
//1、创建文件字节流管道与源文件接通
//1.1、创建File对象
File file = new File("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\pacageDemo\\loco.txt");
try {
//1.2、文件字节流构造器创建流管道
FileInputStream fis = new FileInputStream(file);
FileInputStream fis1 = new FileInputStream("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\pacageDemo\\loco.txt");
//两种读法
//1.3.1 单字节读取
StringBuilder sb = new StringBuilder();
while(true){
int byteByFile = fis.read();
if (byteByFile == -1) break;
System.out.println("读取了字节"+byteByFile+":" + (char)byteByFile);
}
System.out.println(sb.toString());
//1.3.2 字节组读取
byte[] buffer = new byte[5];
while(true){
int len = fis1.read(buffer);
if (len == -1) break;
System.out.println("读取了"+len+"个字节:"+new String(buffer,0,len));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/*打印结果*/
读取了字节97:a
读取了字节115:s
读取了字节100:d
读取了字节49:1
读取了字节50:2
读取了字节51:3
读取了5个字节:asd12
读取了1个字节:3
解决中文字符乱码问题
//1、创建文件字节流管道与源文件接通
File file = new File("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\pacageDemo\\loco.txt");
//2、创建一个尺寸相同的字节数组
byte[] bytes = new byte[Integer.parseInt(Long.toString(file.length()))];
//3、文件字节流创建
try {
FileInputStream fis = new FileInputStream(file);
//4、字节数组流读取
fis.read(bytes);
System.out.println(new String(bytes));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
/*打印结果*/
asd123我爱你asd123我爱你
asd123经典有机奶。asd123我爱你asd123我爱你
asd123经典有机奶。
//1、创建文件字节流管道与源文件接通
File file = new File("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\pacageDemo\\loco.txt");
try {
//2、创建InputStream;
InputStream is = new FileInputStream(file);
//读取流中的字节
byte[] buffer = is.readAllBytes();
System.out.println(new String(buffer));
} catch (IOException e) {
throw new RuntimeException(e);
}
/*打印结果*/
asd123我爱你asd123我爱你
asd123经典有机奶。asd123我爱你asd123我爱你
asd123经典有机奶。
(b)文件字节输出流 FileOutputStream
作用: 以内存为基准,把内存中的数据以字节的形式写到磁盘文件中去的流。
构造器:
构造器 | 说明 |
---|---|
FileOutputStream(File file) | 创建字节输出流管道与源文件对象接通 |
FileOutputStream(File file,boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
FileOutputStream(String filepath) | 创建字节输出流管道与源文件路径接通 |
FileOutputStream(String filepath,boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
写数据API
方法 | 说明 |
---|---|
void write(int a) | 写一个字节出去 |
void write(byte[] buffer) | 写一个字节数组出去 |
void write(byte[] buffer, int pos , int len) | 写一个部分字节数组出去 |
流的刷新与释放操作
方法 | 说明 |
---|---|
void flush() | 刷新流中的数据 |
void close() | 关闭文件输出流 |
写入数据示例
public class StreamDemo {
public static void main(String[] args) {
try {
//1、创建文件输出流
//默认覆盖文件数据,若想追加数据,在构造器中开启追加功能。
OutputStream os = new FileOutputStream("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\OutStreamDemo.java");
//2、写数据
String str = "package com.zengoo.logback;";
for (int i = 0; i < str.length(); i++) {
// write(int a)
os.write(str.charAt(i));
}
os.write("\r\n".getBytes());
// write(byte[] buffer)
os.write("public class OutStreamDemo{".getBytes());
os.write("\r\n".getBytes());
//write(byte[] buffer,int pos, int len)
byte[] writeString = "\tpublic static void main(String[] args){\r\n\r\n\t}\r\n}".getBytes("UTF-8");
os.write(writeString,0, writeString.length);
os.flush(); //执行后,该流刷新数据并仍可操作。
os.close(); //执行后,该流关闭不可再操作。
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
OutStreamDemo.java
package com.zengoo.logback;
public class OutStreamDemo{
public static void main(String[] args){
}
}
(c)文件拷贝示例
/**
* 需求:将某个文件复制到其它目录下
* 分析步骤:
* 1、读取文件
* 2、写入文件
*/
public class CopyFileDemo{
public static void main(String[] args){
String filepath = "D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\loco.txt";
String dicpath = "D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\pacageDemo\\loco.txt";
try {
/*1、读写对象流*/
FileInputStream input = getInputStream(filepath);
FileOutputStream output = getOutputStream(dicpath);
/*2、向目标对象写入数据*/
output.write(input.readAllBytes());
/*3、关闭流*/
output.close();
input.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static FileInputStream getInputStream(String path) throws FileNotFoundException {
return new FileInputStream(path);
}
static FileOutputStream getOutputStream(String path) throws FileNotFoundException {
return new FileOutputStream(path);
}
}
(6)字符流
(a)文件字符输入流FileReader
构造器 | 说明 |
---|---|
FileReader(File file) | 创建字符输入流管道与源文件对象接通 |
FileReader(String pathname) | 创建字符输入流管道与源文件路径接通 |
方法 | 说明 |
---|---|
int read() | 每读取一个字符返回,若无字符可读,则返回-1 |
int read(char[] buffer) | 每读取一个字符数组,返回读取字符个数,若无字符可读,则返回-1 |
public class ReaderDemo {
public static void main(String[] args) {
try(
Reader reader = new FileReader("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\loco.txt");
Reader reader2 = new FileReader("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\loco.txt");
) {
/*方式1 读取1字符*/
System.out.println("———————————————————方式1:读取1字符———————————————");
int rs;
while((rs = reader.read()) != -1){
System.out.print((char) rs);
}
System.out.println();
System.out.println("———————————————————方式2:读取字符数组———————————————");
/*方式2 读取字符数组*/
char[] chars = new char[20];
while(reader2.read(chars) != -1){
System.out.println(String.valueOf(chars));
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
System.out.println("———————————————————读取完毕———————————————");
}
}
}
/*打印结果*/
———————————————————方式1:读取1字符———————————————
asd123我爱你asd123我爱你
asd123经典有机奶。asd123我爱你asd123我爱你
asd123经典有机奶。
———————————————————方式2:读取字符数组———————————————
asd123我爱你asd123我爱你
asd123经典有机奶。asd123我爱
你asd123我爱你
asd123经典有机奶。
———————————————————读取完毕———————————————
(b)文件字符输出流FileWriter
构造器 | 说明 |
---|---|
FileWriter(File file) | 创建字符输入流管道与源文件对象接通 |
FileWriter(File file,boolean append) | 创建字符输入流管道与源文件对象接通,可追加数据 |
FileWriter(String pathname) | 创建字符输入流管道与源文件路径接通 |
FileWriter(String pathname,boolean append) | 创建字符输入流管道与源文件路径接通,可追加数据 |
方法 | 说明 |
---|---|
int writer(intc ) | 写入1个字符 |
int writer(char[] cbuf) | 写入1个字符数组 |
int writer(char[] cbuf,int off,int len) | 写入字符数组的一部分 |
int writer(String str) | 写入1个字符串 |
int writer(String str,int off,int len) | 写入字符数组的一部分 |
public class WriterDemo {
public static void main(String[] args) {
try( //1、创建输出流
FileWriter writer = new FileWriter("D:\\JavaBase\\JavaSEpro\\src\\com\\zengoo\\logback\\WriterTest.java");
) {
/*写入字符串*/
writer.write("package com.zengoo.logback;\n");
writer.write("public class WriterTest{\n");
/*写入字符数组*/
writer.write("\tpublic static void main(String[] args) {\n\t\n\t}\n".toCharArray());
/*写入单个字符*/
writer.write('}');
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
System.out.println("———————————————————写入完毕———————————————");
}
}
}
WriterTest.java
package com.zengoo.logback;
public class WriterTest{
public static void main(String[] args) {
}
}
字节流与字符流适合的场景
五、资源释放
1、try…catch…finally
在原有处理异常基础上,增加默认执行代码finally
try{
受监视的代码块
}catch(异常类型 变量){
异常处理代码块
}final{
/*3、关闭流*/
output.close();
input.close();
}
注意: finally代码即使在异常发生也会执行,所以finally不会使用return进行返回。
2、try(自定义流)…catch…
这种方法会使得流使用完毕后,自动关闭,达到简化的效果
/*JDK7(推荐使用)*/
try(
InputStream is = new FileInputStream(...);
OutputStream os = new FileOutputStream(...);
){
监听代码块
}catch(Exception e){
异常处理块
}finally{
异常执行块
}
/*JDK9(不推荐)*/
InputStream is = new FileInputStream(...);//输入流
OutputStream os = new FileOutputStream(...);//输出流
try(is;os){
监听代码块
}catch(Exception e){
异常处理块
}finally{
异常执行块
}
注意: JDK 7和JDK 9中( )只能放置资源对象
问:为什么资源对象
答:资源对象是实现了Closeable/AutoCloseable接口的类对象,在try()…catch…体系中,JVM会自动调用Closeable或是AutoCloseable的close()方法完成资源释放。
public abstract class InputStream implements Closeable{}
public abstract class OutputStream implements Closeable, Flushable{}