⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_filefind.cpp

📁 类似Linux操作系统0.11版文件系统的文件系统设计和Windows下的操作程序
💻 CPP
字号:
#include "stdafx.h"
#include "UL_FileFind.h"
#include "UL_NameI.h"
#include "UL_Inode.h"
#include "UL_FileSys.h"
#include "UL_Buffer.h"

struct find_file
{
	char ff_parh[1024];
	unsigned short ff_idx;	// 当前索引
	unsigned short ff_num;	// 文件总数
}ffile;

// 查找文件夹下的文件
extern int findfirstfile (const char *pathname, struct FIND_DATA* ff)
{
	int i, entries, block;
	struct m_inode *dir, *inode;
	struct buffer_head *bh;
	struct dir_entry *de, entry;

	if (!ff) return -ENOENT;

	// 根据路径名寻找到对应的i 节点,以及最顶端文件名及其长度。
	if (!(dir = namei (pathname)))
		return -ENOENT;

	strcpy(ffile.ff_parh, pathname);

	// 计算本目录中目录项项数entries。置空返回目录项结构指针。
	entries = dir->i_size / (sizeof (struct dir_entry));

	printk ("findfirstfile: dir->i_size = %d, entries = %d\n", dir->i_size, entries);

	// 如果该i 节点所指向的第一个直接磁盘块号为0,则返回NULL,退出。
	if (!(block = dir->i_zone[0]))
		return -ENOENT;

	// 从节点所在设备读取指定的目录项数据块,如果不成功,则返回NULL,退出。
	if (!(bh = bread (dir->i_dev, block)))
		return -ENOENT;

	// 在目录项数据块中搜索匹配指定文件名的目录项,首先让de 指向数据块,并在不超过目录中目录项数
	// 的条件下,循环执行搜索。
	i = 0;
	ffile.ff_num = 0;
	ffile.ff_idx = 0;

	de = (struct dir_entry *) bh->b_data;
	while (i < entries)
	{
		// 如果当前目录项数据块已经搜索完,还没有找到匹配的目录项,则释放当前目录项数据块。
		if ((char *) de >= BLOCK_SIZE + bh->b_data)
		{
			brelse (bh);
			bh = NULL;
			// 在读入下一目录项数据块。若这块为空,则只要还没有搜索完目录中的所有目录项,就跳过该块,
			// 继续读下一目录项数据块。若该块不空,就让de 指向该目录项数据块,继续搜索。
			if (!(block = bmap (dir, i / DIR_ENTRIES_PER_BLOCK)) ||
				!(bh = bread (dir->i_dev, block)))
			{
				i += DIR_ENTRIES_PER_BLOCK;
				continue;
			}
			de = (struct dir_entry *) bh->b_data;
		}
		if (de->inode)
		{
			if (!ffile.ff_num)
				entry = *de;
			ffile.ff_num++;
		}
		// 否则继续在目录项数据块中比较下一个目录项。
		de++;
		i++;
	}
	brelse (bh);

	ffile.ff_idx++;

	strcpy(ff->ff_name, entry.name);
	inode = iget(dir->i_dev ,entry.inode);
	ff->ff_mode = inode->i_mode;
	iput(inode);
	iput(dir);

	// printk ("FindFirstFile: ff_path=%s, ff_idx=%d, ff_num=%d\n", ffile.ff_parh, ffile.ff_idx, ffile.ff_num);

	return 0;
}
// 查找下一个
int findnextfile (int handle, struct FIND_DATA* ff)
{
	int i, idx, entries, block;
	struct m_inode *dir, *inode;
	struct buffer_head *bh;
	struct dir_entry *de, entry;

	if (!ff) return -ENOENT;

	if (!ffile.ff_num) return -ENOENT;

	if (ffile.ff_idx>=ffile.ff_num)
		return -ENOENT;

	// 根据路径名寻找到对应的i 节点,以及最顶端文件名及其长度。
	if (!(dir = namei (ffile.ff_parh)))
		return -ENOENT;

	// 计算本目录中目录项项数entries。置空返回目录项结构指针。
	entries = dir->i_size / (sizeof (struct dir_entry));

	// 如果该i 节点所指向的第一个直接磁盘块号为0,则返回NULL,退出。
	if (!(block = dir->i_zone[0]))
		return -ENOENT;

	// 从节点所在设备读取指定的目录项数据块,如果不成功,则返回NULL,退出。
	if (!(bh = bread (dir->i_dev, block)))
		return -ENOENT;

	// 在目录项数据块中搜索匹配指定文件名的目录项,首先让de 指向数据块,并在不超过目录中目录项数
	// 的条件下,循环执行搜索。
	i = 0;
	idx = 0;

	de = (struct dir_entry *) bh->b_data;
	while (i < entries)
	{
		// 如果当前目录项数据块已经搜索完,还没有找到匹配的目录项,则释放当前目录项数据块。
		if ((char *) de >= BLOCK_SIZE + bh->b_data)
		{
			brelse (bh);
			bh = NULL;
			// 在读入下一目录项数据块。若这块为空,则只要还没有搜索完目录中的所有目录项,就跳过该块,
			// 继续读下一目录项数据块。若该块不空,就让de 指向该目录项数据块,继续搜索。
			if (!(block = bmap (dir, i / DIR_ENTRIES_PER_BLOCK)) ||
				!(bh = bread (dir->i_dev, block)))
			{
				i += DIR_ENTRIES_PER_BLOCK;
				continue;
			}
			de = (struct dir_entry *) bh->b_data;
		}
		if (de->inode)
		{
			idx++;
			if (idx>ffile.ff_idx)
			{
				entry = *de;
				ffile.ff_idx++;
				break;
			}
		}
		// 否则继续在目录项数据块中比较下一个目录项。
		de++;
		i++;
	}
	brelse (bh);

	strcpy(ff->ff_name, entry.name);
	inode = iget(dir->i_dev ,entry.inode);
	ff->ff_mode = inode->i_mode;

	iput(inode);
	iput (dir);

	// printk ("FindNextFile: ff_path=%s, ff_idx=%d, ff_num=%d\n", ffile.ff_parh, ffile.ff_idx, ffile.ff_num);

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -