文件和IO体系
File类位于java.io包下,可以通过实例化File对象来创建文件、删除、修改、增加文件。
一、文件系统的基本规则
1.文件的全名包含路径名和扩展名,单独将一个文件名时,不带路径只带扩展名,如Student.java。
2.同一目录下,不存在同名的目录和真实文件,系统主要有目录类型的文件、真实文件、虚拟内存文件,真是文件又包括字符文件、二进制文件。
3.绝对路径还是以根目录开头的路径,相对路径是不以路径分隔符开始的路径。
4.linux的目录分隔符和路径分隔符分别是:“/”和“:”,win的目录分隔符和路径分隔符分别是:“\”和“;”。
二、File类的一些常见构造器
File(File parent,String child)——在一个父目录对象下创建一个名字为child的文件对象
File(String pathname)——创建一个指向pathname名字的File对象
File(String parent,String child)——以parent字符串为父目录名,创建名为child的文件对象
需要注意的是通过构造器创建File对象时,只是在JVM内存中生成了一个File对象,与磁盘上的文件没任何关系,只当调用这个对象的其它方法时,才有关。
三、File类的常用方法
booleans exists()——判断文件是否存在
String getName()——得到文件不带路径的名字
booleans isDirectory()——判断文件是否为目录
booleans isFile()——判断是否为真实文件
long length()——得到File对象指向的文件长度,以byte计,如指向目录,则返回0
File [] listFiles()——将File对象指向的文件下一级所有目录和真实文件作为一个数组返回,如果File对象是一个真实文件,则返回null值
static File[] listRoots()——通过File类可以直接调用的静态方法,可以将机器上每个盘最为数组中一个File对象元素,linux是单根文件系统
booleans mkdirs()——如果File类对象是多级目录,可以一次性创建
booleans delete()——从磁盘上删除File类对象所指向的文件
booleans createNewFile()——根据文件对象的名字在磁盘上创建一个新的真实文件,如存在同名文件,则覆盖,如存在同名目录,则抛出异常
四、递归算法
递归算法适当发现有相同规律的时候,方法调用自己,这样可以避免代码冗长,不致于去穷举。如:
//定义文件搜索的方法
public int printDir(String dir, String name){
int count=0;
//如果没找到要查找的文件
if(name == null){
return 0;
}
File file=new File(dir);
File[] fileList=file.listFiles();
if(null==fileList||fileList.length==0){
return 0;
}
for(int i=0;i<fileList.length;i++){
if(fileList[i].isDirectory()){
String subDir=fileList[i].getAbsolutePath();
System.out.println("目录:"+subDir);
count+=printDir(subDir,name);
}
if(fileList[i].isFile()){
count++;
String filePath=fileList[i].getAbsolutePath();
System.out.println("文件:"+filePath);
//如果文件与查找的文件名相同,就把路径添加到队列中
if (filePath.indexOf(name) >= 0) {
arrayList.add(filePath);
}
}
}
return count;
}
这段代码中,如果创建的File类文件对象是目录,因目录当中寻找文件的方法是一样的,说以可以采用递归算法,在方法体内调用方法自己。
五、异常
异常是指程序在运行时,可能由与外部系统的条件变更而导致程序可能出错的情况。java中的异常概念在java.lang包下面的Exception类中,异常的很多类都是Exception类的子类。出现异常可以用try...catch处理机制,如果没有,会出现语法错误“Unhandled exception type IOException”,也可以用thtows抛出异常。 在方法体中也可以用throw自定义异常,但在方法中必须用throws声明。
空指针异常是因为没有实例化或者返回空值没有初始化。
六、stream的概念
java将输入和输出抽象为流的概念 。Java中的流相当于水管,从一端读取数据,想另外一端输出数据,它是程序和外界进行数据交换的通道在OOP中的表现。
七、流的分类
按方向分: 输入流和输出流
按性质分:
基础字节流(原始流):FileInputStream和FileOutputStream是java中可以按最小数据单位读取的流,即每次读取一个字节,基础流是直接连入到输入源的流。
过滤流(节点流、缓冲流 )BufferedInputStream和BufferedOutputStream用来包装基础流或其它流,提供缓冲功能。
基本数据类型流:DataInputStream和DataOutputStream 从流中读取指定类型的数据。
对象流:ObjectInputStream和ObjectOutputStream 对象流得读取就是常说的对象序列化技术。
InputStream和OutputStream是抽象类,不能直接实例化对象,要通过子类实例化对象。
使用FileInputStream读取文件数据,其常用构造函数有:
FileInputStream(File file): 创建一个输入文件流对象,从指定的 File 对象读取数据
FileInputStream(String name) :传入一个字符串(文件路径名)构造连接到指定文件的输入流
使用FileOutputStream将数据写入到文件,其常用构造函数有:
FileOutputStream(File file) 创建一个文件输出流,向指定的 File 对象输出数据。
FileOutputStream(File file,booleans append)append表示输出到文件中的数据是否接在文件中已有的数据后面
BufferedInputStream和BufferedOutputStream的使用,构造器:
BufferedInputStream(InputStream in):使用一个InputStream类型的输入流对象创建一个默认缓冲区大小的缓冲输入对象,默认为8192k
BufferedInputStream(InputStream int size)指定缓冲区大小构造缓冲输入流对象
BufferedOutputStream(OutputStream out):使用默认大小的缓冲区构造缓冲输出流对象
BufferedOutputStream(OutputStream out,int size):可指定缓冲区大小
八、输入输出流中几个重要的方法
int available() :输入流中读取的有效字节长度,(以byte计)
void close() :流对象使用完后关闭
int read() :返回输入流中的下一个字节做为一个byte值,如已读到末尾,则返回-1,虽返回int型,实际上事从流中国读取一个byte值
int read(byte[] b) :从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
int read(byte[] b, int off, int len) :将输入流中从off开始最多 len 个数据字节读入 byte 数组。
void flush() :刷新此输出流并强制写出所有缓冲的输出字节。
void write(byte[] b) :将 b.length 个字节从指定的 byte 数组写入此输出流。
void write(byte[] b, int off, int len) :将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
abstract void write(int b) :将指定的字节写入此输出流。