零基础学习java------day16-----文件,递归,IO流(字节流读写数据)
1.File
1.1 构造方法(只是创建已经存在文件的对象,并不能创建没有的文件)
(1)public File(String pathname)
(2)public File(String parent, String child)
(3)public File(File parent, String child)
public class FileDemo1 {
public static void main(String[] args) {
File f = new File("e:/a/b");
System.out.println(f.exists()); //true
File f1 = new File("e:/G09 result/","H2O"); //此处result后的“/”号有无都可以
System.out.println(f1.exists()); //true
File f2 = new File(f1,"H2O.out");
System.out.println(f2.exists());//true
}
}
1.2 File类成员方法
1.2.1 创建删除重命名功能
(1)创建功能
public boolean createNewFile() 创建文件
public boolean mkdir() 创建单层文件夹
public boolean mkdirs() 创建多层文件夹
(2)删除功能
public boolean delete() 删除文件或文件夹(文件夹中有内容无法删除)
(3)重命名功能
public boolean renameTo(File dest) 重命名(移动)
public class FileDemo2 {
public static void main(String[] args) {
try {
File f = new File("e:/G09 result/H2O/t.txt");//创建文件的时候,目录必须存在
boolean b = f.createNewFile();
new File("e:/a").mkdir(); //在盘创建了a文件夹
new File("e:/a/b/c/d").mkdirs();//创建了多层文件夹,此对象代表d这个文件夹
File f1 = new File("e:/123");
f1.createNewFile();//得到的是一个文件,文件可以没有后缀名
File f2 = new File("e:/789.txt");
f2.mkdir();//得到的是一个文件夹
f1.delete();
f2.delete(); // 如果文件夹中有内容是不能被删除的
f.renameTo(new File("d:/haha.txt")); //将e:/G09 result/H2O/t.txt文件移动到d盘,并重命名为haha.txt
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.2.2 判断功能
(1)public boolean isDirectory():是否是目录
(2)public boolean isFile():是否是文件
(3)public boolean exists():是否存在
(4)public boolean canRead():是否可读
(5)public boolean canWrite():是否可写
(6)public boolean isHidden(): 是否隐藏
public class FileDemo3 {
public static void main(String[] args) {
File f = new File("e:/a");
System.out.println(f.exists()); //true
System.out.println(f.isDirectory());//true
System.out.println(f.isFile());//false
System.out.println(f.canRead()); //true
System.out.println(f.canWrite()); //true
System.out.println(f.isHidden()); //false
}
}
1.2.3 获取功能
a . 基本获取功能
(1)public String getAbsolutePath():获取绝对路径
(2)public String getPath(): 获取相对路径
(3)public String getName(): 获取文件名
(4)public long length(): 获取字节数
(5)public long lastModified: 获取最后修改时间
public class FileDemo4 {
public static void main(String[] args) throws IOException {
File f1 = new File("忽然.txt");
f1.createNewFile();
System.out.println(f1.getAbsolutePath());//E:\development\workspace\java\javase\javase\忽然.txt
System.out.println(f1.getPath());//忽然.txt
System.out.println(f1.getName());//忽然.txt
System.out.println(f1.length());
System.out.println(f1.lastModified());//1566540753201
//先将long类型的毫秒值转为date类型的时间,然后再讲此时间转为特定格式的时间
System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(f1.lastModified())));
}
}
b . 高级获取功能
(1)public String[ ] list(): 获取所有子文件名称(返回值类型为字符串数组)
(2)public File[ ] listFiles(): 获取所有子文件对象 (返回值类型为文件类型数组)
public class FileDemo5 {
public static void main(String[] args) {
File f = new File("E:\\exercise");
System.out.println(f.list()); //[Ljava.lang.String;@279f2327
System.out.println(Arrays.toString(f.list()));//这样转化后就能打印数组了
File[] listFiles = f.listFiles();
System.out.println(f.listFiles());//[Ljava.io.File;@2ff4acd0,需要将其遍历出来
for(File file:listFiles) {
System.out.println(file);
}
}
}
练习 查询单层文件夹下所有以后缀名(.jpg))结尾的文件,此处,我要查询的文件夹如下:
法一:
public class FindFile {
public static void main(String[] args) {
getFile("E:\\exercise",".jpg");
}
public static void getFile(String path,String suffix) {
File f = new File(path);
File[] listFile = f.listFiles();
for (File file : listFile) {
//除了判断后缀,还要判断是不是文件,有大写文件的话,转为小写
if(file.isFile() && file.getName().toLowerCase().endsWith(suffix)) {
System.out.println(file.getAbsolutePath());
}
}
}
}
法二(使用过滤器)
public class FindFile {
public static void main(String[] args) {
getFile("E:\\exercise",".jpg");
}
public static void getFile(String path,String suffix) {
File f = new File(path);
// 带有过滤器为参数的listFiles方法,这里使用了匿名函数来创建过滤器对象
File[] files = f.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
File f1 = new File(dir,name);
if(f1.isFile()&&f1.getName().toLowerCase().endsWith(suffix)) {
return true;
}
return false;
}
});
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
}
}
2. 递归
2.1 递归的思想概述
方法定义中调用本身的现象。
注意事项:
递归要有出口,否则就是死递归;次数不能太多,否则内存会溢出;构造方法不能递归使用
2.2 递归的思想
找到出口;找到规律
2.3 递归练习
1. 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到三个月后每个月又生一对兔子,假如兔子都不死,问第十个月兔子对数为多少?
本题的本质是斐波那契数列,如下图:
第一个月时,有一对兔子(刚生下来为小兔子,过了一个月后就变成大兔子,再过一个月就能生小兔子),第二个月是总的兔子数还是为1,但此时小兔子变成了大兔子,第三个月大兔子生了一对小兔子,所以第三个月有2对兔子(一大一小),依次类推下去可得斐波那契数列(正如图上的sum行)
public class BornRabbit {
public static void main(String[] args) {
System.out.println("10个月后兔子对数:"+ rabbitNumber(10));
}
public static int rabbitNumber(int month) {
if(month==1 || month==2) {
return 1;
}else {
return rabbitNumber(month-1)+rabbitNumber(month-2);
}
}
}
2.小猴子第一天摘下若干桃子,当即吃掉一半,又多吃一个,第二天早上又将剩下的桃子吃掉一半,又多吃一个,以后每天早上吃前一天剩下的一半以及另一个。到第10天早上猴子想再吃时发现,只剩下一个桃子了,问第一天猴子共摘了多少个桃子?
规律如下图
public class Monkey {
public static void main(String[] args) {
System.out.println(eatPeach(1));
}
public static int eatPeach(int day) {
if(day==10) {
return 1;
}else {
return 2*(eatPeach(day+1)+1);
}
}
}
3. 递归查找文件(文件夹有多层)
public class RecursionFindFiles {
public static void main(String[] args) {
findAllFiles("E:/exercise",".jpg");
}
public static void findAllFiles(String path, String suffix) {
File f = new File(path);
//如果传入的路径为文件
if(f.isFile()) {
if(f.getName().toLowerCase().endsWith(suffix));{
System.out.println(f.getAbsolutePath());
}
}else { //是文件
//获取所有子文件
File[] listFiles = f.listFiles();
if(listFiles!=null && listFiles.length>0) {
for (File file : listFiles) {
findAllFiles(file.getAbsolutePath(),suffix);
}
}
}
}
}
变形:递归删除文件夹以及其中的所有文件
public class RecursionDelete {
public static void main(String[] args) {
findAllFiles("E:/a");
}
public static void findAllFiles(String path) {
File f = new File(path);
//如果传入的路径为文件
if(f.isFile()) {
f.delete();
}else { //是文件
//获取所有子文件
File[] listFiles = f.listFiles();
if(listFiles!=null && listFiles.length>0) {
for (File file : listFiles) {
findAllFiles(file.getAbsolutePath());
}
}
f.delete();
}
}
}
3. IO流
3.1 IO流的概述
IO流用来处理设备之间的数据传输(上传文件和下载文件),Java对数据的操作是通过流的方式,此外java用于流的操作对象都在IO包中
3.2 IO流的分类
(1)按照数据流向
输入流: 读入数据
输出流:写出数据
(2)按照数据类型
字节流,字符流
一个汉字若按字节流处理,需要处理3次(utf8编码中一个汉字3个字节),若用字符流来处理只需要一次,但字符流一般只能用来处理文本文件,如图片就不能处理,但字节流(任何文件都可以处理)可以,所以字节流较字符流使用范围更广
(3)什么情况下使用哪种流呢?
如果数据所在的文件通过windows自带的记事本打开并能读里面的内容,就用字符流。其他用字节流
3.3 IO流常用基类
(1)字节流的抽象基类:
InputStream,OutputStream
(2)字符流的抽象基类
Reader , Writer
注意:由这四个类派生出来的子类名称都是以其父类名作为类名的后缀
如:InputStream的子类FileInputStream
Reader的子类FileReader
3.4 字节流写数据(FileOutputStream)
3.41 FileOutputStream的构造方法:
(1)FileOutputStream(File, file)
(2)FileOutputStream(String name) //一般用第二种,方便点
3.4.2 FileOutputStream的成员方法
(1)public void write(int b)
(2)public void write(byte[ ] b)
(3)public void write(byte[ ] b,int off, int len)
public class FileOutputStreamDemo {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("d:/haha.txt");
fos.write(97);
fos.write(98);
fos.write(99);
} catch (Exception e) {
e.printStackTrace();
}finally { // 关流,即关闭文件
if(fos != null) { //此处要判断下不为null
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:d盘中的haha.txt写入了abc
但是怎样写入一字符串呢?=====>将字符串转成Byte,改用第二或第三个成员方法
fos.write("忽然就流出泪来".getBytes());//此代码紧接着fos.write(99)哪行写
fos.write("哈哈忽然间想要听到他的声音".getBytes(),6,33);//后面两个int值第一个为偏移量,第二个为从偏移量位置开始写入数据的长度,这里长度以Byte为单位
运行结果:abc忽然就流出泪来,忽然间想要听到她的声音
有上面代码可知,手动关流写起来比较麻烦,JDK1.7以后提供了自动关流的方法,格式如下:
try(流的定义语句){ }catch(){ }
注意:另外创建一个流,并将数据写入原先有数据的文件,会将原先的数据覆盖掉)(如上面例子中haha.txt原先若有内容则会覆盖掉),但一个流中依次写入的数据,后者写入不会覆盖前者写入的数据
让其不覆盖院线数据的方法是:在利用构造方法创建对象时传两个参数,除了路径再传个True(默认是false),这样就不会覆盖原先的数据了
当将上诉第5行代码换成如下代码时,运行多次程序,会得到多句同样的结果,不会覆盖(原先无论运行几次都是一句话)
fos = new FileOutputStream("d:/haha.txt",true);
3.5 字节流读取数据(FileInputStream)
3.5.1 FileInputStream的构造方法
(1)FileInputStream(File file)
(2)FileInputStream(String) //一般用第二种,方便点
3.5.1 FileInputStream的成员方法
(1)public int read() 每次读取一个字节并 返回读取一个字节所对应的编码
(2)public int read(byte[] b) :每次读取数组的长度个字节,返回读回来的长度(实际读取的内容)
第二个成员方法返回的是buffer(缓存区) b的长度
1 public class FileInputStreamDemo {
2 public static void main(String[] args) {
3 try(
4 FileInputStream fis = new FileInputStream("d:/a.txt"); //啊的内容为 ab
5 ){
6 System.out.println(fis.read()); //97
7 System.out.println(fis.read());//98
8 System.out.println(fis.read());//-1 可见当没内容可读取的时候,返回的是-1
9 } catch (Exception e) {
10 e.printStackTrace();
11 }
12 }
13 }
若将a.txt的内容改为abc大,那么这个中文字“大”怎么读取出来呢?,代码如下
在上面第8行代码后加如下代码
1 int d = fis.read();
2 int e = fis.read();
3 int f = fis.read();
4 // 创建一个Bytes数组,将上面三个字节平成一个byte数组
5 byte[] bs = new byte[] {(byte)d,(byte)e,(byte)f};
6 System.out.println(bs);//[B@279f2327
7 System.out.println(new String(bs));//大
这样一个字节一个字节读取很费经,可以直接1kb的读取,要想1字节的话可以用for循环读取,循环控制条件就是读取数据返回值为-1
若a文件内容还是为”abc大",这次换成一次性读取1kb,代码如下
public class FileInputStreamDemo {
public static void main(String[] args) {
try(
FileInputStream fis = new FileInputStream("d:/a.txt"); //啊的内容为 ab
){
System.out.println(fis.read()); //97
System.out.println(fis.read());//98
System.out.println(fis.read());//99
byte[] bs1 = new byte[1024]; //数组在每个位置的默认值为0,转为字符串就是空格
fis.read(bs1);
System.out.println(new String(bs1)); //将byte数组转为字符串打印出来
System.out.println(new String(bs1).length());//1022 字符串的长度,说明其将空格也读取出来了
} catch (Exception e) {
e.printStackTrace();
}
}
}
字符串长度为1022的由来:空格长度为1024-3=1021,一个汉字(大)长度为1,所以字符串长度为1022+1=1023
怎样让其读取的内容为实际的长度呢?======>让第二个成员方法接收返回值,其返回的是真实的长度
如将上面代码fis.read(bs1)改为System.out.println(fis.read(bs1)),打印的结果为3,可见返回的是真实读取的字节数
下例中把文件的内容为:没有人在热河里谈恋爱
public class FileInputStreamDemo1 {
public static void main(String[] args) {
try(
FileInputStream fis = new FileInputStream("d:/b.txt"); //啊的内容为 ab
){
byte[] bs1 = new byte[1024];
int len;
while((len = fis.read(bs1))!=-1) {
System.out.println(new String(bs1,0,len));//没有人在热河里谈恋爱
System.out.println(new String(bs1,0,len).length());//10
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
由结果可知,读取的内容是实际的长度,并不会将空格也读出来
拷贝文件,比如将"E:/exercise/haha/天空之城.jpg"拷贝到"E:/exercise/haha/热河.jpg"
public class CopyFile {
public static void main(String[] args) {
try(
FileInputStream fis = new FileInputStream("E:/exercise/haha/天空之城.jpg");
FileOutputStream fos = new FileOutputStream("E:/exercise/haha/热河.jpg");
) {
byte[] bs = new byte[1024];
int len;
while((len = fis.read(bs)) != -1) { //读取数据,当返回值为-1时,表示读取完毕
fos.write(bs,0,len); //写入
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
零基础学习java------day16-----文件,递归,IO流(字节流读写数据)的更多相关文章
- 总结了零基础学习Java编程语言的几个基础知识要点
很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面 初学者先弄清这 ...
- 音乐出身的妹纸,零基础学习JAVA靠谱么
问:表示音乐出身的妹纸一枚 某一天突然觉得身边认识的是一群程序员 突然想 要不要也去试试... 众好友都觉得我该去做个老师,可是我怕我会误人子弟,祸害祖国下一代..... 要不要 要不要 学Ja ...
- salesforce 零基础学习(六十三)Comparable实现Object列表数据的自定义排序
项目中通常有些需求为需要将某个sObject的数据列表按照某种规则排序显示到前台页面上,但是list上面的sort远远满足不了复杂的功能,此种情况需要自定义比较两个object大小的方法,所以需要创建 ...
- IDEA + maven 零基础构建 java agent 项目
200316-IDEA + maven 零基础构建 java agent 项目 Java Agent(java 探针)虽说在 jdk1.5 之后就有了,但是对于绝大多数的业务开发 javaer 来说, ...
- 零基础学Java第三节(基本输入输出)
本篇文章是<零基础学Java>专栏的第三篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] Java程序的命令行参数 我们可以 ...
- 零基础学习hadoop到上手工作线路指导
零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...
- 零基础学习Hadoop
零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...
- 零基础学习hadoop到上手工作线路指导(编程篇)
问题导读: 1.hadoop编程需要哪些基础? 2.hadoop编程需要注意哪些问题? 3.如何创建mapreduce程序及其包含几部分? 4.如何远程连接eclipse,可能会遇到什么问题? 5.如 ...
- 零基础学习hadoop到上手工作线路指导(中级篇)
此篇是在零基础学习hadoop到上手工作线路指导(初级篇)的基础,一个继续总结. 五一假期:在写点内容,也算是总结.上面我们会了基本的编程,我们需要对hadoop有一个更深的理解: hadoop分为h ...
随机推荐
- C++类的静态成员变量与静态成员函数
1.类的静态成员变量 C++类的静态成员变量主要有以下特性: 1.静态成员变量需要类内定义,类外初始化 2.静态成员变量不依赖于类,静态成员变量属于全局区,不属于类的空间. 3.静态成员变量通过类名访 ...
- log4j日志集成
一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Syslog ...
- 用 Python 修改微信(支付宝)运动步数,轻松 TOP1
用 Python 修改微信(支付宝)运动步数,轻松 TOP1 项目意义 如果你想在支付宝蚂蚁森林收集很多能量种树,为环境绿化出一份力量,又或者是想每天称霸微信运动排行榜装逼,却不想出门走路,那么该py ...
- LeetCode-40. 组合总和 II C++(回溯法)
回溯法本身是种暴力解法,虽然效率之类的比较低,但是写起来比较易懂和快.在提交之后的排名也挺低的,大概就超过8%左右.以后复习的时候再去看看题解,看看更高性能的算法.这里先暂时贴上回溯法的代码. 最后说 ...
- NOIP模拟92&93(多校26&27)
前言 由于太菜了,多校26 只改出来了 T1 ,于是直接并在一起写啦~~~. T0 NOIP 2018 解题思路 第一次考场上面写三分,然而我并不知道三分无法处理不是严格单峰的情况,但凡有一个平台都不 ...
- SpringCloud远程服务调用
笔记 在微服务中,若想要使用远程调用,需要引入spring-cloud-starter-openfeign(在使用注册中心的环境下) <dependency> <groupId> ...
- Matplotlib(嵩老师.)
Matplotlib 库的使用 Matplotlib 库有各种可视化类构成,内部结构复杂,受Matlab启发 matplotlib.pyplot是绘制个类可视化图形的命令子库相当于快捷方式 imp ...
- [loj2135]幻想乡战略游戏
以1为根建树,令$D_{i}$为$i$子树内所有节点$d_{i}$之和 令$ans_{i}$为节点$i$的答案,令$fa$为$i$的父亲,则$ans_{i}=ans_{fa}+dis(i,fa)(D_ ...
- [bzoj1303]中位数图
由于是排列,因此b一定只出现了一次,找到出现的位置并向左右扩展考虑如何判定是否满足条件,当且仅当$[左边比b小的数ls]+[右边比b小的数rs]=[左边比b大的数lb]+[右边比b大的数rb]$,暴力 ...
- [loj3368]数蘑菇
由于题目是让我们统计个数,当我们确定了$k$个$p_{i}$都为0或1后,再用至多$\lceil \frac{n-k}{k}\rceil$次询问和$2(n-k)$个"$n$"即可求 ...