@w460461339
2016-11-16T07:08:05.000000Z
字数 3892
阅读 881
Java基础
妈蛋,终于搞完开题报告了,可以愉快的重新开始Java的学习(当然还要兼顾毕设了…哭)
今天主要学习的是递归和IO流。
递归就结合File来说吧。分别为递归的获取某目录下所有以jpg结尾的文件(包含子目录中的)以及递归的删除。
递归规则:
递归要有出口(出口条件)
递归次数不能太多
构造方法不能递归使用
递归编程:
要明确规律,将问题分解为有层次感的小问题,每层的问题都可以用相同的策略解决。
这就是数列里面的S(n+1)=F(S(n))的思想。
或者简单点,分解+合并。
import java.io.File;
public class DiguiDemo {
public static void main(String[] args) {
File myFile=new File("demo");
readAllJPG(myFile);
}
public static void readAllJPG(File myFile){
File[] fileArray=myFile.listFiles();
for(File fl:fileArray){
if(fl.isDirectory()){//判断是否是文件夹
readAllJPG(fl);
}else{//终止条件
//获取文件名字,判断字符串是否以.jpg结尾
if(fl.getName().endsWith(".jpg")){
//打印绝对路径
System.out.println(fl.getAbsolutePath());
}
}
}
}
}
import java.io.File;
public class DiguiDemo {
public static void main(String[] args) {
File myFile=new File("demo");
deleteAll(myFile);
}
public static void deleteAll(File myFile){
File[] fileArray=myFile.listFiles();
if(fileArray!=null){//防止空指针异常
for(File fl:fileArray){
if(fl.isDirectory()){//文件夹就继续进入
deleteAll(fl);
}
else{//文件就删
System.out.println(fl.getName()+"--"+fl.delete());
}
}
}
//最后删除当前文件(记得操作的时候不要打开该文件,不会因为被占用而删不掉)
System.out.println(myFile.getName()+"--"+myFile.delete());
}
IO流按流向分可以分为: 输入 输出
按照类型分有:
字节流:输入 输出
字符流:输入 输出
注意:
a:如果我们没有明确说明按照什么分,默认按照数据类型分。
b:除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。
下面仅以字节流演示
a 创建字节输出流对象
b 调用write方法
c 关闭
package myIOstream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyIOStream {
public static void main(String[] args) throws IOException {
//构造方法:直接传入文件的抽象路径也行
//FileOutputStream fos=new FileOutputStream(new File("aa.txt"));
//像楼上这样封装成File对象再传入也行
//另外,若原本没有aa.txt,该构造函数会自动创建
FileOutputStream fos=new FileOutputStream("aa.txt");
//同时,该构造方法会有编译异常,直接抛出就好
fos.write("hello".getBytes());
fos.close();//千万注意关闭
}
}
多次运行会发现,aa.txt中只有一个hello,不会增加。那怎么才能每一次run之后增加呢?
//trur表示每次从当前文档末尾添加,false表示从头覆盖
FileOutputStream fos=new FileOutputStream("aa.txt",true);
有两种方法
Way1:一个字节一个字节读。效率太低。
import java.io.FileInputStream;
import java.io.IOException;
public class myInput {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("aa.txt");
int by=0;
//read()返回字节的int表示。读到文档末尾返回-1
while((by=fis.read())!=-1){
System.out.print((char)by);
}
}
}
Way2:一个字节数组一个字节数组的读。
import java.io.FileInputStream;
import java.io.IOException;
public class myInput {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("aa.txt");
byte[] by=new byte[1024];//最好是1024或者其倍数
int len=0;//len用来记录每次读取的字节数
//此时read(byte[] by)返回读入了多少个字节
while((len=fis.read(by))!=-1){
//一定要用len这种方式。
System.out.println(new String(by,0,len));
}
}
}
BufferedInputStream以及BufferedOutputStream都是高速的读写IO流。之所以高速,是因为其内部利用缓存,每次积累一定量的数据后再对底层进行操作。下面两个一起演示。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MybufferedIO {
/**
* 源数据:
* 当前目录下aa.txt
* 目标数据:
* D盘根目录下bb.txt
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//创建读 写对象
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream("aa.txt"));
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream("D:\\bb.txt",true));
byte[] by=new byte[1024];
int len=0;
while((len=bis.read(by))!=-1){
System.out.println(new String(by,0,len));
bos.write(by, 0, len);
//不同系统换行标识符不同,尽量把\r\n都写上
bos.write("\r\n".getBytes());
}
bos.close();//一定要记得关
bis.close();
}
}
这里演示了BufferedInputStream以及BufferedOutputStream的用法以及如何进行数据的复制。其中BufferedInputStream和BufferedOutputStream的构造函数可以指定缓冲区大小,但一般都用默认的。
另外的对图像和对视频文件的复制这里不演示了。
a:创建字节输出流对象做了几件事情?
三件事:
1、若文件不存在,调用系统功能在指定位置创建文件
2、创建字节输出流对象
3、将字节输出流对象指向该文件。
b:为什么要close()?
1、将字节输出/出路流对象变为垃圾,方便回收资源
2、释放与此流有关的系统资源。
c:如何实现数据的换行?
不同系统换行不同,把\r\n都写了保险点。
d:如何实现数据的追加写入?
FileOutputStream的构造函数之一为:
FileOutputStream(String name, boolean append)或者
FileOutputStream(File file, boolean append)
后面的boolean变量为true,表示从文档尾部添加,实现追加写入。不写或者false,则从文档头部实现覆盖写入。
e:中文字符识别
中文字符由两个字节组成,第一个字节一定为负数,通过识别负数即可知道是否需要将后续字节拼起来,成为一个完整的字。