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();
}
}
}

最新文章

  1. camstar --设备保养
  2. Java SE、Java EE、Java ME
  3. hdu2896 病毒侵袭 ac自动机
  4. 微软Azure开始支持Docker技术
  5. usaco4.12Fence Rails(迭代加深)
  6. (poj)1679 The Unique MST 求最小生成树是否唯一 (求次小生成树与最小生成树是否一样)
  7. Java ArrayIndexOutOfBoundsException: Exception Hierarchy
  8. asp.net core源码地址
  9. Unity编辑器:基于NGUI的引用检测工具
  10. 《剑指offer》二叉树中和为某一值的路径
  11. es6中的Promise学习
  12. Android学习之基础知识四-Activity活动8讲(活动的灵活运用)
  13. Scriter CSS
  14. HTML 标记 1
  15. [原创]浅谈H5页面测试介绍
  16. 关于pcie的备忘
  17. gitlab改变服务器ip
  18. imx6 android5.1 编译
  19. MUI框架-14-使用自定义icon图标、引入阿里巴巴矢量图标
  20. L147 Low Cost Study Has High Impact Results For Premature Babies

热门文章

  1. Shadertoy 教程 Part 4 - 绘制多个2D图形和混入
  2. 策略路由——使用Router-Policy策略路由进行路由协议的引入
  3. ELK集群之elasticsearch(3)
  4. msfsploit框架的使用——ms17_010漏洞的利用
  5. JavaScript 对象:String & Array 及其常见应用
  6. Windows内核中的CPU架构-7-陷阱门(32-Bit Trap Gate)
  7. java更开源-安全可靠国产系统背景下的应有.NET Core的一席之地
  8. linux安全 设置登录失败次数后,拒绝登录
  9. [atARC062F]Painting Graphs with AtCoDeer
  10. [atAGC022D]Shopping