Junior sister learning java IO: File copy and File filter

brief introduction

For a linux command thing, my younger martial sister has to ask me to teach her how to use java to realize it. Alas, I feel powerless to stand such a good younger martial sister. It's really hard to be a elder martial brother.

Using java to copy files

Today, my younger martial sister found me: elder martial brother F, can you tell me how to copy the document?

Copy file? Isn't it a very simple thing? If you have read access to the file, that's all you need.

cp www.flydean.com www.flydean.com.back

Of course, if it is a directory, two parameters can be added to traverse and force copying:

cp -rf srcDir distDir

Such a simple linux command, don't tell me you won't.

Little sister smiled: elder martial brother F, I don't want to use linux command, I just want to use java to implement it. Am I not learning Java? Of course, you need to find a chance to practice. Teach me quickly.

In that case, I'll start. There are actually three ways to copy files in java. You can use the traditional method of reading and writing files, or the latest NIO method.

Using traditional methods is not as fast as NIO or as simple as NIO. Let's see how to use traditional methods of file reading and writing to copy files:

    public  void copyWithFileStreams() throws IOException
        File fileToCopy = new File("src/main/resources/www.flydean.com");
        File newFile = new File("src/main/resources/www.flydean.com.back");
        try(FileOutputStream output = new FileOutputStream(newFile);FileInputStream input = new FileInputStream(fileToCopy)){
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) > 0)
                output.write(buf, 0, bytesRead);

In the above example, we first define two files, then generate the OutputStream and InputStream from the two files, and finally read the data from the input in the form of byte stream to the OutputStream, and finally complete the copy of the file.

The traditional File IO copy is cumbersome and slow. Let's take a look at how to use NIO to complete this process:

public  void copyWithNIOChannel() throws IOException
        File fileToCopy = new File("src/main/resources/www.flydean.com");
        File newFile = new File("src/main/resources/www.flydean.com.back");

        try(FileInputStream inputStream = new FileInputStream(fileToCopy);FileOutputStream outputStream = new FileOutputStream(newFile)){
            FileChannel inChannel = inputStream.getChannel();
            FileChannel outChannel = outputStream.getChannel();
            inChannel.transferTo(0, fileToCopy.length(), outChannel);

As we mentioned before, a very important concept in NIO is channel. By building the channel channels of source and target files, you can copy directly at the channel level. As shown in the above example, we call in channel.transferto to to complete the copy.

Finally, there is a simpler way to copy NIO files:

public  void copyWithNIOFiles() throws IOException
        Path source = Paths.get("src/main/resources/www.flydean.com");
        Path destination = Paths.get("src/main/resources/www.flydean.com.back");
        Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);

Directly use the copy method provided by the tool class Files.

Using File filter

Great, younger martial sister adores: elder martial brother F, I have another requirement, that is, I want to delete the log file ending with. Log in a directory. Is this requirement very common? How does senior brother f usually operate?

Generally, I can handle this operation with one linux command. If I can't handle it, I use two commands:

rm -rf *.log

Of course, if necessary, we can also use java to implement it.

java provides two filters that can be used to implement this function.

These two Filter are java.io.FilenameFilter and java.io.FileFilter:

public interface FilenameFilter {
    boolean accept(File dir, String name);
public interface FileFilter {
    boolean accept(File pathname);

Both interfaces are functional, so their implementation can be directly replaced by lambda expressions.

The difference between the two is that FilenameFilter filters the file name and the directory where the file is located. And FileFilter directly filters the target file.

There is no concept of directory in java. A directory is also represented by File.

The above two are very similar. Let's take FilenameFilter as an example to see how to delete. log files:

public void useFileNameFilter()
        String targetDirectory = "src/main/resources/";
        File directory = new File(targetDirectory);

        //Filter out all log files
        String[] logFiles = directory.list( (dir, fileName)-> fileName.endsWith(".log"));

        //If no log file found; no need to go further
        if (logFiles.length == 0)

        //This code will delete all log files one by one
        for (String logfile : logFiles)
            String tempLogFile = targetDirectory + File.separator + logfile;
            File fileDelete = new File(tempLogFile);
            boolean isdeleted = fileDelete.delete();
            log.info("file : {} is deleted : {} ", tempLogFile , isdeleted);

In the above example, we pass in the Filter created by lambda expression through the directory.list method to achieve the filtering effect.

Finally, we will delete the filtered file. Achieved the goal.


My two problems have been solved. I hope I can not see her again today.

Examples of this article https://github.com/ddean2009/learn-java-io-nio

Author of this article: the flydean program

Link to this article: http://www.flydean.com/io-file-copy-file-filter/

Source: flydean's blog

Welcome to my official account: the procedures, the more wonderful things waiting for you!

Tags: Programming Java Linux Lambda github

Posted on Mon, 18 May 2020 19:53:45 -0400 by MnilinM