I/O流·文件递归

统计该文件夹的大小

* 需求:从键盘就收一个文件夹路径,统计该文件夹的大小

package com.heima.test;

import java.io.File;
import java.util.Scanner; public class Test1 {
/*
* 分析:
* A、从键盘接收文件夹路径:
* 1、创建键盘录入对象
* 2、定义无限循环
* 3、将键盘录入的结果存储并封装成File对象
* 4、对File对象判断
* 5、将文件夹路径对象返回
*
* B、统计该文件夹大小
* 1、定义一个求和变量
* 2、获取该文件夹下所有的文件和文件夹 listFiles();
* 3、遍历数组
* 4、进行判断,如果是文件就计算大小并累加,如果是文件夹就递归调用
*/
public static void main(String[] args) {
File dir = getFile(); // 获取文件夹路径
//System.out.println(dir.length()); // 文件夹是不能直接获取大小的,调用length()返回的是 0
long len = getFileSize(dir);
System.out.println(len / 1024 / 1024 + "M"); }
/*
* 从键盘接收一个文件夹路径:
* 1、返回值类型File
* 2、无参数
*/
public static File getFile() {
Scanner sc = new Scanner(System.in); // 创建键盘录入对象
System.out.println("请输入一个文件夹路径"); // 提示输入
while (true) { // 定义无限循环
String line = sc.nextLine(); // 录入文件夹路径
File dir = new File(line); // 封装成File对象
if (!dir.exists()) { // 判断是否存在
System.out.println("您录入的文件夹路径不存在,请重新输入");
} else if (dir.isFile()) { // 判断是否为文件
System.out.println("您录入的是文件路径,请重新输入");
} else {
return dir; // 返回File对象
}
}
}
/*
* 统计文件夹大小
* 1、返回值类型为long
* 2、参数列表为File对象
*/
public static long getFileSize(File dir) { // 接收File对象
long len = 0; // 定义文件大小为0
File[] subFiles = dir.listFiles(); // 获取该文件夹下的所有内容,返回File数组
for (File subFile : subFiles) { // 遍历数组
if (subFile.isFile()) { // 判断是否为文件
len = len + subFile.length(); // 计算大小
} else {
len = len + getFileSize(subFile); // 递归调用
}
}
return len; // 返回当前文件夹的内容的大小
} }

Test1

删除该文件夹

* 需求:从键盘接收一个文件夹的路径,删除该文件夹

package com.heima.test;

import java.io.File;

public class Test2 {
/*
* 分析:
* 删除该文件夹:
* 1、获取该文件夹下的所有的文件和文件夹
* 2、遍历数组
* 3、判断,如果是文件就直接删除,如果是文件夹就递归调用
* 4、循环结束后再把空文件夹删掉
*/
public static void main(String[] args) {
File dirFile = Test1.getFile(); // 获取文件夹路径
deleteFile(dirFile); // 删除文件夹,注意删除的时候要小心,因为不走回收站,数据难以还原
System.out.println("文件夹以删除");
}
/*
* 删除文件夹
* 1、返回值类型为空
* 2、参数列表为File对象
*/
public static void deleteFile(File dir) { // 传入文件夹路径
File[] subFiles = dir.listFiles(); // 获取该文件夹下的所有内容,返回File数组 for (File subFile : subFiles) { // 遍历数组
if (subFile.isFile()) { // 判断是否为文件
subFile.delete(); // 删除文件
}else {
deleteFile(subFile); // 递归调用
}
} dir.delete(); // 循环结束后文件夹已经是空的了,此时可以删除该文件夹
}
}

Test2

拷贝文件夹

* 需求:从键盘接收两个文件夹路径,把其中一个文件夹(包括内容)拷贝到另一个文件夹中

