/* 日志 以前记录日志是在控制台输出信息,打个输出语句,比如xxx方法被执行了,但是这样不能将其记录到文件或者数据库. 如果代码关闭以后出现问题没法回溯到之前的时间,比如网站用户昨天充值VIP没到账,开发者没用日志技术,就很难找到昨天的情况 日志技术的优势 可以将程序运行的信息选择性的记录到控制台,文件或者数据库中,方便永久保存 日志还可以随时开关,想记录就记录,想打什么就打什么,比如只记录出错的信息等,修改方便 日志利用多线程技术,性能好过在程序里写输出语句,虽然日志学起来用起来感觉和输出语句差不多 日志技术体系 这么多程序员如果随便写日志框架,那就混乱不堪,谁也看不懂,学习成本也很大 为了规范日志技术的体系,降低程序员的学习成本,java提供了两个接口作为实现日志框架的标准. 一个是叫commons logging,简称JCL,一个叫simple logging facade for java,简称slf4j 通过实现这两个接口中的一个,可以定义出规范的日志框架供他人使用 有一些大佬开发了一个日志框架叫logback,实现了slf4j接口,他这个是目前最好的日志框架,我们直接用大佬写好的就行了 Logback日志框架 要想使用logback日志框架,可以百度搜索logback进官网下载 logback日志框架主要分为三个技术模块,core,classic,access core就是核心,等于后面两个模块的基础. classic是经典功能,是log4j的增强版本,也实现了slf4j(log4j也是这个大佬之前开发的一个日志框架) access是收集一些web上的信息,提供HTTP的日志访问 如何使用Logback 要想使用Logback日志框架,首先要去下载slf4j,和logback的core/classic三个jar包文件. 搜索logback日志下载即可 jar包其实就是封装好的很多的类文件,我们可以直接导入到IDEA里 首先在与IDEA的src目录同级别的地方右键新建一个Dictionary,命名为lib,意为library. 然后将jar包文件复制进去,复制进去以后是不能直接打开的 再在IDEA里选中这三个包,右键点击Add as Library, 这样操作以后jar包里面的内容就可以打开了 要想使用logback,还需要一个配置文件,也可以去网上下载,logback.xml. 将这个文件拷贝到src里面 接下来就可以去创建logback的日志对象了,调用LoggerFactory里面的getLogger方法,入参可以命名要打印的日志,顺便定义成静态final的,返回一个日志对象 public static final Logger LOGGER = LoggerFactory.getLogger("LOGGER"); 此时就可以用Logger的方法来输出信息了 xml配置文件 主要是可以定义在控制台输出的格式,输出日志文件的位置和格式,以及日志文件的最大大小.比如一个程序运行时间较长,那么日志内容也会比较多 这就需要对日志进行大小分割,比如每1MB就分割一个文件,这样方便后续查找和利用 还有一个开关,在levelroot里可以设置的. 可以配置是否在控制台和或者是否生成日志文件, 以及设置级别 日志级别 通过设置日志级别,可以看到自己想看的信息.级别分为五个,程度依次是:trace跟踪,debug调试,info信息,warn警告,error错误 默认开启的级别是debug. 写日志,调用日志方法的时候就需要选择这个级别,比如不太重要的可以定义成info,错误日志定义成error 设置了级别以后,日志只会输出这个级别以及更高级别的信息. 比如开启级别是debug,那么就会输出debug,info,warn,error四个级别的信息 如果设置成error级别,那么就只能看到error级别的一些日志. 还有两个特殊级别,是ALL和OFF,代表全开启全关闭 try { LOGGER.debug("main方法"); LOGGER.info("我开始记录第二行"); int a = 10; int b = 0; LOGGER.trace("a=" + a); LOGGER.trace("b=" + b); System.out.println(a / b); } catch (Exception e) { e.printStackTrace(); LOGGER.error("功能异常" + e); } 记录日志的方法就是用前面创建的LOGGER对象来调用五个级别的方法,再在里面写上日志信息即可 */
/* File 方法运行时候数据都储存在内存里,如果方法结束了,那数据就会随之消失. 为了永久保存数据,或者操作文件,需要学习file类. File不能读写文件内容,只能定位文件,操作文件本身. 要想读写文件,需要学习IO流 File类在包java.io.File下,这个类提供了一些方法,比如查看文件信息,删除创建等 要想使用file的功能,应该先创建file对象. 调用file的有参构造器,参数直接输入要调取的文件的路径即可 File f = new File("D:\\帮助说明.txt"); 这里有三种写法,第一种写法是两个反斜杠,第一个反斜杠告诉后面的反斜杠他就是一个反斜杠,避免java把后面的反斜杠和第一个字符当成一个整体来看 第二种写法是用/正斜杠,也可以同样的效果 第三种写法是用api:File.separator 可以生成一个分隔符,好处是多平台运行无需更改路径,兼容性好 File的创建不但支持绝对路径,还支持相对路径. 如果填写绝对路径,那会有很大弊端.比如更改位置或者系统以后,所有路径可能都和之前不同. 但是相对路径可以解决这个问题,相对路径可以直接从当前工程里的目录下寻找文件.即使在计算机里的绝对位置改变,只要相对 路径不变依然可以找得到这个文件. File file = new File("javasepromax\\DAY09-oop-demo\\abc.txt"); File可以直接拿文件夹创建对象,但是不能正确获取字节数 常用方法 file.getAbsolutePath() 获取绝对路径 file.getPath() 获取定义时的路径 file.length() 获取文件的大小,以字节为单位 file.getName() 获取文件名 file.lastModified() 获取最后修改的时间,返回时间毫秒值,需要转成date file.isFile() 是否是文件 file.isDirectory() 是否是文件夹 file.createNewFile() 在创建的时候无论是否有那个文件,file对象都会创建成功的. 如果实际上没有,那可以用这个file对象调用createNewFile方法来创建这个文件 file.mkdir()和file.mkdirs() 同上,但是mkdir只能创建一级目录,无法创建多级. mkdirs可以创建多级目录 比如现在我的C盘下有一个文件夹是C:\Users,现在我用C:\Users\aaa作为路径来创建file对象,此时file.mkdir()就会自动创建这个aaa文件 但是如果是多级文件就不行了,比如现在我创建一个C:\Users\aaa\bbb\ccc的file对象,这时候其实是要创建三级目录,就需要调用file.mkdirs方法 file.delete() 删除文件, 或者删除空文件夹. 非空文件夹不能直接删除,要想删除则需要对文件夹进行遍历 遍历的方法和api file.list() list方法会获取这个文件夹里面所有一级目录下的文件的文件名,然后以String[]数组的形式返回 file.listFiles() listFiles会返回这个文件夹里所有一级目录下的文件file对象,然后以File[]来储存 值得注意的是,如果找不到这个目录,则会返回null,如果file本身不是一个文件夹而是文件,那他下面不可能有一级目录了, 所以list()和listFiles()方法都会返回null. */ /* 方法递归 递归有两种,直接递归和间接递归. 直接递归就是方法自己调用自己, 简洁递归是方法1调用方法2,方法2再调用方法1. 如果控制不好,可能会出现递归死循环. 因为自己调用自己, 这个方法不会出栈, 随着方法越来越多,栈内存就会爆,程序会挂掉 递归解决问题的思路是把复杂问题层层转化成一个与原问题相似但规模较小的问题来求解 规律化递归 递归的三大要素大体可以总结为:递归的公式,递归的终点,递归的方向必须走向终点 实例1:定义一个方法求出n! 第一步,找出递归公式 f(2) = f(1) * 2; f(3) = f(2)*3; 可以知道:f(n) = f(n-1)*n 第二步,确定递归终点 f(1) = 1 第三步,确定递归的方向是走向终点的,比如f(10),最终会变成f(1),确实会走到终点 确定这三步以后代码就很容易写了 public static int f(int n){ if(n == 1){ return 1; }else{ return f(n-1)*n ; } } 实例2:有一只猴子和若干桃子,猴子第一天吃完了全部桃子的一半,后额外又吃一个. 第二天再吃一半,然后再吃一个. 到了第十天,桃子只有一个了.那么第一天猴子有多少桃子? 第一步,找出递归公式. f(9) = (f(10)+1)*2 假如用n表示天数,f表示剩余的桃子数,那么f(n) = (f(n+1)+1)*2; 第二步,确定递归终点, f(10) = 1; 第十天只有一个桃子 第三步,让递归走向终点,那就从1走到10即可 public static int f(int n){ if(n == 10){ return 1; }else{ return (f(n+1)+1)*2; } } 非规律化递归 实例:从给定目录下查找某个文件,输出这个文件的地址值 public static void find(File dir, String fileName) { //先判断一下传进来的是不是文件夹以及是否为null if (dir != null && dir.isDirectory()) { //把里面所有一级目录下的文件创建城file对象存入数组 File[] files = dir.listFiles(); //先确定数组不是null,然后确定里面有元素. 值得注意的是,必须先判定不是null,再判定数组长度,否则会空指针异常 if (files != null && files.length > 0) { //遍历里面每一个file文件 for (File file : files) { //如果是文件,就看一下是否是这个. 如果不是文件证明是文件夹,重复上述过程 if (file.isFile()) { if (file.getName().equals(fileName)) { System.out.println(file.getAbsolutePath()); } } else { //开始递归,在这个文件夹里重复整个方法 find(file, fileName); } } } } } */