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 - 1201B Zero Array

    You are given an array a1,a2,-,ana1,a2,-,an. In one operation you can choose two elements aiai and a ...

  2. SSM框架整合(Spring + SpringMVC + MyBatis)

    搭建环境 使用Spring(业务层)整合其他的框架SpringMVC(表现层)和MyBatis(持久层) Spring框架 创建数据库表 CREATE DATABASE ssm; USE ssm; C ...

  3. Netty(六)揭开 BootStrap 的神秘面纱

    6.1 客户端 BootStrap 6.1.1 Channel 简介 在 Netty 中,Channel 是一个 Socket 的抽象,它为用户提供了关于 Socket 状态(是否是连接还是断开)以及 ...

  4. 银河麒麟V10安装ASP.NET Core并配置Supervisor让网站开机自动运行

    银河麒麟高级服务器操作系统V10是针对企业级关键业务,适应虚拟化.云计算.大数据.工业互联网时代对主机系统可靠性.安全性.性能.扩展性和实时性的需求,依据CMMI 5级标准研制的提供内生安全.云原生支 ...

  5. js optional chaining operator

    js optional chaining operator js 可选链 可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效. ?. 操作符的功能类似于 ...

  6. Gatsby Themes

    Gatsby Themes React & SSR gatsby-config.js refs https://www.gatsbyjs.com/docs/themes/ https://ww ...

  7. How to using PyPI publish a Python package

    How to using PyPI publish a Python package PyPI & Python package https://pypi.org/ main make a f ...

  8. infinite auto load more & infinite scroll & load more

    infinite auto load more & infinite scroll & load more https://codepen.io/xgqfrms/pen/NZVvGM ...

  9. Flutter: 使用相机拍照

    文档 camera import 'dart:io'; import 'package:camera/camera.dart'; import 'package:flutter/material.da ...

  10. 04、数组与Arrays工具类

    目录 前言 一.一维数组 基本认识 内存空间 二.二维数组 基本认识 三.工具类Arrays 前言 去年四月份大一下半学期正式开始学习Java,一路从java基础.数据库.jdbc.javaweb.s ...