---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
IO流 一
1:File
(1)File:因为数据在硬盘上最常见的方式,就是文件。而文件本身有很多的属性,比如说:文件大小,是否可读啊,
是否隐藏啊。那么,java为了方便我们对文件进行操作,就提供了File类供我们使用。
File既可以表示文件,也可以表示文件夹。(目录)
(2)构造方法
A:File(String pathname):根据指定的路径创建File对象。
B: File(String parent, String child):根据指定的父文件夹和子文件或者文件夹创建File对象
C: File(File parent, String child):根据指定的父文件夹对象和子文件或者文件夹创建File对象
(3)成员方法
A:创建功能
创建文件:public boolean createNewFile()
如果指定的文件不存在,就创建。如果存在,就不创建。
创建文件夹:public boolean mkdir()
创建指定的目录,如果存在,就不创建。
创建多级文件夹:public boolean mkdirs()
创建指定的目录,如果存储,就不创建。这个时候,如果父目录不存在,它也会自动创建。
注意:
你要创建什么,自己最清楚。也就是,你要调用哪个方法,你自己必须明白。
因为如果你不明白,就会有问题。
什么问题呢?骑白马的不一定是王子。
可能你想创建一个123.txt的文本文件,但是你用了mkdir方法就会创建一个123.txt的文件夹,
而你还可能以为自己创建好了
绝对路径:以盘符开始的路径。
相对路径:不以盘符开始的路径。
B:删除功能
public boolean delete():既可以删除文件,也可以删除文件夹。取决于你使用的对象。
注意:
A:如果你删除的目录下还有内容,那么,必须先把所有内容删除完毕后,在删除目录。
B:java语言的删除不走回收站。
C:判断功能
boolean exists():判断file对象是否存在
boolean isFile():判断file对象是否是文件
boolean isDirectory():判断file对象是否是文件夹
boolean isAbsolute():判断file对象是否是绝对路径
boolean canRead():判断file对象是否可读
boolean canWrite():判断file对象是否可写
boolean isHidden():判断file对象是否隐藏
D:获取功能:
String getAbsolutePath():绝对路径
String getPath():相对路径
String getName():文件名称
long length():文件大小,单位是字节
long lastModified():上次修改时间的毫秒值。
public static File[] listRoots():列出可用的系统文件根目录
public String[] list():返回的是指定目录下所有文件或者文件夹的名称数组
public File[] listFiles():返回的是指定目录下所有文件或者文件夹对象数组
//案例:获取指定目录下所有.mp4文件的名称
// 思路:
// A:封装指定目录
// B:获取指定目录下所有文件或者文件夹File数组
// C:遍历File数组,获取得到每一个File对象
// D:判断该对象是否是否文件
// E:判断该对象的后缀名是否是.mp4,是否以.mp4结尾。
// 封装指定目录
File f = new File("d:\\");
// 获取指定目录下所有文件或者文件夹File数组
File[] fileArray = f.listFiles();
// 遍历File数组,获取得到每一个File对象
for (File file : fileArray) {
// 判断该对象是否是否文件
if (file.isFile()) {
// 判断该对象的后缀名是否是.mp4,是否以.mp4结尾。
String name = file.getName();
if (name.endsWith(".mp4")) {
System.out.println(name);
}
}
}
2:递归
(1)方法定义中调用方法本身的现象。
举例:老和尚给小和尚讲故事,我们学编程。
(2)递归的注意事项:
A:一定要有出口,否则死递归。
B:次数不能过多,否则内存溢出。
构造方法不能递归调用。
(3)案例:(面试)
A:递归求阶乘
/*
* 递归求阶乘:
* 出口:1!=1
* 规律:n!=n*(n-1)!
*/
public class DiGuiDemo2 {
public static void main(String[] args) {
int num = 5;
System.out.println(jc(num));
}
/*
* 返回值:int 参数:int n 如果jc(n)表达的是n的阶乘的话, 请问,n-1的阶乘如何表示? jc(n-1)
*/
public static int jc(int n) {
if (n == 1) {
// 出口
return 1;
} else {
// 规律
return n * jc(n - 1);
}
}
}
B:递归求数列第二十项
/*
* 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?
* 分析:
* 对数
* 第一个月 1
* 第二个月 1
* 第三个月 2
* 第四个月 3
* 第五个月 5
* 通过分析我们得到这样的一个数列
* 1,1,2,3,5,8,13,21,...
* 找什么?
* 出口:第一项和第二项是已知的。
* 规律:从第三项开始,每一项是前两项之和。
*/
public class DiGuiDemo3 {
public static void main(String[] args) {
System.out.println(fun(20));
}
/*
* 返回值类型:int 参数列:int n 假设fun(n)表示第n个月的兔子对数。 请问,第n-1和第n-2个月的兔子分别是多少对?
* fun(n-1) fun(n-2)
*/
public static int fun(int n) {
// if (n == 1) {
// return 1;
// } else if (n == 2) {
// return 1;
// } else {
// return fun(n - 1) + fun(n - 2);
// }
if (n == 1 || n == 2) {
return 1;
} else {
return fun(n - 1) + fun(n - 2);
}
}
}
C:递归遍历指定目录的文件绝对路径
/*
* 需求:在控制台输出 D:\itcast\20131130 所有的java文件的绝对路径。
*
* 思路:
* A:封装目录 D:\itcast\20131130
* B:获取该目录下的所有文件或者文件夹的File[]数组。
* C:遍历File[]数组,获取到每一个File对象
* D:判断该File对数是否是
* 目录:返回B。(递归)
* 不是目录:
* 判断是否java结尾。
* 是:输出路径。
*/
public class ShowFileName {
public static void main(String[] args) {
// 封装目录 D:\itcast\20131130
File file = new File("D:\\itcast\\20131130");
showFiles(file);
}
private static void showFiles(File file) {
// 获取该目录下的所有文件或者文件夹的File[]数组。
File[] fileArray = file.listFiles();
// 遍历File[]数组,获取到每一个File对象
for (File f : fileArray) {
// 判断该File对数是否是目录
if (f.isDirectory()) {
showFiles(f);
} else {
// 文件
if (f.getName().endsWith(".java")) {
System.out.println(f.getAbsolutePath());
}
}
}
}
}
D:递归删除带内容的目录
/*
* 需求:删除指定的目录。(目录是带有目录或者文件的)
* 思路:
* A:封装目录
* B:获取该目录下的所有文件或者文件夹的File[]数组。
* C:遍历File[]数组,获取到每一个File对象
* D:判断该File对象是否是
* 目录:返回B。(递归)
* 不是目录:
* 删除文件
* 作业:用断点看删除目录或者文件的过程。
*/
public class DeleteFile {
public static void main(String[] args) {
File file = new File("test");
deleteFiles(file);
}
private static void deleteFiles(File file) {
File[] fileArray = file.listFiles();
if (fileArray != null) {
for (File f : fileArray) {
if (f.isDirectory()) {
deleteFiles(f);
} else {
System.out.println(f.getName() + "***" + f.delete());
}
}
// 如果for循环结束,就表示目录下的文件被删除完毕。
System.out.println(file.getName() + "***" + file.delete());
}
}
}
3:IO流
(1)IO流的分类:
A:字节流
字节输入流 InputStream
字节输出流 OutputStream
B:字符流
字符输入流 Reader
字符输出流 Writer
(2)FileWriter写入数据
步骤:
A:创建字符输出流对象
B:调用写入数据方法,并刷新缓冲区
C:释放资源
代码体现:
FileWriter fw = new FileWriter("a.txt");
fw.write("hello,io");
fw.flush();
fw.close();
问题?
A:创建字符输出流对象做了几件事情?
1.调用系统功能创建了文件
2.创建字符输出流对象
3.把字符输出流对象指向创建的文件
B:写数据完毕后,为什么要刷新?
字符流 1字符 = 2字节 文件数据底层单位是字节,而我们现在是字符,
所以它不能直接把数据写入文件。 把字符输出存储到缓冲区里面。刷新
就存储到文件里了。
C:为什么要close()?
1:让流对象变成垃圾。
2:通知系统去释放和文件相关的资源。
D:flush()和close()的区别?
flush():只刷新缓冲区,流对象还可以继续使用。
close():先刷新缓冲区,在关闭流对象。流对象不可以继续被使用。
E:怎么实现数据换行?
不同的操作系统,对换行符的要求不一样:
windows:\r\n
linux:\n
mac:\r
而有些软件,在制作的时候,为了通用,对任何换行符都是可以识别的。
F:怎么实现数据追加写入?
构造的时候,用带两个参数的。如果第二个参数是true就是追加的。
public FileWriter(String fileName,boolean append)
(3)FileReader读取数据
步骤:
A:创建字符输入流对象
B:调用读取数据方法,并显示
C:释放资源
代码体现:
FileReader fr = new FileReader("a.txt");
//方式1
//一次读取一个字符
int ch = 0;
while((ch=fr.read())!=-1)
{
System.out.print((char)ch);
}
//方式2
//一次读取一个字符数组
char[] chs = new char[1024];
int len = 0;
while((len=fr.read(chs))!=-1)
{
System.out.print(new String(chs,0,len));
}
fr.close();
(4)案例:
复制文本文件。
/*
* 需求:我要把项目路径下的FileWriterDemo.java复制到d:\\Copy.java中
*
* 数据源:
* 读取数据:
* FileWriterDemo.java -- Reader -- FileReader
*
* 目的地:
* 写入数据:
* d:\\Copy.java -- Writer -- FileWriter
*/
public class CopyFile {
public static void main(String[] args) throws IOException {
// 封装数据源
FileReader fr = new FileReader("FileWriterDemo.java");
// 封装目的地
FileWriter fw = new FileWriter("d:\\Copy.java");
// 读取数据
// int ch = 0;
// while ((ch = fr.read()) != -1) {
// fw.write(ch);
// // fw.flush();
// }
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs,0,len);
}
// 释放资源
fw.close();
fr.close();
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------