Java實現(xiàn)文件讀取操作

Java實現(xiàn)文件操作方式有很多,這里寫了幾個小工具,需要的話可以直接拷貝使用,或者優(yōu)化后使用。

基本概念

  • FileChannel是一個用讀寫,映射和操作一個文件的通道,也是Java NIO對應(yīng)于磁盤等存儲設(shè)備文件操作的通道。除了讀寫操作之外,還有裁剪特定大小文件truncate(),強(qiáng)制在內(nèi)存中的數(shù)據(jù)刷新到硬盤中去force(),對通道上鎖lock()等功能。

  • RandomAccessFile類的主要功能是完成隨機(jī)讀取功能,可以讀取指定位置的內(nèi)容。
    之前的File類只是針對文件本身進(jìn)行操作的,而如果要想對文件內(nèi)容進(jìn)行操作,則可以使用RandomAccessFile類,此類屬于隨機(jī)讀取類,可以隨機(jī)讀取一個文件中指定位置的數(shù)據(jù)。

  • 在使用FileChannel之前,必須先打開它。但是,我們無法直接打開一個FileChannel,需要通過使用一個InputStream、OutputStream或RandomAccessFile來獲取一個FileChannel實例。

寫文件操作

    /**
     * 寫文件
     * @param fileName
     * @throws IOException
     */
    public void doWrite(String fileName) throws IOException {
        outFile = new RandomAccessFile(fileName, "rw");
        outChannel = outFile.getChannel();
        String newData = "New String to write to file... \n";
        buf.clear();
        buf.put(newData.getBytes());
        buf.flip();
        while (buf.hasRemaining()){
            outChannel.write(buf);
        }
        outChannel.close();
        System.out.println("Write Over!\n");
    }

讀文件操作

    /**
     * 讀文件
     * @param fileName
     * @throws IOException
     */
    public void doRead(String fileName) throws IOException {
        inFile = new RandomAccessFile(fileName, "rw");
        inChannel = inFile.getChannel();
        int bytesRead = inChannel.read(buf);
        while (bytesRead != -1) {
            System.out.println("Read " + bytesRead);
            buf.flip();
            while (buf.hasRemaining()){
                System.out.print((char) buf.get());
            }
            buf.clear();
            bytesRead = inChannel.read(buf);
        }
        inFile.close();
    }

文件拷貝操作

    /**
     * 拷貝文件
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    public void doCopy(String sourceFile, String targetFile) throws IOException {
        inFile = new RandomAccessFile(sourceFile, "rw");
        inChannel = inFile.getChannel();
        RandomAccessFile bFile = new RandomAccessFile(targetFile, "rw");
        FileChannel outChannel = bFile.getChannel();
        inChannel.transferTo(0, inChannel.size(), outChannel);
        System.out.println("Copy over");
        inChannel.close();
    }
    /**
     * 按照行讀文件
     * @param fileName
     * @throws IOException
     */
    public void doReadLine(String fileName) throws IOException {
        inFile = new RandomAccessFile(fileName, "rw");
        int lineNum = 0;
        inFile.seek(lineNum);
        String line = "";
        while((line = inFile.readLine())!=null){
            line =  new String(line.getBytes("UTF-8"), "UTF-8");
            System.out.println(line);
        }
        inFile.close();
    }

特殊情況下倒序拷貝文件操作

    /**
     * 倒序拷貝文件
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    public void reverseCopy(String sourceFile, String targetFile) throws IOException {
        inFile = new RandomAccessFile(sourceFile, "r");
        inChannel = inFile.getChannel();
        outFile = new RandomAccessFile(targetFile, "rw");
        outChannel = outFile.getChannel();
        // 文件長度
        long len = inFile.length();
        System.out.println("文件開始指針為"+0);
        //指針是從0到length-1
        long nextEnd =  len - 1;
        String line;
        //seek到最后一個字符
        inFile.seek(nextEnd);
        int c = -1;
        while (nextEnd >= 0) {
            c = inFile.read();
            //只有行與行之間才有\(zhòng)r\n,這表示讀到每一行上一行的末尾的\n,而執(zhí)行完read后,指針指到了這一行的開頭字符
            if (c == '\n')
            {
                line =  new String(inFile.readLine().getBytes("UTF-8"), "UTF-8");
                System.out.println(line);
                writeLine(line, outChannel);
            }
            // 當(dāng)文件指針退至文件開始處,輸出第一行
            if (nextEnd == 0) {
                //不需要為下次做準(zhǔn)備了,但是因為read()方法指針從0到了1,需重置為0
                inFile.seek(0);
                line =  new String(inFile.readLine().getBytes("UTF-8"), "UTF-8");
                System.out.println(line);
                writeLine(line, outChannel);
            } else {
                //為下一次循環(huán)做準(zhǔn)備
                inFile.seek(nextEnd-1);
            }
            nextEnd--;
        }
        System.out.println("Reverse Copy over");
        outChannel.close();
        inChannel.close();
    }

    private void writeLine(String line, FileChannel outChannel)throws IOException{
        // 寫入文件
        line += "\n";
        buf.clear();
        buf.put(line.getBytes());
        buf.flip();
        while (buf.hasRemaining()){
            outChannel.write(buf);
        }
    }

完整代碼

源碼參考

小技巧

文件按照行倒序輸出可以使用這個命名

perl -e 'print reverse <>' filename
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容