Thao tác với tập tin và thư mục trong Java

1- Tổng quan

Trong thực tế rất thường xuyên bạn phải thao tác với các tập tin và thư mục trong hệ thống, các thao tác ở đây bao gồm thêm, xóa, đổi tên. Java cung cấp cho bạn 2 class để làm việc này:
  • java.io.File
  • java.nio.file.Files

java.io.File

Lớp java.io.File đại diện cho một tập tin (file) hoặc một thư mục (directory) của hệ thống, nó được đưa vào Java từ phiên bản 1.0

java.nio.file.Files

Phiên bản 7.0, Java bổ xung thêm lớp java.nio.file.Files, việc bổ xung này làm đơn giản hóa việc thao tác với các tập tin và thư mục, tất cả các phương thức của class này đều là tĩnh và tự nhiên (static & nature)
Trong bài hướng dẫn này tôi chỉ đề cập tới việc sử dụng lớp java.io.File, bạn có thể xem thêm java.nio.file.Files tại:
  • TODO Link? 11395

2- java.io.File

Lớp java.io.File đại diện cho một tập tin hoặc một thư mục trong hệ thống, nó đại diện cho một đường dẫn (pathname). Ví dụ dưới đây tạo một đối tượng File đại diện cho một đường dẫn trên Windows hoặc Unix:
// Window

File apath1 = new File("C:/mydocument/test.txt");

File apath2 = new File("C:/mydocument/java");

// Unix

File apath3 = new File("/mydocument/test.txt");

File apath3 = new File("/mydocument/java");
 
java.io.File có thể đại diện cho một đường dẫn (pathname) mà đường dẫn đó có thể không thực sự tồn tại trên hệ thống. Nếu tồn tại nó có thể là một thư mục (directory) hoặc là một tập tin (file).
Ví dụ đơn giản sau đây tạo một đối tượng File đại diện cho một đường dẫn, và kiểm tra sự tồn tại của nó, ghi ra các thông tin cơ bản nếu đường dẫn đó thực sự tồn tại:
FileInfoExample.java
package org.o7planning.filedirectory;

import java.io.File;
import java.util.Date;

public class FileInfoExample {

	public static void main(String[] args) {

		// Tạo một đối tượng File đại diện cho một đường dẫn.
		File apath = new File("C:/test/mytext.txt");

		// Kiểm tra sự tồn tại.
		System.out.println("Path exists? " + apath.exists());

		if (apath.exists()) {

			// Kiểm tra 'apath' có phải là một thư mục hay không?
			System.out.println("Directory? " + apath.isDirectory());

			// Kiểm tra 'apath' là một đường dẫn ẩn hay không?
			System.out.println("Hidden? " + apath.isHidden());

			// Tên đơn giản.
			System.out.println("Simple Name: " + apath.getName());

			// Đường dẫn tuyêt đối.
			System.out.println("Absolute Path: " + apath.getAbsolutePath());

			// Kiểm tra kích thước file (Theo đơn vị byte):
			System.out.println("Length (bytes): " + apath.length());

			// Thời điểm sửa lần cuối (mili giây)
			long lastMofifyInMillis = apath.lastModified();
			Date lastModifyDate = new Date(lastMofifyInMillis);

			System.out.println("Last modify date: " + lastModifyDate);

		}

	}

}

3- Tạo thư mục

Lớp File cung cấp 2 phương thức để tạo môt thư mục:
Phương thức Mô tả
public boolean mkdir() Tạo thư mục cho bởi đường dẫn. Chú ý thư mục chỉ được tạo ra nếu thư mục cha tồn tại.
public boolean mkdirs() Tạo thư mục cho bởi đường dẫn, bao gồm cả các thư mục cha nếu nó không tồn tại.
MakeDirExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class MakeDirExample {

	public static void main(String[] args) {

		File dir1 = new File("C:/test2/test3");

		System.out.println("Pathname: " + dir1.getAbsolutePath());
		System.out.println("Path Exists? " + dir1.exists());
		System.out.println("Parent Path Exists? " + dir1.getParentFile().exists());

		// Với mkdir(), thư mục chỉ được tạo ra nếu thư mục cha tồn tại.
		boolean created = dir1.mkdir();

		System.out.println("Directory created? " + created);

		System.out.println("--------------------");

		File dir2 = new File("C:/test2/test3/test4");

		System.out.println("Pathname: " + dir2.getAbsolutePath());
		System.out.println("Exists? " + dir2.exists());

		//  
		created = dir1.mkdirs();

		System.out.println("Directory created? " + created);
	}

}

