程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> 多線程-對於RandomAccessFile的seek函數的一些疑問?

多線程-對於RandomAccessFile的seek函數的一些疑問?

編輯:編程解疑
對於RandomAccessFile的seek函數的一些疑問?

seek就是查詢的意思,可以根據文件中的字節進行查詢數據(不知道這麼說對不對)

下面這個函數中

    private void setThreadBreakpoint(
            File file, 
            File tempFile,
            long contentLength, 
            long[] startPos, 
            long[] endPos) {
        RandomAccessFile tempFileFos = null;
        try {
            if (file.exists()) {
                System.out.println("file " + fileName + " has exists!");

                long localFileSize = file.length();
                // 下載的目標文件已存在,判斷目標文件是否完整
                if (localFileSize < contentLength) {
                    System.out.println("Now download continue ... ");

                    tempFileFos = new RandomAccessFile(tempFile, "rw");
                    // 遍歷目標文件的所有臨時文件,設置斷點的位置,即每個臨時文件的長度
                    for (int i = 0; i < threadNum; i++) {
                        tempFileFos.seek(4 + 24 * i + 8);
                        endPos[i] = tempFileFos.readLong();

                        tempFileFos.seek(4 + 24 * i + 16);
                        startPos[i] = tempFileFos.readLong();
                    }
                } else {
                    System.out.println("This file has download complete!");
                }

            } else {
                // 如果下載的目標文件不存在,則創建新文件
                file.createNewFile();
                tempFile.createNewFile();
                tempFileFos = new RandomAccessFile(tempFile, "rw");
                tempFileFos.writeInt(threadNum);

                for (int i = 0; i < threadNum; i++) {

                    // 創建子線程來負責下載數據,每段數據的起始位置為(threadLength * i)
                    startPos[i] = threadLength * i;
                    tempFileFos.writeLong(startPos[i]);

                    /*
                     * 設置子線程的終止位置,非最後一個線程即為(threadLength * (i + 1) - 1)
                     * 最後一個線程的終止位置即為下載內容的長度
                     */
                    if (i == threadNum - 1) {
                        endPos[i] = contentLength;
                    } else {
                        endPos[i] = threadLength * (i + 1) - 1;
                    }
                    // end position
                    tempFileFos.writeLong(endPos[i]);
                    // current position
                    tempFileFos.writeLong(startPos[i]);
                }
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            try {
                tempFileFos.close();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
        }
    }

這個循環方法體裡

 // 遍歷目標文件的所有臨時文件,設置斷點的位置,即每個臨時文件的長度
                    for (int i = 0; i < threadNum; i++) {
                        tempFileFos.seek(4 + 24 * i + 8);
                        endPos[i] = tempFileFos.readLong();
                        tempFileFos.seek(4 + 24 * i + 16);
                        startPos[i] = tempFileFos.readLong();
                    }

這句話

 tempFileFos.seek(4 + 24 * i + 8);

這裡面seek的參數是根據什麼確定的?

最佳回答:


首先更正一下,seek函數的作用是從文件起始位置開始計算,將文件指針定位到seek所指向的位置。
這個臨時文件的格式應該是:
線程數(4字節)
線程1起始位置(8字節)
線程1結束位置(8字節)
線程1當前位置(8字節)

線程2起始位置(8字節)
線程2結束位置(8字節)
線程2當前位置(8字節)

.....
線程n起始位置(8字節)
線程n結束位置(8字節)
線程n當前位置(8字節)

tempFileFos.seek(4 + 24 * i + 8); 的含義是偏移到:
線程數(4字節) + 24(起始位置8字節+結束位置8字節+當前位置8字節) × 當前第i個線程 + 線程i的起始位置8字節 = 當前第i個線程結束位置數據在文件中的偏移

tempFileFos.seek(4 + 24 * i + 16); 的含義是偏移到:
線程數(4字節) + 24(起始位置8字節+結束位置8字節+當前位置8字節) × 當前第i個線程 + 16(線程i的起始位置8字節 + 線程i的終止位置8字節) = 當前第i個線程當前位置數據在文件中的偏移

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved