Java SE(十六):File、RandomAccessFile


Java SE

包括File类简介、查看文件或目录、新建文件或目录、删除文件或目录、查看目录内容、FileFilter接口、顺序读写方法、基于缓存的写方法、基于缓存的读方法、随机读写方法。


一、File

1、File类简介

(1)java.io.File用于表示文件(目录),可以通过File类在程序中操作硬盘上的文件和目录

(2)File的每一个实例可以表示文件系统中的一个文件或目录

(3)使用File可以:

  • 访问文件或目录的属性(如:大小,名字,修改时间等)
  • 操作文件或目录(创建 ,删除文件和目录)
  • 访问目录中的所有内容

(4)不能对文件的内容进行访问

2、查看文件或目录

方法 功能
long length() 返回文件的大小(字节)
long lastModified() 返回文件最后一次被修改的时间
String getName() 返回文件或目录的名称
String getPath() 返回一个路径名字的字符串
boolean exists() 判断文件或目录是否存在
boolean isFile() 判断是否是一个标准文件
boolean isDirectory() 判断是否是目录
boolean canRead() 判断是否可读
boolean canWrite() 判断是否可写
//项目所在路径下需存在demo.txt文件
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileDemo {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("."+File.separator+"demo.txt"); //跨平台使用,避免耦合度,写相对路径(相对文件地址),File.separator(常量)(windows代表\;linux中代表/)

        //获取名字
        String name = file.getName();
        System.out.println("name:"+name);

        //大小(占用的字节量)
        long length = file.length();
        System.out.println("大小:"+length+"字节");

        //是否为文件
        boolean isFile = file.isFile();
        System.out.println("是文件:"+isFile);

        //是否为目录
        boolean isDir = file.isDirectory();
        System.out.println("是目录:"+isFile);

        //是否为隐藏文件
        boolean isHidden = file.isHidden();
        System.out.println("是否隐藏:"+isHidden);

        //最后修改时间
        long time = file.lastModified();
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日 HH:mm:ss");
        System.out.println(sdf.format(date));

        //是否可写
        boolean canWrite = file.canWrite();
        System.out.println("可写:"+canWrite);

        //是否可读
        boolean isWrite = file.canWrite();
        System.out.println("可读"+isWrite);
    }
}

3、新建文件或目录

方法 功能
long mkdir() 创建指定目录
long mkdirs() 创建指定目录,包括创建必须但不存在的父目录
String createNewFile() 创建一个新的空文件

创建文件代码示例:

import java.io.File;
import java.io.IOException;

/**
 * 创建一个文件
 */
public class FileDemo1 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
        在当前目录下创建文件test.txt
        默认路径就是当前目录,即“./”,所以可以不写
         */
        File file = new File("test.txt");
        if(!file.exists()){
    
     //boolean exists()判断该文件是否真实存在
            file.createNewFile(); //不存在创建文件
            System.out.println("创建成功!");
        }else{
    
    
            System.out.println("文件已经存在!");
        }
    }
}

创建目录代码示例:

import java.io.File;

public class FileDemo3 {
    
    
    public static void main(String[] args) {
    
    
        /*
        创建一个新目录
         */
        File file = new File("demo"); //创建demo目录
        if(!file.exists()){
    
    
            file.mkdir();
            System.out.println("创建目录成功!");
        }else{
    
    
            System.out.println("目录已存在!");
        }
        
        /*
        创建多级目录
        在当前目录下创建./a/b/c/d/e/f
         */
        File file1 = new File("a"+File.separator+"b"+File.separator+"c"+File.separator+"d"+File.separator+"e"+File.separator+"f");
        if (!file1.exists()){
    
    
            file1.mkdirs(); //在创建当前目录的同时将所有不存在的父目录一起创建出来
            System.out.println("创建成功!");
        }
    }
}

4、删除文件或目录

方法 功能
boolean delete() 删除文件或目录

删除文件代码示例:

import java.io.File;

/**
 * 删除一个文件
 */
public class FileDemo2 {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("test.txt"); //删除当前目录中的test.txt文件
        if(file.exists()){
    
    
            file.delete();
            System.out.println("删除成功!");
        }else{
    
    
            System.out.println("文件不存在!");
        }
    }
}

删除目录代码示例:

扫描二维码关注公众号,回复: 16326036 查看本文章
import java.io.File;

/**
 * 删除给定的文件或目录
 */
public class Test {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("a");
        delete(file);
    }
    public static void delete(File file){
    
    
        if(file.isDirectory()){
    
    
            //将其所有子项删除
            File[] subs = file.listFiles();
            for(File sub:subs){
    
    
                delete(sub); //递归(整个流程都需要在走一遍):方法内部执行自己方法本身
            }
        }
        file.delete();
    }
}

