ext2read

 

最近在采用ext2read读取读硬盘里ext2文件系统分区文件的数据,该开源库是读取MBR分区下的各分区数据,对ext2read库里面的主要接口大概整理下:

1.int Ext2Read::scan_partitions(char *path, int diskno)          
scanMBR分区分区头及4个分区表,获取各分区数据(分区起始扇区,分区总的扇区数,如果是GPT分区,需根据情况分析。

2. Ext2Partition::Ext2Partition(lloff_t size, lloff_t offset, int ssize, FileHandle phandle, LogicalVolume *vol)
 size:分区末尾扇区号
offset:分区起始扇区号
phandle:文件句柄
LogicalVolume :这个我没有用到(NULL),应该是有无逻辑分区。。。
该构造函数可以获取root节点的inode表中数据(Ext2File)
GPT分区只要确定了分区起始扇区和分区扇区数(该数值貌似库里面并没有用到),就可调用此接口,如果分区的镜像文件直接读取的分区数据,offset置为0即可。

3. bool Ext2CopyProcess::copy_file(QString &destfile, Ext2File *srcfile)
该接口为拷贝文件到自己设定的路径,不过它实现的是从当前目录下拷贝文件,而不是从根目录搜索文件,再保存。其中srcfile为当前文件的inode表项

4.bool Ext2CopyProcess::copy_folder(QString &path, Ext2File *parent)
同样,从当前目录下拷贝目录中的文件夹。parent为当前目录的的inode表项。

如若从root开始搜索文件
Ext2File *Ext2Partition::read_dir(EXT2DIRENT *dirent)读取目录文件的数据块数据,并获取一个文件/目录的项的inode表项

if(!dirent->dirbuf)
    {
        dirent->dirbuf = (EXT2_DIR_ENTRY *) new char[blocksize];   //new出一个数组
        if(!dirent->dirbuf)
            return NULL;
        ret = read_data_block(&dirent->parent->inode, dirent->next_block, dirent->dirbuf);
        if(ret < 0)
            return NULL;

        dirent->next_block++;
    }

    again:
    if(!dirent->next)
        dirent->next = dirent->dirbuf;
    else
    {
        pos = (char *) dirent->next;
        dirent->next = (EXT2_DIR_ENTRY *)(pos + dirent->next->rec_len);
        if(IS_BUFFER_END(dirent->next, dirent->dirbuf, blocksize))
        {
            dirent->next = NULL;
            if(dirent->read_bytes < dirent->parent->file_size)
            {
                //LOG("DIR: Reading next block %d parent %s\n", dirent->next_block, dirent->parent->file_name.c_str());
                ret = read_data_block(&dirent->parent->inode, dirent->next_block, dirent->dirbuf);
                if(ret < 0)
                    return NULL;

                dirent->next_block++;
                goto again;
            }
            return NULL;
        }
    }

    dirent->read_bytes += dirent->next->rec_len;
    filename.assign(dirent->next->name, dirent->next->name_len);
    if((filename.compare(".") == 0) ||
       (filename.compare("..") == 0))
        goto again;                                                    //以上,读取目录文件中的一个文件夹/文件夹项,保存在dirent->next


    newEntry = read_inode(dirent->next->inode);     //读取该文件夹/文件项的inode表项内容
    if(!newEntry)
    {
        LOG("Error reading Inode %d parent inode %d.\n", dirent->next->inode, dirent->parent->inode_num);
        return NULL;
    }

    newEntry->file_type = dirent->next->filetype;
    newEntry->file_name = filename;

    return newEntry;                            //返回inode表项的内容(Ext2File )

 

如若需要从根目录下查找一个文件,需要多次调用read_dir,并判断是否是所要查找的文件夹/文件。 目录文件里面含有文件夹/文件标识,并通过判断文件夹/文件名称来判断就可以。

 

 

 

调试过程中遇到的问题:

读取数据块中的数据时,存放数据的内存区域必须要大于等于blocksize,否则保存数据时会出错。

即int Ext2Partition::read_data_block(EXT2_INODE *ino, lloff_t lbn, void *buf)中buf new出来的空间必须大于等于blocksize,其实blocksize就可以了,如果读一次即存储的话。如果new char[filesize],在数据边读边存情况下没有问题,当文件大小低于blocksize时,读取一个数据块就会出错。

 

你可能感兴趣的:(ext2read)