4- Bộ lọc File (File Filter)

Lớp java.io.File cung cấp một vài phương thức để lấy ra danh sách các tập tin con và thư mục con trong một thư mục. Và sử dụng FileFilter để lọc các tập tin đó.
Phương thức Mô tả
static File[] listRoots() Trả về một mảng các đối tượng File là đại diện cho các thư mục gốc. Trong Windows nó sẽ là các ổ đĩa (C:, D:,..), trong Unix nó là /
File[] listFiles() Trả về một mảng các đối tượng File, là các tập tin và các thư mục con của thư mục hiện tại.
File[] listFiles(FilenameFilter filter) Trả về một mảng các đối tượng File, là các tập tin và các thư mục con của thư mục hiện tại, và phù hợp với bộ lọc FilenameFilter trên tham số.
File[] listFiles(FileFilter filter) Trả về một mảng các đối tượng File, là các tập tin và các thư mục con của thư mục hiện tại, và phù hợp với bộ lọc FileFilter trên tham số.
   
String[] list() Trả về một mảng các đường dẫn, là đường dẫn của các tập tin và đường dẫn của các thư mục con của thư mục hiện tại.
String[] list(FilenameFilter filter) Trả về một mảng các đường dẫn, là đường dẫn của các tập tin và đường dẫn của các thư mục con của thư mục hiện tại, và phù hợp với bộ lọc FiltenameFilter trên tham số.
Ví dụ liệt kê tất cả các thư mục gốc:
RootFilesExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class RootFilesExample {

    public static void main(String[] args) {


        File[] roots = File.listRoots();
        
        for(File root: roots)  {
            System.out.println(root.getAbsolutePath());
        }

    }

}
Ví dụ sau liệt kê ra tất cả các tập tin và thư mục con trực tiếp của một thư mục:
FileListExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class FileListExample {

    public static void main(String[] args) {
       
        System.out.println("File[] listFiles():\n");

        File dir = new File("C:/test");

        File[] children = dir.listFiles();

        for (File file : children) {
            System.out.println(file.getAbsolutePath());
        }

        System.out.println("\n-----------------------");
       
        System.out.println("String[] list():\n");

        String[] paths = dir.list();

        for (String path : paths) {
            System.out.println(path);
        }
    }

}

java.io.FileFilter

** FileFilter **
package java.io;


@FunctionalInterface
public interface FileFilter {
 
    boolean accept(File pathname);


}
Ví dụ đơn giản dưới đây sử dụng FileFilter để lọc ra các tập tin nằm trong một thư mục và có phần mở rộng là "txt":
TxtFileFilter.java
package org.o7planning.filedirectory;

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

public class TxtFileFilter implements FileFilter {

	// Chỉ chấp nhận 'pathname' là file và có 'phần mở rộng' (extension) là txt.
	@Override
	public boolean accept(File pathname) {

		if (!pathname.isFile()) {
			return false;
		}

		if (pathname.getAbsolutePath().endsWith(".txt")) {
			return true;
		}

		return false;
	}

}
FileFilterExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class FileFilterExample {

    public static void main(String[] args) {

        File dir = new File("C:/test");

        File[] txtFiles = dir.listFiles(new TxtFileFilter());

        for (File txtFile : txtFiles) {
            System.out.println(txtFile.getAbsolutePath());
        }
    }

}

java.io.FilenameFilter

