目录结构:

contents structure [+]

Java用File来访问文件、目录,以及对它们的删除、创建等。
接下来列出File类中常用的方法:
1. 访问文件名相关的方法
Sring getName():返回此File对象所表示的文件名或路径名(如果是路径则返回最后一级子路径)
String getPath():返回此File对象所对应的路径名
File getAbsoluteFile():返回此File对象所对应的绝对路径名称
String getParent():返回此File对象所对应的目录(最后一级子目录)的父目录名。
boolean renameTo(File newName):重命名此File对象所对应的的文件或是目录,如果重命名成功,则返回true,否则返回false。

2.文件检查相关的方法
boolean exists():判断File对象所对应的文件或目录是否存在。
boolean canWrite():判断File对象所对应的文件或目录是否可写。
boolean canRead():判断File对象所对应的文件或目录是否可读。
boolean isFile():判断File对象所对应的是否是文件。
boolean isDirectory():判断FIle对象所对应的是否是目录。
boolean isAbsolute():判断File所对应的文件或目录是否是绝对路径。该方法消除了不同平台的差异,可以直接判断FIle对象是否为绝对路径。在UNIX/Linux/BSD 等系统,如果路径名开头是一条斜线(/),则表明该File对象所对应一个绝对路径。在Window系统上,如果路径开头盘符,则说明它是一个绝对路径。

3.获取常规文件信息
boolean lastModified():返回文件的最后修改时间。
boolean length():返回文件内容的长度。

4.获取文件的常规信息
boolean createNewFile():当此File对象所对应的文件不存在时,该方法将新建一个该File对象所对应的新文件。如果创建成功则返回true,否则返回false。
boolean delete():删除File对象所对应的文件或是目录。
static File createTempFile(String prefix,String suffix) 在默认的临时文件目录中创建一个临时的空文件,使用给定前缀、系统生成的随机数和给定后缀做文件名。这是一个静态方法,可以直接通过File类来调用。Prefix参数必须至少是3字节长。建议前缀使用一个短的,有意义的字符串。suffix 可以为null,这种情况下默认使用后缀“.temp”。
static File createTempFile(String prefix,String suffix,File directory) 在directory指定的目录中创建一个临时的空文件,使用给定前缀、系统生成的随机数和给定后缀作为文件名。这是一个静态方法,可以直接通过File类来调用。
void deleteOnExit():注册一个删除勾子,指定当Java虚拟机退出时,删除File对象所对应的文件和目录。

5.目录操作相关的方法
boolean mkdir():试图创建一个File对象所对应的目录,如果创建成功,则返回true;否则返回false,调用方法时,File对象必须对应一个路径。
String[] list() 列出File对象的所有子文件名和路径名。
File[] listFiles() 列出File对象的所有子文件和路径。
static File[] listRoots() 列出系统所有的根目录。

下面使用使用递归打印某个目录下及其子目录下的所有的文件名:

public class TestDirPrint {
    //打印指定目录中的内容,要求子目录中的内容也要打印出来
    public static void dirPrint(File f){
        //1.若f关联的是普通文件,则直接打印文件名即可
        if(f.isFile()){
            System.out.println(f.getName());
        }
        //2.若f关联的是目录文件,则打印目录名的同时使用[]括起来
        if(f.isDirectory()){
            System.out.println("[" + f.getName() + "]");
            //3.获取该目录中的所有内容,分别进行打印
            File[] ff = f.listFiles();
            for(File ft : ff){
                dirPrint(ft);
            }
            
        }    
    }
}

2. I/O流体系

2.1 流的基本介绍

首先介绍流的分类:

按照流的方向来分,可以分为字节流和字符流。
输入流:只能读取数据。
输出流:只能向其中写入数据。
输入流和输出流都是站在程序的角度进行考虑的。

按照流处理的数据单元不同,可以分为字节流和字符流。
字节流和字符流的用法几乎一致,区别是它们操作的数据单元不同。字节流操作的数据单元是一个字节,字符流操作的数据单元是2个字节。