delete方法可以删除一个目录,但是前提是该目录必须是一个空目录

5、查看目录内容

方法 功能
String[] list() 返回目录中的文件和目录的名称所组成字符串的数组
String[] listFiles() 返回目录中的文件
import java.io.File;

/**
 * 获取一个目录中的所有子项
 */
public class FileDemo6 {
    
    
    public static void main(String[] args) {
    
    
        /*
         * 获取当前目录中的所有子项
         */
        File file = new File(".");
        /*
        boolean isFile()判断是否为一个文件
        boolean isDirectory()
         */
        if (file.isDirectory()){
    
    
            /*
             * File[] listFiles()获取所有子项
             */
            File[] subs = file.listFiles();
            for (File sub:subs){
    
    
                if (sub.isFile()){
    
    
                    System.out.print("是文件:");
                }else {
    
    
                    System.out.print("是目录:");
                }
                System.out.println(sub);
            }
        }
    }
}

6、FileFilter接口

用于路径名的过滤器,此接口的实例可传递给File类的listFiles(FileFilter)方法

import java.io.File;
import java.io.FileFilter;

/**
 * 获取一个目录中符合条件的部分子项
 * 使用重载的listFiles方法,需要传入一个额外的文件过滤器
 * 文件的过滤器是一个接口:FileFilter
 */
public class FileDemo7 {
    
    
    public static void main(String[] args) {
    
    
        File file = new File(".");
        /*
        获取名字以“.”开头的子项
         */
        File[] subs = file.listFiles(new FileFilter() {
    
    
            @Override
            public boolean accept(File pathname) {
    
    
                System.out.println("正在过滤"+pathname.getName());
                return pathname.getName().startsWith(".");
            }
        });
        for(File sub:subs){
    
    
            System.out.println(sub.getName());
        }
    }
}

二、RandomAccessFile

1、顺序读写方法

(1)、Java文件模型
在硬盘上文件是byte by byte存储的,是数据的集合

(2)、打开文件
有两种模式“rw”(读写)、“r”(只读)
RandomAccessFile raf = new RandomAccessFile(file,“rw”);
打开文件时候默认文件指针在开头pointer=0

(3)、写入方法
raf.write(int)可以将整数的“低八位”写入到文件中,同时指针自动移动到下一个位置,准备再次写入

(4)、读取文件
int b = raf.read()从文件中读取一个byte(8位)填充到int的低八位,高24位为0,返回值范围正数:0~255,如果返回-1表示读取到了文件末尾!每次读取后自动移动文件指针,准备下次读取

(5)、文件读写完一定关闭文件
如果不关闭,可能遇到一些意想不到的错误,根据具体操作平台不同会有不同。在使用过程中,切忌文件读写完成后要关闭文件

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * java.io.RandomAccessFile用来读写文件数据
 * RAF是基于指针进行读写的,即RAF总是在指针指向的位置读写字节,并且读写后指针会自动向后移动
 * RAF既可以读取文件数据也可以向文件中写入数据
 */
public class RandomAccessFileDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
        RandomAccessFile(String path,String mode)
        RandomAccessFile(File file,String mode)
        第二个参数为模式:常用的有   r:只读模式   rw:读写模式
        注:当文件不存在时会自动创建,但目录不存在时不会自动创建目录
         */
        RandomAccessFile raf = new RandomAccessFile("demo.dat","rw");
        /*
        void write(int d)
        写出给定的int值对应的2进制的低八位
                                     vvvvvvvv
        1:00000000 00000000 00000000 00000001
        -1:11111111 11111111 11111111 11111111
        255:00000000 00000000 00000000 11111111
        256:00000000 00000000 00000001 00000000
        a:97
         */
        raf.write(97);
        System.out.println("写入完毕!"); //多次运行是从头开始写,不会在之前内容后添加
        raf.close();

   }
}

2、基于缓存的写方法

方法 功能
void write(byte[] b) 从当前指针开始,将b.length个字节从指定字节数组写入到文件中
void write(byte[] b,int off,int len) 指针从off处开始,将len个字节从指定数组中写入到文件中
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * java.io.RandomAccessFile用来读写文件数据
 * RAF是基于指针进行读写的,即RAF总是在指针指向的位置读写字节,并且读写后指针会自动向后移动
 * RAF既可以读取文件数据也可以向文件中写入数据
 */
