File类
1.File类
文件和目录路径名的抽象表示。
2.路径
绝对路径:带盘符的路径.
相对路径:相对某个文件或目录来描述的路径.
当相对的文件或目录与当前描述的文件或目录不在同一个盘符下时,绝对路径=相对路径.
在大部分情况情况下, 绝对路径!=相对路径.
3.file类常用方法:
public static void main(String[] args) {
//创建一个文件对象
//File f=new File("d:\\a.txt");
File f=new File("d:"+File.separator+"a.txt");
System.out.println("文件绝对路径:"+f.getAbsolutePath());
System.out.println("文件相对路径:"+f.getPath());
System.out.println("文件名:"+f.getName());
System.out.println("文件是否可读:"+f.canRead());
System.out.println("文件是否可写:"+f.canWrite());
System.out.println("文件是否隐藏:"+f.isHidden());
System.out.println("文件长度:"+f.length());
long d1=f.lastModified();
//将日期格式化
String d2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d1);
System.out.println("文件最后一次修改日期:"+d2);
}
4.递归
方法自身调用自身.
- 1:可以将原问题拆分成若干子问题,子问题的解决方法与原问题的解决方法一样.
- 2:原问题的解决依赖于所有子问题的解决.
- 3:递归一定要有出口.
/**
* file类常用方法
* (1)输出当前文件夹下所有以.txt结尾的子文件
* (2)输出当前文件夹及后代文件夹中,所有以.txt结尾的子文件
*/
public class FileTest5 {
public static void main(String[] args) throws IOException {
//创建一个文件对象
File f=new File("aa");
if (f.isDirectory()) {//文件夹
isDictory(f);
} else {
System.out.println("当前对象不是文件夹,无子文件");
}
}
/**
* 判断当前文件夹下是否有以.txt结尾的文件,有就输出
*/
public static void isDictory(File f) {
//获得当前文件夹下所有子文件和子目录
File[] childFiles=f.listFiles();
//遍历所有子文件和子目录
for (File f2 : childFiles) {
//判断当前遍历的对象是否是文件,且是否是以.txt结尾,输出
if (f2.isFile()&&f2.getName().endsWith(".txt")) {
System.out.println(f2.getPath());
} else if(f2.isDirectory()){//当前对象是文件夹
//递归,判断当前遍历的文件夹下面还有没有以.txt结尾文件
isDictory(f2) ;
}
}
}
}
5.过滤器
将需要数据留下来,不需要数据过滤掉.
public static void main(String[] args) throws IOException {
//创建一个文件对象
File f=new File("aa");
//判断当前对象是否是文件夹
if (f.isDirectory()) {
//获得当前目录下以.txt结尾子文件,方法了匿名内部类过滤器对象
String[] childFiles=f.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//根据父目录对象和子文件名,创建子文件对象
File child=new File(dir, name);
//判断当前的文件对象是否是文件,是否以.txt结尾
if (child.isFile()&&name.endsWith(".txt")) {
return true;
}
return false;
}
});
for (String f2 : childFiles) {
System.out.println(f2);
}
} else {
System.out.println("当前的对象不是目录,没有子文件");
}
}
流
1.IO流
将数据从一个地方传输到另一个地方.
2.流的分类:
-
1:按方向分:相对程序角度来说.
输入流(读取流):将文件中数据读取到程序中.
注意: 所有输入流,当文件不存在时,直接抛异常.
输出流(写入流):将程序中数据写入到文件中.注意:所有输出流,当文件存在时,直接向文 件中写入数据;当文件不存在,先创建文件,再向文件中写入内容. -
2:按单位分:
字节流:按字节为单位传输数据.作用:处理部分文本文件,图片,视频,二进制文件.
字符流:按字符为单位传输数据.作用:处理所有文本文件. -
3:按功能分
节点流:原始的流,没有封装任何其他流.
处理流:封装节点流.
3.装饰者模式
封装原有类使其功能更强大.
4.基本字节流(原始字节流)
4.1:字节输入流
InputStream->FileInputStream
- 1:一个字节一个字节的读取
public static void main(String[] args) throws IOException {
//声明流对象
InputStream is=null;
try {
//1.创建流对象
is=new FileInputStream("aa"+File.separator+"a1.txt");
/*2.用流对象一个字节一个字节的读取内容*/
//先读取一次,返回就是读取的一个字节的Ansi码
int content=is.read();
while (content!=-1) {
//将读取的内容输出
System.out.println((char)content);
//接着读取
content=is.read();
}
System.out.println("读取完成!");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (is!=null) {
is.close();
}
}
}
- 2:按字节数组的读取
public static void main(String[] args) throws IOException {
//声明流对象
InputStream is=null;
try {
//1.创建流对象
is=new FileInputStream("aa"+File.separator+"a1.txt");
/*2.用流对象一个字节一个字节的读取内容*/
//准备一个字节数组读取
byte[] b=new byte[10];
//先按数组读取一次,读取的内容存在数组b中,返回读取的长度
int len=is.read(b);
while (len!=-1) {
//将读取的内容输出
System.out.println(new String(b, 0, len));
//接着读取
len=is.read(b);
}
System.out.println("读取完成!");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (is!=null) {
is.close();
}
}
}
4.2:字节输出流
OutputStream->FileOutputStream
public static void main(String[] args) throws IOException {
//声明流对象
FileOutputStream os=null;
try {
//1.创建流对象,先将文件中内容清空,再向文件中重写写入内容
//os=new FileOutputStream("aa"+File.separator+"a1.txt");
//加了第二个参数后,表示在原文件末尾追加数据
os=new FileOutputStream("aa"+File.separator+"a1.txt",true);
//2.用流对象向文件中写入内容
os.write("Hello china".getBytes());
os.write("我是中国人".getBytes());
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流,释放资源
if (os!=null) {
os.close();
}
}
}
4.3:文件的拷贝
public static void main(String[] args) throws IOException {
//声明流对象
InputStream is=null;
OutputStream os=null;
try {
//1.创建流对象
is=new FileInputStream("aa"+File.separator+"a1.txt");
//复制后的文件要与原文件后缀名相同(文件类型相同),文件名可以不同
os=new FileOutputStream("bb"+File.separator+"b1.txt");
/*2.用流边读取边写入*/
//准备一个数组
byte[] b=new byte[20];
//先读取一次,读取的内容存在数组中,返回读取的实际长度
int len=is.read(b);
while (len!=-1) {
//每读取一次就要写入一次
os.write(b, 0, len);
//接着读取
len=is.read(b);
}
System.out.println("拷贝成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (is!=null) {
is.close();
}
if (os!=null) {
os.close();
}
}
}
5.字节缓冲流
处理流封装原始字节流
5.1:字节缓冲输入流
FilterInputStream->BufferedInputStream
public static void main(String[] args) throws IOException {
//声明流对象
FilterInputStream fis=null;
try {
//1.创建流对象
fis=new BufferedInputStream(new FileInputStream("aa"+File.separator+"c.txt"));
/*2.用流对象读取文件中数据*/
//准备一个数组
byte[] b=new byte[10];
//读取一次,读取的内容存数组b中,返回读取实际长度
int len=fis.read(b);
while (len!=-1) {
//读取一次就输入一次
System.out.println(new String(b, 0, len));
//接着读取
len=fis.read(b);
}
System.out.println("读取成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关闭流
if (fis!=null) {
fis.close();
}
}
}
5.2:字节缓冲输出流
FilterOutputStream->BufferedOutputStream
public static void main(String[] args) throws IOException {
//声明流对象
FilterOutputStream fos=null;
try {
//1.创建流对象
fos=new BufferedOutputStream(new FileOutputStream("aa"+File.separator+"c.txt"));
//2.用流对象向文件中写入数据
fos.write("Hello".getBytes());
fos.flush();
fos.write("java".getBytes());
fos.flush();
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关闭流
if (fos!=null) {
fos.close();
}
}
}
其他流
所有字符流都是处理流封装字节流.
6.基本字符流
设置编码,实现内容追加.
6.1:基本字符输入流
Reader->InputStreamReader
public static void main(String[] args) throws IOException {
//声明流对象
FilterOutputStream fos=null;
try {
//1.创建流对象
fos=new BufferedOutputStream(new FileOutputStream("aa"+File.separator+"c.txt"));
//2.用流对象向文件中写入数据
fos.write("Hello".getBytes());
fos.flush();
fos.write("java".getBytes());
fos.flush();
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关闭流
if (fos!=null) {
fos.close();
}
}
}
6.2:基本字符输出流
Writer->OutputStreamWriter
public static void main(String[] args) throws IOException {
//声明流对象
Writer w=null;
try {
//1.创建流对象,可以实现内容追加,设置编码
w=new OutputStreamWriter(new FileOutputStream("aa"+File.separator+"d.txt",true), "gbk");
/*2.用流向文件中写入数据*/
w.write("我是程序猿");
w.append("我爱java");
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (w!=null) {
w.close();
}
}
}
7.字符流
FileReader,FileWriter,特点:使用方便,不能设置字符编码.
public static void main(String[] args) throws IOException {
//声明流对象
FileReader r=null;
FileWriter w=null;
try {
//1.创建流对象
r=new FileReader("aa"+File.separator+"a1.txt");
w=new FileWriter("bb"+File.separator+"c2.txt");
/*2.用流对象读取和写入*/
//准备一个数组
char[] c=new char[10];
//先读取一次
int len;
while ((len=r.read(c))!=-1) {
//读取一次就写入一次
w.write(c, 0, len);
}
System.out.println("拷贝成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (r!=null) {
r.close();
}
if (w!=null) {
w.close();
}
}
}
8.字符缓冲流
如果一行一行的读取,那么写入时一定要有换行符,否则会出现线程阻塞.
注意: 所有记事本文件和word文件自带换行.
8.1:字符缓冲输出流
BufferedWriter
public static void main(String[] args) throws IOException {
//声明流对象
BufferedWriter w=null;
try {
//1.创建流对象
w=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("aa"+File.separator+"e.txt",true), "utf-8"));
/*2.用流向文件中写入数据*/
w.write("不忘初心");
w.flush();//刷新
//换行
w.newLine();
//\n可以换行
w.append("方得\n始终");
w.flush();//刷新
//换行
//w.newLine();
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (w!=null) {
w.close();
}
}
}
8.2:字符缓冲输入流
BufferedReader
public static void main(String[] args) throws IOException {
//声明流对象
BufferedReader r=null;
try {
//1.创建流对象
r=new BufferedReader(new InputStreamReader(new FileInputStream("aa"+File.separator+"e.txt"), "utf-8"));
/*2.用流读取文件中数据*/
String content;
while ((content=r.readLine())!=null) {
//输出读取内容
System.out.println(content);
}
System.out.println("读取成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (r!=null) {
r.close();
}
}
}
9.对象流
用来程序间交换数据.
- 1:序列化:将程序(内存)中对象存到磁盘的文件中,叫序列化.
持久化:将内存中短暂存储的数据存长久存储的磁盘上叫持久化.
反序列化:将磁盘上文件中对象读取到程序(内存)中,叫反序列化. - 2:对象输出流:ObjectOutputStream
注意: 对象输出流向文件中写入对象的过程,其实就是序列化.
public static void main(String[] args) {
//声明流对象
ObjectInputStream ois=null;
try {
//1.创建流对象
ois=new ObjectInputStream(new FileInputStream("aa"+File.separator+"a.txt"));
/*2.用流读取文件中对象*/
//读取字符串对象
//结论一:读取方法的数据类型要与写入方法的数据类型一致
// Object ob1= ois.readObject();
// System.out.println("读取的内容为:"+ob1);
//读取一个学生对象
// Student ob2=(Student)ois.readObject();
// System.out.println(ob2);
//读取多个对象
List<Student> stulist=(List<Student>) ois.readObject();
for (Student stu : stulist) {
System.out.println(stu);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (ois!=null) {
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
- 3:对象输入流:ObjectInputStream
注意: 对象输入流将文件中数据读取到程序中过程,其实就反序列化.
public static void main(String[] args) {
//声明流对象
ObjectInputStream ois=null;
try {
//1.创建流对象
ois=new ObjectInputStream(new FileInputStream("aa"+File.separator+"a.txt"));
/*2.用流读取文件中对象*/
//读取字符串对象
//结论一:读取方法的数据类型要与写入方法的数据类型一致
// Object ob1= ois.readObject();
// System.out.println("读取的内容为:"+ob1);
//读取一个学生对象
// Student ob2=(Student)ois.readObject();
// System.out.println(ob2);
//读取多个对象
List<Student> stulist=(List<Student>) ois.readObject();
for (Student stu : stulist) {
System.out.println(stu);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (ois!=null) {
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
-
4:对象输入流读取的方法与对象输出流写入的方法类型要一致,否则会报错EOFException.(write数据类型()和read数据类型()这两个方法的数据类型要一致)
-
5:只有实现序列化接口java.io.Serializable接口的类的对象,才能(序列化)用对象输出流写入到文件中.
-
6:版本号错误:
local class incompatible:
stream classdesc serialVersionUID = -1243946572963888417
local class serialVersionUID = 3821573340049539149- 操作:先将学生类的一个对象进行序列化(用对象输出流存到文件中),再修改学生类,再将现在的学生类反序列化取数据,就报版本号错误.
- 原因:学生类只实现序列化接口,但是没有因定化序列化版本号,这样学生类每修改一次就会重新产生一个新的序列化版本号,如果你用原来序列化版本号对应类的对象存的数据,用新的序列化版本号就取不出数 据.
- 解决:给每个序列化类固定版本号.
-
7:如果序列化类中属性不想实现序列化,就用static或transient来修饰就可以
-
8:如果想用对象流存多个对象到文件中,可以先将多个对象存在集合中,再把集合存到 文件中.
10.打印流:
10.1:字节打印流的使用:
public static void main(String[] args){
//声明流对象
PrintStream ps=null;
try {
//1.创建流对象
ps=new PrintStream("aa"+File.separator+"b.txt");
//2.用流向文件中写入数据
ps.append("abc");
ps.print("good");
ps.println("bye");
ps.printf("%.2f", 0.23232323);
ps.write("java".getBytes());
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关闭流
if (ps!=null) {
ps.close();
}
}
}
10.2:输出重定向
给流重新定义一个方向,将原来输出到控制台的数据,重新定义一个方向后,输出到文件中.
- 语法
System.setOut(PrintStream ps);
public static void main(String[] args) throws FileNotFoundException {
//输出重定向
System.setOut(new PrintStream("aa"+File.separator+"c.txt"));
System.out.println("我是程序猿");
System.out.println("我爱java");
}
10.3:输入重定向
给流重新定义一个方向,将原来从控制台接收的数据,重新定义一个方向后,从文件中接收.
- 语法:
System.setIn(InputStream in)
public static void main(String[] args) throws FileNotFoundException {
//输入重定向
System.setIn(new FileInputStream("aa"+File.separator+"c.txt"));
Scanner input=new Scanner(System.in);
System.out.println("请输入字符串");
String s1=input.next();
String s2=input.next();
System.out.println("接收数据为:"+s1);
System.out.println("接收数据为:"+s2);
}
11.Properties类
properties配置文件类,按key-value存取值
public static void main(String[] args) throws Exception {
//创建Properties对象
Properties p=new Properties();
//用Properties对象调用方法加载配置文件
p.load(new FileInputStream("aa"+File.separator+"jdbc.properties"));
//获取配置文件中属性值
System.out.println("用户名:"+p.get("username"));
System.out.println("密码:"+p.get("password"));
System.out.println("url:"+p.get("url"));
}
12.装饰者模式:
作用:封装原有类,使其功能更强大.
要实现装饰者模式,注意以下几点内容:
a.装饰者类要实现真实类同样的接口 或继承同样父类.
b.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入)
c.装饰类对象在主类中接受请求,将请求发送给真实的对象(相当于已经将引用传递到了 装饰类的真实对象)
d.装饰者可以在传入真实对象后,增加一些附加功能(因为装饰对象和真实对象都有同样 的方法,装饰对象可 以添 加一定操作在调用真实对象的方法,或者先调用真对象的方法,再添加自己的方法)
个人笔记,思路,仅供参考