** FilenameFilter **
package java.io;

@FunctionalInterface
public interface FilenameFilter {
    /**
     * Tests if a specified file should be included in a file list.
     *
     * @param   dir    the directory in which the file was found.
     * @param   name   the name of the file.
     * @return  <code>true</code> if and only if the name should be
     * included in the file list; <code>false</code> otherwise.
     */
    boolean accept(File dir, String name);

}

 
Ví dụ sử dụng FilenameFilter:
TxtFilenameFilter.java
package org.o7planning.filedirectory;

import java.io.File;
import java.io.FilenameFilter;

public class TxtFilenameFilter implements FilenameFilter {

	// Chấp nhận các đường dẫn (path) có hậu tố là '.txt'
	@Override
	public boolean accept(File dir, String name) {

		if (name.endsWith(".txt")) {
			return true;
		}

		return false;
	}

}
FilenameFilterExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class FilenameFilterExample {

    public static void main(String[] args) {

        File dir = new File("C:/test");

        File[] txtFiles = dir.listFiles(new TxtFilenameFilter());

        for (File txtFile : txtFiles) {
            System.out.println(txtFile.getAbsolutePath());
        }
    }

}

5- Liệt kê tất cả các file con

Lớp java.io.File cung cấp cho bạn vài phương thức để liệt kê các thư mục và các tập tin là "con trực tiếp" của thư mục hiện tại. Ví dụ dưới đây sử dụng đệ quy để liệt kê toàn bộ các thư mục hậu duệ (con,cháu,..) và các tập tin hậu duệ của một thư mục.
RecursiveFileExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class RecursiveFileExample {

	private void fetchChild(File file) {

		System.out.println(file.getAbsolutePath());

		if (file.isDirectory()) {

			File[] children = file.listFiles();

			for (File child : children) {
				// Đệ quy (Recursive)
				this.fetchChild(child);
			}
		}

	}

	public static void main(String[] args) {

		RecursiveFileExample example = new RecursiveFileExample();

		File dir = new File("C:/test");

		example.fetchChild(dir);

	}

}

6- Đổi tên (đường dẫn)

Sử dụng phương thưc rename() của lớp File, bạn có thể thay đổi tên (Hoặc cả đường dẫn) của một file hoặc thư mục. Nếu bạn đổi cả đường dẫn, hãy đảm bảo rằng thư mục cha mới đã tồn tại.

Đổi tên

Ví dụ đơn giản dưới đây đổi tên một tập tin (Hoặc thư mục) nhưng không thay đổi đường dẫn cha.
SimpleRenameExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class SimpleRenameExample {

    public static void main(String[] args) {

        File srcFile = new File("C:/test/test2/abc.txt");

        File destFile = new File("C:/test/test2/def.txt");

        boolean renamed = srcFile.renameTo(destFile);
       
        System.out.println("Renamed: "+ renamed);

    }

}

Đổi tên bao gồm cả đường dẫn cha:

Đổi tên và đổi cả đường dẫn cha, giống với hành động "Cut" một file hoặc một thư mục sang một thư mục khác và sau đó đổi tên.
Chú ý:  Với hệ điều hành Windows, phương thức File.rename() sẽ không hoạt động nếu bạn đổi đường dẫn từ ổ đĩa này sang ổ đĩa kia.
RenameAndPathExample.java
package org.o7planning.filedirectory;

import java.io.File;

public class RenameAndPathExample {

	public static void main(String[] args) {

		// File nguồn (Source file).
		File srcFile = new File("C:/test/test2/abc.txt");

		// File đích (Destination file).
		File destFile = new File("C:/test2/test3/defgh.txt");

		if (!srcFile.exists()) {
			System.out.println("Src File doest not exists");
			return;
		}

		// Tạo thư mục cha của file đích.
		destFile.getParentFile().mkdirs();

		boolean renamed = srcFile.renameTo(destFile);

		System.out.println("Renamed: " + renamed);

	}

}

Xem thêm các chuyên mục: