第十八天总结:
1.转换流:
InputStreamReader字节流变字符流
OutPutStreamWriter字符流变字节流,这两个流都属于字符流!
操作流的基本规律:
a.明确源和目的,这是为了明确使用输入流还是输出流
b.明确操作的数据是不是文本数据,这是为了明确使用字符流还是字节
流
转换流自身是挂着码表的
FileReader继承了InputStreamReader,一次读两个字节,然后查表去
了,所以他也挂了码表,所以能直接读中文,字符流就没法操作非文本
文件。
FileWriter继承了OutputStreamReader
如果处理的是纯文本,并涉及到编码转换,就要使用转换流!
感悟:
a拿copy做为例子,如果我们要把一个纯文本拷贝到硬盘的另外一个地
方,则只要只用字符流:FileReader和FileWriter
b如果要把一个图片拷贝到硬盘的另外一个地方,则只要使用字节
流:FileInputStreamhe FileOutputStream.
c如果要把用键盘输入的文字存储到某个文件中,则需要用到转换流,
因为键盘输入的都是字节,而存到文件中的是字符。
________________________________________________________
2.异常日志
import java.io.*;
import java.util.*;
import java.text.*;
class ThrowableLog
{
public static void main(String[] args)
{
try
{
int x=4/0;
int[] arr=new int[2];
System.out.println(arr[2]);//这里是故
意制造几个异常信息
}
catch (Exception e)
{
Date d=new Date();//建立日期对象
SimpleDateFormat sdf=new
SimpleDateFormat("yyyy年mm月dd日 hh:mm:ss");
//建立text包中的SimpleDateFormat对象,
设置要输出的时间的格式
String s_date=sdf.format(d);//调用sdf
对象中的format方法输出该格式下的时间d
PrintStream out=null;//从这里开始到下
面都是在通过流把异常信息存入到对应的log文件
try
{
out=new PrintStream(new
FileOutputStream("log.txt",true));//不覆盖的打印
//FileOutputStream是
OutptuSteadm的子类对象,他可以传递给PreamStream的构造函数
//PrintStream是打印流,上面的
构造是让他把数据打印到指定的txt文件中
out.println(s_date);//println
是PrintStream的一个方法,打印内容并终止该行
e.printStackTrace(out);//把异
常信息输出到指定的流,这是异常类中的方法
}
catch (IOException ex)//这是在建立流的
时候所抛出的异常
{
System.out.println("无法建立日
志文件:"+ex.toString());
}
finally
{
if(out!=null)
out.close
();//PrintStream流的关闭方法不抛异常。
}
}
}
}
________________________________________________________
3.properties集合
properties是和流相结合的集合。一般用他来读ini文件。
________________________________________________________
4.File类
这个类是文件和目录路径名的抽象表现形式,这个抽象是指把现实生活
中的事物抽象了。
File弥补了流的不足,他不存在覆盖,流是存在覆盖的
流只能操作文件中数据,不能操作文件的属性信息
而File类专门操作文件或者文件夹的属性信息的
流对象的构造函数是可以接受一个File对象的
File file=new File("file.txt");//File类可以封装存在的文件,也
可以风封装不存在的
if(file.exists())//判断该流是否存在
FileReader=new FileReader(file);//流可以接受
file对象
file.deleteOnExit();//这个删除动作只有在JVM退
出的时候才会删除,所有方法运行完毕
boolean b=file.createNewFile();//创建文件。创
建这个动作被成功执行的话会返回true
System.out.println(b);
boolean c=file.delete();//只有删除这个动作成功
执行了才返回真,
System.out.println(c);
file.getAbsolutePath();//用字符串形式返回该文
件或文件夹的绝对路径,比如F:/java32/0413/file.txt
file.getPath();//用字符串形式返回该文件或文件
夹的相对路径,如file.txt(和你在File中封装的路径一样)
file.getParet();//用字符串形式返回该文件或文件
夹的父目录,前提是File中封装的是绝对路径
file.lastModified();//返回此路径名表示的文件最
后一次被修改的时间
file.mkdir();//创建一个文件夹,创建成功才返回
真,如c://a就是在c盘床架a文件夹
file.mkdirs();//创建过个文件夹。比如封装的是
C://a//b就是先在C盘创建a文件夹,在在a里创建b文件夹
//在创建文件的时候必须要有扩展名,而文件夹的时
候不要扩展名
file.isDirectory();//判断是不是文件夹
file.isFile();//判断是不是文件
//在创建文件和文件夹的时候一定要先判断是不是存
在和是不是文件夹或文件
//if(file.exists()&&file.isDirectory())
File[] roots=File.listRoots();//返回的是机器上
的有效盘符,和对象没关系,可以直接类名调用
for (File root:roots )
{
System.out.println(root);
}
File f=new File("C://","a.txt")//这里是把父目
录和文件名分开了,这样方便粗啊哦做
//File中也可以只封装一个目录
File f=new File(File filefu,"a.txt");//这里是
先封装父目录,在穿到问价的File类中
//File.separator是在任何平台下都表示该平台的目
录分隔符,在win里就表示/
File f=new File("c:"+File.separator+"a.txt");
String[] arr=file.list();//list方法返回的是一
个字符串数组
//该方法列的是当前路径下所有文件和文件夹的名称
,如果File中封装的是一个文件路径,则该
//方法得到的是null值,因为他下层没有东西了,所
以只有当封装的是对象存在且是一个文件夹路径
________________________________________________________
5.过滤器
FilenameFilter
/*
过滤器的原理:
1,首先调用list,拿到了目录下的所有文件和文件夹的名称,在遍历这
些文件
2.在定义一个临时容器,在同一if判断accept方法中的条件
3.只要满足该条件,就把满足条件的名称存到该临时容器,
4.当判断结束后,就把该临时容易转化成字符串数组返回出来
*/
import java.io.*;
import java.util.*;
interface MyFilenameFilterx//定义一个接口,强制用户复写该接口
当中的myAccept方法
{
public boolean myAccept(File dir,String name);
}
class MyFilex
{
private File dir;
MyFilex(File dir)
{
this.dir=dir;
}
//构造一个方法,类似于list(FilenameFileter filter)方法
实现功能
public String[] myList(MyFilenameFilterx filter)
{
String[] arr=dir.list();
ArrayList<String> list=new ArrayList<String>
();//临时存储容器
for (int x=0;x<arr.length ;x++ )
{
if(filter.myAccept(dir,arr[x]))
list.add(arr[x]);
}
return list.toArray(new String[list.size()]);
}
}
class MyFileDemox
{
public static void main(String[] args)
{
File file=new File(".");
MyFilex mf=new MyFilex(file);
String[] str=mf.myList(new MyFilenameFilterx
()//跟Comparator的形式类似
{
public boolean myAccept(File
file,String name)
{
return new File(name).isFile()
&& name.endsWith(".java");
//先判断该名称是否是一个文件
}
});
for (String s:str)
{
System.out.println(s);
}
}
}
________________________________________________________
6.递归
函数自己调用自己,一定要有结束的条件
public void toBin(int num)-----4
{
if(num>0)-----1
{
toBin(num/2);------2
System.out.println(num%2);------3
}
}
上面程序就是一个简单的递归,假设传一个num=4,则流程分析如下:
a>当num=4传进该函数后,读到1,判断为真读到2,因为又调用了该函
数,所以得到num=2返回继续调用4
b>这个时候num=2被传到该函数,读到1,判断为真读到2,同上句所描
述的,得到num=1,返回继续调用4
c>当num=1被传到该函数,的到1,判断为真读到2,1/2得到结果为0,
则num=0返回继续读4
d>当num=0被传到该函数,读到1,判断结果为假,d结束,
e>此时该c中的方法则读到3,输出1%2得到1,c结束
f>c结束后,b开始读到3,输出2%2得到0,b结束
g>b结束后,a开始读到3,输出4%2得到0.a结束
h>到此程序运行结束,得到结果为100
在递归使用的时候,一定要注意控制条件,就相当上面程序中的1句,
If(num>0),如果没有这个条件,程序就不会停下来,直到内存溢出。
因为在递归的过程中,没递归一次,则会新建一个参数变量,所以条件
一定要控制好,防治内存溢出