按照流的角色,可以分为节点流和处理流。
节点流是可以直接向特定的IO设备进行读/写操作的流,这种流也被称为低级流。处理流则用于对一个已存在的流,通过封装后的流来实现数据读/写功能,处理流被称为装饰流或高级流。

java的输入/输出流提供了近40个类,下面按照流的功能进行分类:

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInptStream PipedOutoutStream PipedReader PipedWriter
访问字符串     StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转化流     InputStreamReader OutputStreamWriter
对象流 ObjectInputStream ObjectOutputStream    
抽象基类 FilterInputStream FilterOutputStream FilterReader FilterWriter
打印流   PrintStream    
推回输入流 PushbackInputStream   PushbackReader  
特殊流 DataInputStream DataOutputStream    


我们已经知道字节流的数据单元是一个字节,字符流的数据单元是两个字节。通常情况下,如果访问的是文本内容,那么应该使用字符流,如果访问的是二进制内容,那么应该使用字节流。
使用字节流访问文本内容,如果一次访问不完,那么很有可能出现乱码的情况。
例如有GBK格式编码的文本文件test.txt,内容如下:
“do not give up.不要放弃。”
这段文本中“do not give up.”一共占据15个字节。“不要放弃。”一共占了10个字节。
如果使用如下的代码来访问:

        String path="C:\\Users\\dell\\Desktop\\test.txt";
        FileInputStream fis=new FileInputStream(new File(path));
        byte[] bytes=new byte[1024];//一次读取1024个字节
        int offset=0;
        String result="";
        while((offset=fis.read(bytes,0,bytes.length))!=-1){
            result+=new String(bytes,0,offset);
        }
        System.out.println(result);

由于上面的文本没有1024个字节,所以可以一次性读完,并不会出现乱码情况。
而如果改为一次读取3个字节,那么就会出现乱码。我们甚至还可以推断出,那些字符会出现乱码,由于读取数据的单位为3个字节,所以前面的“do not give up.”会分为5次读完。后面的汉字“不要放弃。”每个汉字占两个字节,为了方便理解,我们把这10个字节用一下这些字符来表示“12 34 56 78 9A”,第一次读取了三个字节123,12可以被正常解析为“不”,后面有一个字节不能被正常解析。第二此又读取三个字节456,45不能被正常解析,6也不能被正常解析。第三次又读取三个字节789,78可以被正常解析,9不能。最后读取最后一个字节A,A也不能被正常解析。所以最终汉字中只有“不”、“弃”可以被正常解析。

2.2 访问文件

在前面介绍过访问文件主要涉及到FileInputStreaam、FileOutputStream、FileReader、FileWriter,如果是二进制文件,那么使用字节流。如果是文本文件,那么使用字符流。
接下使用FileInputStream、FileOutputStream实现对文件的复制:

public class TestFileCopy {

    public static void main(String[] args) {
        
        try{
            //1.建立FileInputStream类的对象与源文件建立关联
            FileInputStream fis
                = new FileInputStream("D:/java09/day16/javaseday16-IO流常用的类-06.wmv");
            //2.建立FileOutputStream类的对象与目标文件建立关联
            FileOutputStream fos = new FileOutputStream("c:/javaseday16-IO流常用的类-06.wmv");
            //3.不断地读取源文件中的内容并写入到目标文件中
            /* 可以实现文件的拷贝,但是文件比较大时效率很低
            int res = 0;
            while((res = fis.read()) != -1){
                fos.write(res);
            }
            */
            //第二种方案,根据源文件的大小准备对应的缓冲区(数组),可能导致内存溢出
            //第三种方案,无论文件的大小是多少,每次都准备一个1024整数倍的数组
            byte[] data = new byte[1024 * 8];
            int res = 0;
            while((res = fis.read(data)) != -1){
                fos.write(data, 0, res);
            }
            System.out.println("拷贝文件结束!");
            //4.关闭文件输入流对象
            fis.close();
            //5.关闭文件输出流对象
            fos.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
TestFileCopy.java

相关文章: