*File类型:
java.io.File类型,可以对硬盘上的文件/目录,进行操作。(java 7 在java.nio及其子包下提供了一系列全新的API,这些API是对原有新IO的升级,因此也被称为NIO 2,通过这些NIO 2 ,程序可以更高效的进行输入、输出操作)
如查看文件/目录的属性信息,
创建,删除文件/目录.
此类型不能访问文件本身的"内容"。
–常用构造器:
File(String pathname): 指定一个路径,创建一个File对象
路径:
(1)文件的路径,要写到文件的扩展名为止
(2)目录的路径,要写到当前目录的名称为止
=======================================================================
java.io.File类型
一、概念:
可以用来创建,删除文件/目录,还可以查看文件/目录的属性信息。
但是不可以修改文件里的数据。如果需要修改,应该使用输入/输出流。
二、常用构造器:
File(String pathname): 创建一个指定路径的File对象
File(File parent,String child):
在指定parent路径下,创建一个child的file对象
File(String parent,String child):
在指定parent路径下,创建一个child的file对象
三、绝对路径:是从根目录开始写的路径.
window: 从盘符开始书写:
D:\a\f1.txt
D:\a\b
linux/UNIX/BSD: /home/scott/f1.txt
/home/scott
相对路径: 相对某一文件/目录的路径,不是从根路径书写的, 在默认情况下,系统总是依据用户的工作路径来解释相对路径,这个路径由系统属性“user.dir”指定, 通常也就是运行java虚拟机时所在的路径。
reg: f2.txt相对于a目录的路径:
window: b\f2.txt
linux: b/f2.txt
reg: f3.txt相对于f2.txt的路径
../c/f3.txt
四、常用方法
boolean exists(); 判断指定的路径是否存在
boolean isFile(); 判断指定路径是不是文件
boolean isDirectory(); 判断指定路径是不是目录
String getName(); 获取文件/目录名称
long lastModified(); 获取文件/目录的最后修改时间
boolean isAbsolute(); 判断指定路径是不是绝对路径
String getAbsolutePath(); 获取绝对路径
String getParent(); 获取父目录的路径
long length(); 获取文件大小
文件/目录创建方法:
boolean createNewFile(); 创建文件
boolean mkdir(); 创建目录
boolean mkdirs(); 创建多级目录
文件/目录的删除方法:
boolean delete(): 可以删除文件 ;删除目录时,需要目录下没有文件或子目录(即空目录)
File[] listFiles(): 获取File对象的所有子文件和路径,返回File数组
String[] list(): 列出File对象的所有子文件名和路径名,返回String数组
文件过滤器:list()方法中可以接收一个FilenameFilter参数,通过该参数可以只列出符合条件的文件。 FilenameFilter接口和javax.swing.filechooser包下的FileFilter抽象类的功能非常相似,可以把后者当成 前者的实现类。FilenameFilter接口里包含一个accept(File dir ,String name)方法,该方法将依次对 指定File的所有子目录或者文件进行迭代,若该方法返回true, 则 list()方法会列出该子目录 / 文件
五.递归:
递归思想:分成"递与归"。一层层递进,最后再一层层归。
两种递归:
(1)方法调用自己
(2)方法A调用方法B,方法B调用A
举例:
n*(n-1)*......*1
z = f(n) 计算n的阶乘
= n*f(n-1)
= n*(n-1)*f(n-2)
= n*(n-1)*......*1
f(n)是一个函数:
里的逻辑:
n*f(n-1)
练习:
斐波那契数列: 第n个数是第n-1个数与第n-2个数的和。
1,1,2,3,5,8,13,.......
计算第10个数的值。
=======================================================================
*javaBean规范:
程序开发者默认遵循的一种规范
(1)提供两个构造器
(2)给成员变量提供get/set方法
String name
getName()
setName(String name);
Bean:豆子的意思,get/set方法名上的后续单词称之为bean.
在命名方法时,作为bean的单词,首字母要大写,
成员变量要尽可能的与bean名一致,首字母小写。
(3)重写hashCode方法和equals方法
(4)重写toString()
=======================================================================
*IO流:(Input,Output)
我们在做项目时,除了自定义的一些数据外,还可能需要从"外界"引入数据,
或者将数据导出到"外界".
这时,我们需要I/O操作。
外界:指的可能是 键盘,显示器,硬盘,另外一个程序。
输入:又叫读入操作
数据是从"外界"流向程序
输出:又叫写出操作
数据是从程序流向"外界"
流: 就是数据序列, 一经创建成功,就会打开一个通道。
所以使用完应该进行关闭操作。
–IO流的分类:
(1)按照流向分类:
输入流
输出流
(2)按照处理的数据单位分类:
字节流
字符流
(3)按照功能分类:
节点流:直接连接两个设备的流类型
处理流:对节点流再次封装与处理的流类型(在使用处理流包装了底层的节点流之后, 关闭输入/输出流资源时,只要关闭最上层的处理流即可。 关闭最上层的处理流时,系统会自动关闭被该处理流包装的节点流)
或者:
高级流:
低级流:
–字节流(4种):
抽象父类 InputStream/OutputStream
一、字节输入输出流: (低级流)
抽象父类: InputStream(定义了字节输入流的常用方法)
int available();
void close();
int read(); 读取一个字节,存入int的低八位上,范围是0-255
int read(byte[] b); 尝试一次读取b.length个字节存入字节数组b中,
返回的是读取的有效字节个数。
int read(byte[] b,int off,int len);
skip(int n);
抽象父类: OutputStream(定义了字节输出流的常用方法)
void close();
void flush(); 冲刷,作用是将(缓冲区中)流的数据,冲刷进文件中
void write(int b); 写一个字节,写的是int值的低八位
void write(byte[] b); 写一个字节数组
void write(byte[] b,int off,int len);
子类:
-
FileInputStream/FileOutputStream:
继承了字节流的抽象父类。重写了方法,并且提供了自己独有的方法构造器:
FileInputStream(File file)
FileInputStream(String path)FileOutputStream(File file) FileOutputStream(File file,boolean append) FileOutputStream(String pathname) FileOutputStream(String pathname,boolean append)
PS:所有的输出流,对于指定的路径中的文件若是不存在,都会自动创建。
使用java 的IO流进行输出时,不要忘记关闭输出流, 关闭输出流作用:1)保证流的物理资源被回收 2)还可以将输出流缓冲区中的数据flush到物理结点里(因为在执行close()方法之前, 自动执行输出流的flush()方法)
2.缓冲流: (高级流)
–BufferedOutputStream:字节缓冲输出流
在写数据时,如果一个字节一个字节的写,写的次数明显很多,
效率就会变得很低。
如何提高效率呢?
缓冲输出流的特点是:
在流里维护了一个缓冲区(默认是8k),写字节时,先将字节写入缓冲区,
当缓冲区满时,再一次性的将数据写到文件里。
这样就降低了写的次数,因此提高了效率。
因此缓冲输出流"缺失即时性",可以使用flush方法进行冲刷
常用构造器:
BufferedOutputStream(OutputStream out):
创建一个指定字节输出流的缓冲流对象
BufferedOutputStream(OutputStream out,int size):
创建一个指定字节输出流的缓冲流对象,并设置指定(默认)缓冲区的大小
PS:当一次写的字节超出缓冲区大小,会出现溢出情况,
溢出的字节会先写出到文件中
常用方法:
void write(int b): 写int数据的低八位,写入缓冲区内
void write(byte[] b,int off,int len):
写指定长度len的字节数组,写入缓冲区
--BufferedInputStream:字节缓冲输入流
在读取字节时,也是一个字节一个字节的读,次数多,效率低。
使用缓冲输入流,内部维护了一个缓冲区,默认8k,先一次性将缓冲区装满
等待读取.
当将缓冲区的数据读完,缓冲区再次存储后续数据。读取的次数明显降低效率高
构造器:
BufferedInputStream(InputStream is);
BufferedInputStream(InputStream is,int size);
常用方法:
int read(byte[] bs):
读取缓冲区里的字节存储bs中,
当一次性读取的字节小于缓冲区,我们是从缓冲区里读数据。
此时,效率高
当一次性读取的字节超出缓冲区大小,
不使用缓冲区,直接从文件里读。
int read(byte[] bs,int off,int len):
3.数据字节流:
与缓冲流一样,父类都是过滤字节流(
FilterOutputStream/FilterInputStream
)
这两个类提供了几个特殊的方法,可以直接写基本数据类型.
数据输出流:DataOutputStream
构造器:
DataOutputStream(OutputStream os):
创建一个指定字节输出流的数据输出流对象
常用方法:
除了提供写一个字节和写一个字节数组的方法外,还提供了如下方法:
writeByte(int b)
writeShort(int s)
writeInt(int i)
writeLong(long l)
writeFloat(float f)
writeDouble(double d);
writeChar(int c);
writeBoolean(boolean b)
writeUTF(String s);
数据输入流:DataInputStream
构造器:
常用方法:
4.对象流:
有的时候,我们可能需要将内存中的对象持久化到硬盘上,
或者将硬盘中的对象信息读到内存中,这个时候我们需要使用对象输入
输出流。
序列化: 是对象转换成一个字节序列(字節數組)的过程,是一个写操作
反序列化: 一个字节序列转换成对象的过程 ,是一个读操作
实现序列化与反序列化的要求:
(1)ObjectOutputStream:
构造器:
ObjectOutputStream(OutputStream out):
创建一个指定字节输出流的对象输出流对象。
常用方法:
除了提供了一些基本数据类型的写方法外,还提供了
void writeObject(Object obj): 将内存中的对象持久化到硬盘上
(2)ObjectIntputStream
构造器:
ObjectIntputStream(OutputStream out):
创建一个指定字节输入流的对象输入流对象。
常用方法:
除了提供了一些基本数据类型的读方法外,还提供了 Object readObject(): 从硬盘上读取一个字节序列,转换成对象
=======================================================================
*Serializable:序列化接口
如果想将对象序列化,那么对象的类型必须实现此接口。
此接口内什么都没有,只是一个序列化标识。
–serialVersionUID:
每个能序列化的对象,在被序列化时,系统会默认给此对象的类计算一个
序列化版本号。不同的平台默认提供的序列化版本号多数情况下不会相同。
因此当我们反序列时,如果硬盘里存储的对象的版本号与当前设计的类型
的版本号不一致。会出现运行时异常:
java.io.InvalidClassException,这种情况叫不兼容问题。
如果我们想解决不兼容问题。我们应该手动提供版本号。
尽可能的相同,这样来解决不兼容问题
另外一种情况:
序列化过后,可能会修改类型,如果使用系统默认提供的
版本号,在反序列时,会有异常,如果手动提供,不出现异常,
多出来的成员变量,以默认值的形式,赋值给反序列化回来的对象。
–transient:
成员变量的一个修饰词,可以理解为瘦身(忽略)。
有的时候,在序列化对象时,我们不需要将对象的某些成员变量值
持久化到硬盘上(因为不重要),此时,我们可以在这些成员变量
前添加修饰词transient(保存时,进行减肥