package com.heima.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; public class Test3 {
/*
* 分析:
* 1、在目标文件夹下创建原文件夹
* 2、获取源文件夹中所有的文件和文件夹,存储在File 数组中
* 3、遍历数组
* 4、如果是文件,就用io流读写
* 5、如果是文件夹,就递归调用
*/
public static void main(String[] args) throws IOException {
File src = Test1.getFile(); // 获取原文件夹路径
File dest = Test1.getFile(); // 获取目标文件夹路径
if (!src.equals(dest)) { // 判断二者是否不同,避免无限循环,文件夹内嵌套过多会导致系统无法删除
copy(src, dest);
} else {
System.out.println("目标文件夹是源文件的子文件夹"); // 如果目标文件和原文件夹是嵌套关系也会无限循环
}
}
/*
* 文件拷贝:
* 1、 返回值类型为空
* 2、参数列表两个File对象
*/
public static void copy(File src, File dest) throws IOException { // 传入两个File对象
File newDir = new File(dest, src.getName()); // 新建File对象,使其在目标目录下,并且和原文件夹同名
newDir.mkdir(); // 在目标路径下建立和原文件夹同名的文件夹
File[] subFiles = src.listFiles(); // 获取原文件夹下的所有内容,返回File数组
for (File subFile : subFiles) { // 遍历数组
if (subFile.isFile()) { // 判断是否是文件
BufferedInputStream bis = // 创建带缓冲的字节输入流,关联原文件下的文件
new BufferedInputStream(new FileInputStream(subFile));
BufferedOutputStream bos = // 创建带缓冲的字节输出流,并且在目标路径下创建和原文件同名的文件,并与之关联
new BufferedOutputStream(new FileOutputStream(new File(newDir, subFile.getName()))); int b;
while ((b = bis.read()) != -1) { // 读取原文件内的数据
bos.write(b); // 向目标路径下的同名文件中写入数据
} bis.close(); // 关流
bos.close(); } else {
copy(subFile, newDir); // 如果是文件夹,就递归调用
// subFile是原文件下的文件夹,newDir是目标路径的上一层级的文件夹 }
}
} }

Test3

按层级打印

* 需求:从键盘接收一个文件夹的路径,把文件夹中国的所有文件及文件夹的名字按层级打印

package com.heima.test;

import java.io.File;

public class Test4 {
/*
* 分析:
* 1、获取所有文件和文件夹,返回的是File数组
* 2、遍历数组
* 3、无论是文件还是文件夹,都需要直接打印
* 4、如果是文件夹就递归调用
*/
public static void main(String[] args) {
File dir = Test1.getFile(); // 获取文件夹路径
printLev(dir, 0); // 打印
}
/*
* 按层级打印:
* 1、返回值类型为空
* 2、参数列表是File对象和层级数
*/
public static void printLev(File dir, int lev) { // 传入File对象和层级数
File[] subFiles = dir.listFiles(); // 获取File下的所有内容,返回File数组 for (File file : subFiles) { // 遍历数组
for (int i = 0; i < lev; i++) {
System.out.print("\t"); // 按照层级打印缩进
} System.out.println(file); // 打印文件名
if (file.isDirectory()) { // 判断是否为文件夹
printLev(file, lev+1); // 递归调用,同时将层级数增加
}
}
} }

Test4

1000的阶乘中尾部零的个数

* 需求:求出1000阶乘尾部零的个数

package com.heima.test;

import java.math.BigInteger;

public class Test6 {

    public static void main(String[] args) {
// demo1();
// demo2();
// demo3(); } public static void demo1() {
int result = 1;
for (int i = 1; i < 1000; i++) {
result *=i;
}
System.out.println(result); // 因为1000的阶乘远大于int的取值范围,所以值输出为0
} public static void demo3() {
// 获取1000的阶乘尾部有多少个0
BigInteger bi1 = new BigInteger("1"); // 创建BigInteger,通过构造传入字符串型数字
for (int i = 1; i <= 1000; i++) {
BigInteger bi2 = new BigInteger(i + ""); // 将乘数转换为BigInteger类型
bi1 = bi1.multiply(bi2); // 相乘
} String str = bi1.toString(); // 转换为字符串
StringBuilder sb = new StringBuilder(str); // 创建StringBuilder对象,并通过构造将字符串传入
str = sb.reverse().toString(); // 链式编程 int count = 0; // 定义计数器
for (int i = 0; i < str.length(); i++) { // 遍历字符串
if (str.charAt(i) != '0') { // 判断每一位字符是否为0
break; // 如果不是,就跳出循环
}else {
count ++;
}
} System.out.println(count);
} public static void demo2() {
// 求1000的阶乘中所有的零
BigInteger bi1 = new BigInteger("1"); // 创建BigInteger,通过构造传入字符串型数字 for (int i = 1; i <= 1000; i++) {
BigInteger bi2 = new BigInteger(i + ""); // 将乘数转换为BigInteger的形式
bi1 = bi1.multiply(bi2); // 将bi1与bi2相乘的结果赋值给bi1
} String str = bi1.toString(); // 获取BigInteger的字符串表现形式
int count = 0; // 统计字符0出现的次数
for (int i = 0; i < str.length(); i++) { // 遍历字符串
if (str.charAt(i) == '0') { // 判断是否为字符0
count ++;
}
} System.out.println(count);
}
}

不用递归

package com.heima.test;

public class Test7 {
// 如果有因数能被5整除,那么这个因数一定会使阶乘末尾产生一个零
public static void main(String[] args) {
System.out.println(fun(1000));
} public static int fun(int num) {
if (num > 0 && num < 5) {
return 0;
} else {
return num / 5 + fun(num / 5);
}
}
}

递归

约瑟夫环

* 需求:求出幸运数字

package com.heima.test;

import java.util.ArrayList;

