CSDNRGY 2016-12-16 08:18 采纳率: 87.5%
浏览 1816
已采纳

对于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的参数是根据什么确定的?

  • 写回答

1条回答 默认 最新

  • tang_cheng 2016-12-16 08:35
    关注

    首先更正一下,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个线程当前位置数据在文件中的偏移

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办