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. qmh的测试1

    题目:传送门 首先输入一个n,之后输入n个数a(1<=a<=1e7),对这n个数排序后,你需要找到所有的它们连续的长度.把这些连续的长度排序后输出 输入 输入: 8 1 5 2 7 4 5 ...

  2. Gitlab 快速部署及日常维护 (二)

    一.概述 上一篇我们将Gitlab的安装部署和初始化设置部分全部讲解完成了,接下来我们介绍Gitlab在日常工作中常遇见的问题进行梳理说明. 二.Gitlab的安装和维护过程中常见问题 1.Gitla ...

  3. anaconda python3.7 安装 tensorflow-gpu 2.0.0 beta1 配置PyCharm

    参考tensorflow 公众号<tensorflow2.0 安装指南> https://mp.weixin.qq.com/s/7rNXFEC5HYe91RJ0-9CKdQ # 1. NV ...

  4. ZOJ 2563 Long Dominoes(状压DP)题解

    题意:n*m的格子,用1 * 3的矩形正好填满它,矩形不能重叠,问有几种填法 思路:poj2411进阶版.我们可以知道,当连续两行的摆法确定,那么接下来的一行也确定.当第一行还有空时,这时第三行必须要 ...

  5. hdu1228双指针

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; char ...

  6. shiro<1.2.4反序列化分析

    0x01.环境搭建 下载地址:https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4 环境:Tomcat 8.5.27 + idea ...

  7. CURL (CommandLine Uniform Resource Locator) 简易教程!

    1 http://curl.haxx.se/ http://curl.haxx.se/docs/httpscripting.html curl is an open source command li ...

  8. Get your site working on Google Search Console , 在 Google Search Console中运行您的网站, Google Search Console

    1 1 https://support.google.com/webmasters/topic/4564315? Search Console Help SEARCH CONSOLEHELP FORU ...

  9. 如何实现 React 模块动态导入

    如何实现 React 模块动态导入 React 模块动态导入 代码分割 webpack & code splitting https://reactjs.org/docs/code-split ...

  10. convert image to base64 in javascript

    convert image to base64 in javascript "use strict"; /** * * @author xgqfrms * @license MIT ...