public class Test8 {
// 约瑟夫环
public static void main(String[] args) {
System.out.println(getLuckyNum(8)); // 获取幸运数字
}
/*
* 获取幸运数字:
* 1、返回值类型int
* 2、参数列表int num
*/
public static int getLuckyNum(int num) {
ArrayList<Integer> list = new ArrayList<Integer>(); // 创建集合,存储1到num的对象
for (int i = 1; i <= num; i++) {
list.add(i); // 将1到num的数字存储到集合中
} int count = 1; // 一旦count能被3整除,就删除元素
for (int i = 0; list.size() != 1; i++) { // 只要元素的数量大于1,就要不断的删除
if (i == list.size()) { // 如果i增长到list集合最大的索引加一时,重新归零
i = 0;
} if (count % 3 == 0) { // 判断是否为3的倍数
list.remove(i); // 删除元素
i--; // 注意一定要对索引减一,因为列表在删除元素的时候,后面的元素都会往前进一位,此时不需要在对i自增了
}
count ++;
}
return list.get(0); // 返回幸运数字
} }

Test6

Java I/O流 05的更多相关文章

  1. java基础-IO流对象之Properties集合

    java基础-IO流对象之Properties集合 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Properties集合的特点 Properties类表示了一个持久的属性集. ...

  2. Java IO: 字符流的Piped和CharArray

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本章节将简要介绍管道与字符数组相关的reader和writer,主要涉及PipedReader.Pip ...

  3. day38-IO流05

    JavaIO流05 4.常用的类04 4.4节点流和处理流03 4.4.8打印流-PrintStream和PrintWriter 打印流只有输出流,没有输入流 1.简单介绍及应用 PrintStrea ...

  4. 【转】输入/输出流 - 深入理解Java中的流 (Stream)

    基于流的数据读写,太抽象了,什么叫基于流,什么是流?Hadoop是Java语言写的,所以想理解好Hadoop的Streaming Data Access,还得从Java流机制入手.流机制也是JAVA及 ...

  5. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  6. 理解Java中字符流与字节流的区别

    1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序 ...

  7. Java Io 字符流

    Java Io 字符流包含: 1. InputStreamReader  它是由byte流解析为char流,并且按照给定的编码解析. 2. OutputStreamWrite  它是char流到byt ...

  8. mybatis oracle java.sql.SQLException: 流已被关闭问题

    /** * 按照页码取值(从current_page页开始,每页page_size条) * @param key * @param params * @param current_page * @pa ...

  9. Java IO包装流如何关闭?

      问题: (1)JAVA的IO流使用了装饰模式,关闭最外面的流的时候会自动调用被包装的流的close()方吗? (2)如果按顺序关闭流,是从内层流到外层流关闭还是从外层到内存关闭? 问题(1)解释: ...

随机推荐

  1. Codeforces Round #570 (Div. 3) E. Subsequences (easy version) (搜索,STL)

    题意:有一长度为\(n\)的字符串,要求得到\(k\)不同的它的子序列(可以是空串),每个子序列有\(|n|-|t|\)的贡献,求合法情况下的最小贡献. 题解:直接撸个爆搜找出所有子序列然后放到set ...

  2. 牛客编程巅峰赛S1第5场 - 青铜&白银 A.凯撒密码(字符串)

    题意:给你一个加密的字符串,以及偏移量,求对应的明文. 题解:根据样例,不难看出模板串是:\(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq ...

  3. Linux-平均负载指数

    目录 系统平均负载 什么是平均负载 平均负载多少合理 如何观察平均负载 平均负载和CPU的使用率的区别 平均负载分析 执行CPU密集型任务 执行I/O密集型任务 大量进程调度 关于平均负载的总结 系统 ...

  4. cdn jsdelivr + github releases 以wordpress sakura主题manifest为例

    1 创建github repository 在本地创建文件,这里为文件夹 /manifest 在github创建库wordpresscdn,上传 /manifest到库中 2 github relea ...

  5. UESTC - 1222 Sudoku(深搜)

    Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny game himself. It looks l ...

  6. codefoeces 864B

    B. Polycarp and Letters time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. C# TextBlock

    TextBlock 适合长文本多行显示,Label可以看成是一个简短的单行的TextBlock,只是Label可以显示图片,TextBlock只能显示纯文本 默认的文本不会分行显示,超出窗体宽度的字符 ...

  8. Dapr 正式发布1.0

    年前我写了一篇博客<Dapr 已在塔架就位 将发射新一代微服务>, 今天Dapr 正式发布了1.0 : Dapr Runtime v1.0.0 Dapr dotnet SDK v1.0.0 ...

  9. SVG path d Attribute

    Scalable Vector Graphics (SVG) 1.1 (Second Edition) W3C Recommendation 16 August 2011 http://www.w3. ...

  10. npm ip

    npm ip webpack $ ip address var ip = require('ip'); ip.address() // my ip address ip.isEqual('::1', ...