public class RandomAccessFileDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
        RandomAccessFile(String path,String mode)
        RandomAccessFile(File file,String mode)
        第二个参数为模式:常用的有   r:只读模式   rw:读写模式
        注:当文件不存在时会自动创建,但目录不存在时不会自动创建目录
         */
        RandomAccessFile raf = new RandomAccessFile("demo.dat","rw");
        /*
        void write(int d)
        写出给定的int值对应的2进制的低八位
                                     vvvvvvvv
        1:00000000 00000000 00000000 00000001
        -1:11111111 11111111 11111111 11111111
        255:00000000 00000000 00000000 11111111
        256:00000000 00000000 00000001 00000000
        a:97
         */
        raf.write(97);
        System.out.println("写入完毕!"); //多次运行是从头开始写,不会在之前内容后添加
        raf.close();

   }
}

3、基于缓存的读方法

方法 功能
int read(byte[] b) 读取文件中的byte数据填充到buf数组中尽可能多的读取数据填充,返回值是读取的byte数量,返回值区间:(0,buf.legth)>0;如果返回-1表示读取到文件末尾了
int read(byte[] b,int off,int len) 将最多len个字节从文件读入字节数组
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读取文件数据
 */
public class RandomAccessFile1 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile raf = new RandomAccessFile("demo.dat","r");
        /*
        int read()
        读取一个字节,并以10进制的int型返回
        若返回值为-1,则表示读取到了文件末尾
         */
        int d = raf.read();
        System.out.println(d);
        raf.close();
    }
}

4、随机读写方法

方法 功能
void seek(long pos) 设置到此文件开头的指针偏移量,从该位置开始读取或写入操作
ins skipBytes(int n) 尝试跳过输入的n个字节以丢弃跳过的字节
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 *
 * RAF提供了方便读写基本类型数据的方法
 */
public class RandomAccessFileDemo2 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile raf = new RandomAccessFile("raf1.dat","rw");

        /*
        long getFilePointer()
        获取当前RAF的指针位置
         */
        System.out.println("指针位置:"+raf.getFilePointer());

        /*
        向文件中写入一个int最大值
                                   vvvvvvvv
        01111111 11111111 11111111 11111111
         */
        int max = Integer.MAX_VALUE;
        raf.write(max>>>24);
        raf.write(max>>>16);
        raf.write(max>>>8);
        raf.write(max);

        raf.writeInt(max);

        raf.writeLong(123L);

        raf.writeDouble(123.123);

        System.out.println("指针位置:"+raf.getFilePointer());
        //EOFException:end of file
        //int i = raf.readInt(); //指针在最后一位,读的话,因为指针在最后一位没有数据,所以会报EOFException异常
        //System.out.println(i);

        /*
        void seek(long pos)
         */
        raf.seek(0);
        System.out.println("指针位置:"+raf.getFilePointer());
        int i = raf.readInt();
        System.out.println(i);

        raf.seek(8);
        long l = raf.readLong();
        System.out.println(l);

        double d = raf.readDouble();
        System.out.println(d);

        raf.seek(0);
        l = raf.readLong();
        System.out.println(l);

        raf.close();
    }
}

案例一:复制文件

import java.io.IOException;
import java.io.RandomAccessFile;

public class CopyDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        /*
        创建一个RAF读取原文件,再创建一个RAF向目标文件中写出
        顺序从原文件中读取每一个字节并写入到目标文件中即可
         */
        RandomAccessFile src = new RandomAccessFile("image.png","r");
        RandomAccessFile desc = new RandomAccessFile("image_py.png","rw");
        int d = -1;
        long start = System.currentTimeMillis();
        while ((d=src.read())!=-1){
    
    
            desc.write(d);
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕!耗时:"+(end-start)+"毫秒");
        src.close();
        desc.close();
    }
}

案例二:提高读写效率

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 若想提高读写效率,可以通过提高每次读写的数据量来减少读写的次数
 */
public class CopyDemo1 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile src = new RandomAccessFile("image.png","r");
        RandomAccessFile desc = new RandomAccessFile("image01.png","rw");
        /*
        int read(byte[] data)
        一次性尝试读取给定的字节数组总长度的字节量并存入到该数组中,返回值为实际读取到的字节量
        若返回值为-1,则表示本次没有读取到任何数据(文件末尾)
         */
        //10k
        byte[] buf = new byte[1024*10];
        int len = -1;
        long start = System.currentTimeMillis(); //记录写入开始时间
        while ((len = src.read(buf))!=-1){
    
    
            /*
            void write(byte[] data)
            一次性将给定的字节数组中的所有字节写出
            void write(bytr[] d,int start,int len)
            将给定数组从下标start处开始的连续len个字节一次性写出
             */
            desc.write(buf,0,len);
        }
        long end = System.currentTimeMillis(); //记录写入结束时间
        System.out.println("写出完毕!耗时:"+(start-end)+"ms");
        src.close();
        desc.close();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45138120/article/details/124780243