进行文件I/O操作之前,首先要找到文件的位置,这就和File类有关。File可以表示文件也可以表示文件所在的目录,File只关注文件本身的信息,不能操作文件里面的内容。
文件目录的路径名和操作系统有关系,在UNIX系统中根目录的分隔符是“/”,在Windows系统中是“\\”,例如找到C盘Program File 目录下的test.txt文件,可以把路径写成“C:\\Program Files\\test.txt”,也可以写成”C:/Program Files/test.txt”
路径分为相对路径和绝对路径的写法:
绝对路径:硬盘上的目录的物理路径,从盘符开始的路径,如”C:/Program Files/test.txt”或”C:\\Program Files\\test.txt”
相对路径:从当前目录开始的路径,“./”表示当前目录(也可以省略),“../”表示上级目录,如找到C盘Program File 所在的同级目录test下的1.text文件,路径可以写成“../test/1.txt”;
字段:
file.separatorChar;
public static final char separatorChar = fs.getSeparator();
//与系统有关的路径分隔符,在 UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\',返回char类型。
file.separator;
public static final String separator = "" + separatorChar;
//只包含一个字符,即separatorChar,返回String类型。
file.pathSeparator;
public static final char pathSeparatorChar = fs.getPathSeparator();
//与系统有关的路径分隔符。此字符用于分隔以路径列表形式给定的文件序列中的文件名。在 UNIX 系统上,此字段为 ':';在 Microsoft Windows 系统上,它为 ';',返回char类型。
file.pathSeparatorChar;
public static final String pathSeparator = "" + pathSeparatorChar;
//只包含一个字符,即pathSeparatorChar,返回String类型。
构造方法:
File(String pathname);//给定路径名字字符串创建File对象。如果是绝对路径,在路径名称对应的硬盘路径创建,如果是相对路径,在项目所在的目录下创建。
File(String parent, String child)//给定父目录的路径字符串和文件名创建File对象
File(File parent, String child) //给定父目录和文件名创建File对象
File(URI uri) 给定URI对象创建File对象
方法:
public boolean canRead()//表示文件是否可读
public boolean canWrite()//表示文件是否可写
public boolean exists()//文件或者目录是否存在
public boolean isDirectory()//表示是否是一个目录
public boolean isFile()//表示是否是一个文件
public boolean isHidden()//指定的文件是否是隐藏文件
public long lastModified()//文件最后修改时间,以1970 年 1 月 1 日,00:00:00 GMT为基准
long类型时间转换为String类型时间:
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
String time = format.format(file.lastModified());
public long length()//文件长度,以字节为单位,如果是目录,返回值不确定
public boolean createNewFile() throws IOException//创建文件,指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false
public boolean mkdir()//创建指定的目录,当且仅当已创建目录时,返回 true;否则返回 false
public boolean mkdirs()//当且仅当已创建目录以及所有必需的父目录时,返回 true;否则返回 false
public static File createTempFile(String prefix,String suffix,File directory)//在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称
public static File createTempFile(String prefix,String suffix)//在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。调用此方法等同于调用 createTempFile(prefix, suffix, null)
public boolean delete()//删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。
public File getAbsoluteFile()//返回此抽象路径名的绝对路径名形式
public String getAbsolutePath()//返回此抽象路径名的绝对路径名字符串。
public String getPath()//将此抽象路径名转换为一个路径名字符串,File对象创建时的路径名怎么写,getPath()就怎么返回;而getAbsolutePath()是返回绝对路径,和字符串参数形式无关。
public String getParent()//返回父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null
public File getParentFile()//返回父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
public String getParent()//返回文件或目录的名称。该名称是路径名名称序列中的最后一个名称。如果路径名名称序列为空,则返回空字符串。
public String[] list()//返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
public File[] listFiles()//返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
public String[] list(FilenameFilter filter)//返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录,过滤器需要满足 FilenameFilter.accept(java.io.File, java.lang.String)
public File[] listFiles(FilenameFilter filter)//返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
public File[] listFiles(FileFilter filter)//返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
public static File[] listRoots()//列出可用的文件系统根。
例1:创建指定目录下的文件
public static void main(String[] args) throws IOException {
File file = new File("c://io//io1//test.txt");
//判断指定路径的文件是否存在,如果不存在,则创建该文件
//System.out.println(file.exists());
if(!file.exists()){
//如果目录不存在,则先创建目录
File dir = file.getParentFile();
if(!dir.exists()){
//dir.mkdir();//如果该目录的上级目录不存在抛出异常信息:java.io.IOException: 系统找不到指定的路径。
dir.mkdirs();
}
//再创建目录
boolean result = file.createNewFile();
System.out.println(result);
}
}
例2:输出指定目录下的指定文件后缀的信息。
1)要求只输出文件后缀名为txt的文件
首先通过listFile(),获取到所有的文件,然后再逐个判断
*2)根据API的过滤器来完成该功能
public static void main(String[] args) throws IOException {
//创建File对象指向指定的目录
File dir = new File("C:\\io");
showFile(dir);//不指定过滤器
showFile2(dir);//指定过滤器
}
public static void showFile(File dir){
File[] files = dir.listFiles();
for(File f : files){
if(f.isDirectory()){
showFile(f);
}else{
if(f.getName().endsWith(".txt")){//输出txt格式文件信息
System.out.println(f.getAbsolutePath());
}
/*if(dir.isFile()){//输出所有文件信息
return true;
}*/
}
}
}
public static void showFile2(File dir){
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//考虑目录---如果是目录,返回true
if(new File(dir,name).isDirectory()){
return true;
}
if(name.endsWith(".txt")){
return true;
}
/*if(dir.isFile()){//输出所有文件信息
return true;
}*/
return false;
}
});
for(File f : files){
if(f.isDirectory()){
showFile2(f);
}else{
System.out.println(f.getAbsolutePath());
}
}
}
例3:删除目录
public static void main(String[] args) {
File dir = new File("e://1");
//dir.delete();
del(dir);
}
public static void del(File dir){
File[] files = dir.listFiles();
for(File f : files){
if(f.isDirectory()){
del(f);
}else{
f.delete();
}
}
dir.delete();
}
IO流概念
流是一组有序的,有起点和终点的字节集合,是对数据传输的总称或抽象。流的本质是数据传输。
IO流划分
按方向分:输入流、输出流(相对于程序来说,输入流只能进行读操作,输出流只能进行写操作)
按读取单位分:字节流、字符流(图片、视频等二进制文件用字节流,文本文件还可以用字符流读取)
按功能分:节点流、处理流
1.输入字节流InputStream
此抽象类是表示字节输入流的所有类的超类。
public int read()//下一个数据字节;如果到达流的末尾,则返回 -1。
public int read(byte[] b)//读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
public int read(byte[] b, int off, int len)//读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
public void close()//关闭流操作,大部分流打开后最终都必须进行关闭操作。
2.输出字节流OutputStream
此抽象类是表示输出字节流的所有类的超类。
public void flush()//刷新此输出流并强制写出所有缓冲的输出字节。(数据较多的时候)
public void write(byte[] b)//将 b.length 个字节从指定的 byte 数组写入此输出流。
public void write(byte[] b,int off,int len)//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
public abstract void write(int b)//将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。
3.FileInputStream(节点流)
FileInputStream 从文件系统中的某个文件中读取输入字节,可以传入File对象或文件的路径,如:
public FileInputStream(File file)
public FileInputStream(String name)
4.FileOutputStream(节点流)
FileOutputStream是用于将数据写入 File 或 FileDescriptor 的输出流。和输入流一样可以传入File对象或文件的路径。
public FileOutputStream(File file)
public FileOutputStream(String name)
//append为true时在文件的末尾追加,否则从文件的最开始位置写入
public FileOutputStream(String name,boolean append)
public FileOutputStream(File file,boolean append)
例1:A文件内容复制到B文件中
public static void main(String[] args) throws IOException {
//输入流读取文件
FileInputStream input = new FileInputStream("test.txt");
//输出流写文件
FileOutputStream out = new FileOutputStream("test2.txt");
/*int i = -1;
while((i=input.read())!=-1){
out.write(i);
}*/
byte[] bs = new byte[1024];
int len = -1;
while((len=input.read(bs))!=-1){
out.write(bs);
}
out.close();
input.close();
System.out.println("copy finish");
5.BufferedInputStream(过滤流)
在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。缓冲区大小8192(8K),也可以传入参数指定缓冲区数组大小:
private static int defaultBufferSize = 8192;
public BufferedInputStream(InputStream in) {
this(in, defaultBufferSize);
}
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
6.BufferedOutputStream(过滤流)
输出流和输入流一样,默认带有缓冲区数组,也可以指定缓冲区数组大小。
带缓冲区的输入流和输出流与FileInputStream和FileOutputStream没有区别,只是在传输数据量大的时候选择带缓冲区的流速度更快,提高效率。