Java SE (16): File, RandomAccessFile


Java SE

Including File class introduction, viewing files or directories, creating new files or directories, deleting files or directories, viewing directory contents, FileFilter interface, sequential read and write methods, cache-based write methods, cache-based read methods, and random read and write methods.


1. File

1. Introduction to File class

(1) java.io.File is used to represent files (directories), and files and directories on the hard disk can be manipulated in the program through the File class

(2) Each instance of File can represent a file or directory in the file system

(3) Using File can:

  • Access file or directory attributes (such as: size, name, modification time, etc.)
  • Manipulate files or directories (create, delete files and directories)
  • access everything in the directory

(4) Cannot access the content of the file

2. View files or directories

method Function
long length() Returns the size of the file in bytes
long lastModified() Returns the time when the file was last modified
String getName() Returns the name of a file or directory
String getPath() Returns a string of pathnames
boolean exists() Check if a file or directory exists
boolean isFile() Determine whether it is a standard file
boolean isDirectory() Determine whether it is a directory
boolean canRead() Judging whether it is readable
boolean canWrite() Determine whether it is writable
//项目所在路径下需存在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. Create a new file or directory

method Function
long mkdir() Create specified directory
long mkdirs() Create the specified directory, including creating a parent directory that is required but does not exist
String createNewFile() Create a new empty file

Create file code example:

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("文件已经存在!");
        }
    }
}

Create directory code example:

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. Delete a file or directory

method Function
boolean delete() delete file or directory

Delete file code example:

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("文件不存在!");
        }
    }
}

Delete directory code example:

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. View the content of the directory

method Function
String[] list() Returns an array of strings containing the names of the files and directories in the directory
String[] listFiles() Return files in directory
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 interface

A filter for pathnames, an instance of this interface can be passed to the listFiles(FileFilter) method of the File class

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. Sequential reading and writing method

(1), Java file model
The file on the hard disk is stored byte by byte, which is a collection of data

(2)
There are two modes of opening a file: "rw" (read-write), "r" (read-only)
RandomAccessFile raf = new RandomAccessFile(file,"rw");
when opening a file, the default file pointer is at the beginning pointer=0

(3) The writing method
raf.write(int) can write the "lower eight bits" of the integer into the file, and at the same time the pointer automatically moves to the next position, ready to be written again

(4), read the file
int b = raf.read() read a byte (8 bits) from the file and fill it into the lower eight bits of int, the upper 24 bits are 0, and the return value range is positive: 0~255, If it returns -1, it means that the end of the file has been read! Automatically move the file pointer after each read to prepare for the next read

(5) After reading and writing the file, you must close the file
. If you do not close the file, you may encounter some unexpected errors, which will vary depending on the specific operating platform. During use, do not close the file after reading and writing the file

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. Cache-based write method

method Function
void write(byte[] b) Writes b.length bytes from the specified byte array to the file, starting at the current pointer
void write(byte[] b,int off,int len) Starting from the pointer off, write len bytes from the specified array to the file
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. Cache-based read method

method Function
int read(byte[] b) Read the byte data in the file and fill it with as much read data as possible in the buf array. The return value is the number of bytes read, and the return value range: (0, buf.legth)>0; if it returns -1, it means read Fetched to the end of the file
int read(byte[] b,int off,int len) Read up to len bytes from the file into a byte array
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. Random read and write method

method Function
void seek(long pos) Sets the pointer offset to the beginning of this file at which to begin reading or writing operations
ins skipBytes(int n) Attempt to skip n bytes of input to discard skipped bytes
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();
    }
}

Case 1: copy files

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();
    }
}

Case 2: Improving Reading and Writing Efficiency

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();
    }
}

Guess you like

Origin blog.csdn.net/qq_45138120/article/details/124780243