關於檔案讀寫使用RandomAccessFile類的一些簡單操作

weixin_44168259發表於2020-11-01

最近接觸到了一些關於檔案生成以及檔案內容寫入的工作任務,關於檔案的一些方法常用的是 java.io.File包中的一些方法。這些方法是在java1.0的時候提供的。然後在File類的註釋中看到了這個包java.nio.file.Files;隨後檢視了一下這個包。簡單瞭解了一下

File

/**
 * An abstract representation of file and directory pathnames.
 .......
* <h3>Interoperability with {@code java.nio.file} package</h3>
 *
 * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
 * package defines interfaces and classes for the Java virtual machine to access
 * files, file attributes, and file systems. This API may be used to overcome
 * many of the limitations of the {@code java.io.File} class.
 * The {@link #toPath toPath} method may be used to obtain a {@link
 * Path} that uses the abstract path represented by a {@code File} object to
 * locate a file. The resulting {@code Path} may be used with the {@link
 * java.nio.file.Files} class to provide more efficient and extensive access to
 * additional file operations, file attributes, and I/O exceptions to help
 * diagnose errors when an operation on a file fails.
 *
 * @author  unascribed
 * @since   JDK1.0
 */

public class File
    implements Serializable, Comparable<File>
{
	.....
}

從這段註釋的說明中可以看出Files類是對原File類的一些操作的擴充套件。

Files

/**
 * This class consists exclusively of static methods that operate on files,
 * directories, or other types of files.
 *
 * <p> In most cases, the methods defined here will delegate to the associated
 * file system provider to perform the file operations.
 *
 * @since 1.7
 */

public final class Files {
    private Files() { }
    
....
}

這個包是nio下的關於檔案操作的一系列類似於工具包的類。這個類中只包含了對檔案,目錄和其他型別的檔案操作的靜態方法。

查了 一下關於這個類的使用是與java.nio.file.Path一起使用的。

關於Path類是可以使用在多執行緒的情況下。

/**
 * An object that may be used to locate a file in a file system. It will
 * typically represent a system dependent file path.
 .....
  * <h2>Concurrency</h2>
 * <p> Implementations of this interface are immutable and safe for use by
 * multiple concurrent threads.
 *
 * @since 1.7
 * @see Paths
 */
public interface Path
    extends Comparable<Path>, Iterable<Path>, Watchable
{
    /**
     * Returns the file system that created this object.
     *
     * @return  the file system that created this object
     */
    FileSystem getFileSystem();
	.....
}

Path是一個介面,有2個實現類。

AbstractPath、ZipPath;

File的基本操作建立檔案

/**
 * 指定路徑下開啟檔案,如果檔案不存在就建立一個檔案
 */
File file = new File("F:\\test\\", "generatorFile.txt");
        if (!file.exists()) {
            try {
                if (!file.createNewFile()) {
                    System.out.println("檔案建立失敗,或者已經存在");
                }
            } catch (IOException e) {
                System.out.println(e);
                return;
            }
        }
----------------------------------

關於檔案內容處理,在網上找到了一個randomAccessFile類,可以在檔案中覆蓋指定位置的內容,也可以在尾部追加內容。

比較方便的一個檔案操作類。

RandomAccessFile randomAccessFile = null;
        try {
            //對rw是檔案操作的操作模式
            randomAccessFile = new RandomAccessFile(file, "rw");
        } catch (FileNotFoundException e) {
            System.out.println("檔案不存在");
        }
        randomAccessFile.seek(randomAccessFile.length());
        randomAccessFile.write("abcdcd".getBytes());
        randomAccessFile.close();
操作符號介紹
r以只讀的方式開啟文字,不能用write方法寫入資料
rw允許對檔案進行讀寫操作
rws寫操作的時候,同步的重新整理到磁碟,重新整理內容和後設資料
rwd寫操作操作,同步的重新整理到磁碟,重新整理內容
/**
....
* @param      file   the file object
     * @param      mode   the access mode, as described
     *                    <a href="#mode">above</a>
     * @exception  IllegalArgumentException  if the mode argument is not equal
     *               to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
     *               <tt>"rwd"</tt>
     * @exception FileNotFoundException
     *            if the mode is <tt>"r"</tt> but the given file object does
     *            not denote an existing regular file, or if the mode begins
     *            with <tt>"rw"</tt> but the given file object does not denote
     *            an existing, writable regular file and a new regular file of
     *            that name cannot be created, or if some other error occurs
     *            while opening or creating the file
     * @exception  SecurityException         if a security manager exists and its
     *               {@code checkRead} method denies read access to the file
     *               or the mode is "rw" and the security manager's
     *               {@code checkWrite} method denies write access to the file
     * @see        java.lang.SecurityManager#checkRead(java.lang.String)
     * @see        java.lang.SecurityManager#checkWrite(java.lang.String)
     * @see        java.nio.channels.FileChannel#force(boolean)
     * @revised 1.4
     * @spec JSR-51
     */
    public RandomAccessFile(File file, String mode)
        throws FileNotFoundException
    {
     ...
    }

RandomAccessFile類的幾個常用方法

seek()指定檔案的游標位置,你的游標位置,就是下次讀檔案資料的時候從該位置讀取,寫入的資料也是從這個位置寫,但是寫入的資料會覆蓋之前的資料
getFilePointer()返回當前檔案的偏移量,以位元組為單位。也就是檔案內容游標的長度。
length()獲取檔案內容的長度,以位元組為單位
read()有多個read()的過載方法可以獲取指定長度的資料
write()可以read()方法相反,可以在檔案中寫入指定長度的資料。
   /**
     * Returns the current offset in this file.
     *
     * @return     the offset from the beginning of the file, in bytes,
     *             at which the next read or write occurs.
     * @exception  IOException  if an I/O error occurs.
     */
    public native long getFilePointer() throws IOException;

Example:
randomAccessFile.seek(3);      
System.out.println(randomAccessFile.getFilePointer());
返回輸出3;
------------------------------
    RandomAccessFile randomAccessFile;
        try {
            randomAccessFile = new RandomAccessFile(file, "rws");
        } catch (FileNotFoundException e) {
            System.out.println("檔案不存在");
            return;
        }
//將游標指向檔案的開頭,寫入資料
        randomAccessFile.seek(0);
        randomAccessFile.write("abcde".getBytes());
        randomAccessFile.close();
//在檔案後面追加內容
 RandomAccessFile randomAccessFile;
        try {
            randomAccessFile = new RandomAccessFile(file, "rws");
        } catch (FileNotFoundException e) {
            System.out.println("檔案不存在");
            return;
        }

        randomAccessFile.seek(randomAccessFile.length());
        randomAccessFile.write("追加內容abcde".getBytes());
        randomAccessFile.close();
//讀取檔案內容

        byte[] bytes = new byte[1024];
//從檔案開頭讀取
        randomAccessFile.seek(0);
        while (randomAccessFile.read(bytes) > 0) {
            System.out.println(new String(bytes, 0, bytes.length));
        }
        randomAccessFile.close();

相關文章