主题
SimpleDirectoryReader 是把本地文件加载进 LlamaIndex 最简单的方式。生产环境更可能要用的是众多 Reader 集成中的一个,但入门用 SimpleDirectoryReader 非常好。
支持的文件类型
默认情况下,SimpleDirectoryReader 会尝试读取它找到的任何文件,并都按纯文本处理。除了纯文本,它还显式支持下列文件类型(依据扩展名自动识别):
- .csv - 逗号分隔值
- .docx - Microsoft Word
- .epub - EPUB 电子书格式
- .hwp - 韩文字处理器(Hangul Word Processor)
- .ipynb - Jupyter Notebook
- .jpeg, .jpg - JPEG 图像
- .mbox - MBOX 邮件归档
- .md - Markdown
- .mp3, .mp4 - 音频与视频
- .pdf - 便携文档格式
- .png - 便携网络图像
- .ppt, .pptm, .pptx - Microsoft PowerPoint
你可能期望在这里看到 JSON,这个我们建议改用 JSON Loader。
用量
最基本的用法是传入一个 input_dir,它会加载该目录下所有支持的文件:
from llama_index.core import SimpleDirectoryReader
reader = SimpleDirectoryReader(input_dir="path/to/directory")
documents = reader.load_data()当要从目录加载大量文件时,也可以用并行处理来加载 Documents。注意 multiprocessing 在 Windows 与 Linux/MacOS 上的行为存在差异,multiprocessing 文档里有逐处说明(例如这里)。总之,Windows 用户可能看不到或只看到很少的性能提升,而 Linux/MacOS 用户加载同一批文件时则能看到这些收益。
...
documents = reader.load_data(num_workers=4)读取子目录
默认情况下,SimpleDirectoryReader 只读取目录顶层的文件。要读取子目录,请设置 recursive=True:
SimpleDirectoryReader(input_dir="path/to/directory", recursive=True)边加载边遍历文件
你也可以用 iter_data() 方法,在文件加载的过程中逐个处理它们
reader = SimpleDirectoryReader(input_dir="path/to/directory", recursive=True)
all_docs = []
for docs in reader.iter_data():
# <do something with the documents per file>
all_docs.extend(docs)限定要加载的文件
不必加载全部文件,你可以传入一份文件路径列表:
SimpleDirectoryReader(input_files=["path/to/file1", "path/to/file2"])或者用 exclude 传入一份要排除的文件路径列表:
SimpleDirectoryReader(
input_dir="path/to/directory", exclude=["path/to/file1", "path/to/file2"]
)还可以把 required_exts 设为一组扩展名,只加载这些扩展名的文件:
SimpleDirectoryReader(
input_dir="path/to/directory", required_exts=[".pdf", ".docx"]
)也可以用 num_files_limit 设定最多加载多少个文件:
SimpleDirectoryReader(input_dir="path/to/directory", num_files_limit=100)指定文件编码
SimpleDirectoryReader 假定文件是 utf-8 编码,但你可以通过 encoding 参数覆盖:
SimpleDirectoryReader(input_dir="path/to/directory", encoding="latin-1")抽取元数据
SimpleDirectoryReader 会自动为每个 Document 对象挂上一个 metadata 字典。默认包含这些条目:
file_path:文件的完整路径(含文件名)(字符串)file_name:文件名(含后缀)(字符串)file_type:由 `mimetypes.guess_type 推测出的 MIME 类型(字符串)file_size:文件字节大小(整数)creation_date,last_modified_date,last_accessed_date:文件的创建、修改与访问时间,已归一化到 UTC 时区。见下文日期与时间元数据(字符串)
不过,你可以替换生成这个元数据字典的逻辑。写一个接收文件路径字符串、返回字典的自定义函数,然后把它作为 file_metadata 传给 SimpleDirectoryReader 构造函数:
def get_meta(file_path):
return {"foo": "bar", "file_path": file_path}
reader = SimpleDirectoryReader(
input_dir="path/to/directory", file_metadata=get_meta
)
docs = reader.load_data()
print(docs[0].metadata["foo"]) # prints "bar"日期与时间元数据
SimpleDirectoryReader 的默认元数据函数会以 格式 %Y-%m-%d 输出日期字符串。
为保证一致性,时间戳都会归一化到 UTC 时区。如果输出的日期看起来比实际晚/早一天,很可能是因为它落在 UTC 午夜的另一侧。
扩展到其它文件类型
你可以扩展 SimpleDirectoryReader 以读取其它文件类型:把「文件扩展名 → BaseReader 实例」的字典作为 file_extractor 传入。一个 BaseReader 应读取文件并返回一个 Document 列表。例如为 .myfile 加上自定义支持:
from llama_index.core import SimpleDirectoryReader
from llama_index.core.readers.base import BaseReader
from llama_index.core import Document
class MyFileReader(BaseReader):
def load_data(self, file, extra_info=None):
with open(file, "r") as f:
text = f.read()
# load_data returns a list of Document objects
return [Document(text=text + "Foobar", extra_info=extra_info or {})]
reader = SimpleDirectoryReader(
input_dir="./data", file_extractor={".myfile": MyFileReader()}
)
documents = reader.load_data()
print(documents)注意这个映射会覆盖你所指定文件类型的默认抽取器,所以如果还想支持默认行为,需要把它们再加回去。
支持外部文件系统
与其他模块一样,SimpleDirectoryReader 接受一个可选的 fs 参数,用于遍历远程文件系统。
它可以是由 fsspec 协议实现的任意文件系统对象。fsspec 协议已有多种远程文件系统的开源实现,包括 AWS S3、Azure Blob 与 DataLake、Google Drive、SFTP,以及许多其他实现。
下面是一个连接 S3 的例子:
from s3fs import S3FileSystem
s3_fs = S3FileSystem(key="...", secret="...")
bucket_name = "my-document-bucket"
reader = SimpleDirectoryReader(
input_dir=bucket_name,
fs=s3_fs,
recursive=True, # recursively searches all subdirectories
)
documents = reader.load_data()
print(documents)完整示例 notebook 见这里。