FastDFS 是一个开源的、轻量级、高性能的分布式文件系统,它主要解决大容量文件存储和高并发访问的问题,在 Python 生态中,最常用、最成熟的库是 fastdfs-client-py。

安装
您需要安装 Python 客户端库,最推荐的方式是使用 pip。
pip install fastdfs-client-py
重要提示:
这个 Python 客户端库依赖于一个 C 语言库 libfastclient,在 Linux 系统上,通常需要先安装这个依赖。
- 对于 Ubuntu/Debian:
sudo apt-get update sudo apt-get install -y python-dev libffi-dev # 尝试安装 libfastclient,如果官方源没有,可能需要从源码编译 # fastdfs-client-py 的安装会尝试自动编译,但确保开发工具包存在是关键 sudo apt-get install -y build-essential
- 对于 CentOS/RHEL:
sudo yum install -y python-devel libffi-devel sudo yum groupinstall -y "Development Tools"
- 对于 macOS (使用 Homebrew):
brew install python libffi
如果安装 fastdfs-client-py 时遇到编译错误,请确保上述开发环境已正确安装。
核心概念与配置
Python 客户端通过一个配置文件来连接到 FastDFS 的 Tracker 服务器,这个配置文件通常是一个 .conf 文件。

1 配置文件示例 (fastdfs.conf)
这是一个典型的配置文件内容:
# connect timeout in seconds # default value is 30s connect_timeout = 30 # network timeout in seconds # default value is 30s network_timeout = 60 # the base path to store log files # default value is /tmp base_path = /tmp # tracker_server can be multiple, must be provider in ip:port format # 这个是必须的,指向你的 Tracker 服务器 tracker_server = 192.168.1.100:22122 # 如果有多个 Tracker,可以多写几行 # tracker_server = 192.168.1.101:22122 # standard log level as syslog, case insensitive, value list: # emerg, alert, crit, err, warn, notice, info, debug # default value is info log_level = info # if use connection pool # default value is false # since V4.05 use_connection_pool = false # connections whose the pool can hold # default value is 10 # since V4.05 connection_pool_max_idle_time = 3600 # since V4.06 connection_pool_max_count = 10
2 配置文件路径
客户端需要知道这个配置文件的位置,通常有两种方式:
- 放在项目目录下:在代码中指定相对路径。
- 放在系统标准路径:
/etc/fdfs/,客户端会自动查找。
核心 API 使用方法
主要使用的类是 fdfs_client.client.FdfsClient。
1 初始化客户端
from fdfs_client.client import FdfsClient
try:
# 初始化客户端,传入配置文件路径
client = FdfsClient('fastdfs.conf')
print("FastDFS client initialized successfully.")
except Exception as e:
print(f"Failed to initialize FastDFS client: {e}")
2 上传文件
这是最常见的操作。upload_by_filename 用于上传本地文件,upload_by_buffer 用于上传内存中的二进制数据。

示例:上传本地文件
from fdfs_client.client import FdfsClient
client = FdfsClient('fastdfs.conf')
# 要上传的文件路径
file_path = '/path/to/your/local/file.txt'
try:
# 上传文件
result = client.upload_by_filename(file_path)
# result 是一个字典,包含上传结果
print("Upload Result:", result)
# result 结构示例:
# {
# 'Group': 'group1',
# 'Status': 'Upload successed.',
# 'Local file name': '/path/to/your/local/file.txt',
# 'Storage IP': '192.168.1.101',
# 'Remote file_id': 'group1/M00/00/00/rBAQB2v6qUuAeX7aAAAAADaB5Xg412.txt'
# }
if result['Status'] == 'Upload successed.':
remote_file_id = result['Remote file_id']
print(f"File uploaded successfully! Remote File ID: {remote_file_id}")
else:
print(f"File upload failed: {result['Status']}")
except Exception as e:
print(f"An error occurred during file upload: {e}")
示例:上传内存中的二进制数据
from fdfs_client.client import FdfsClient
client = FdfsClient('fastdfs.conf')
# 假设你有一个二进制数据
# 从文件读取
with open('/path/to/your/local/image.jpg', 'rb') as f:
file_buffer = f.read()
# 或者直接创建
# file_buffer = b"Hello, this is a test file content."
try:
result = client.upload_by_buffer(file_buffer)
if result['Status'] == 'Upload successed.':
remote_file_id = result['Remote file_id']
print(f"Buffer uploaded successfully! Remote File ID: {remote_file_id}")
else:
print(f"Buffer upload failed: {result['Status']}")
except Exception as e:
print(f"An error occurred during buffer upload: {e}")
3 下载文件
根据 Remote file_id 从 Storage 服务器下载文件。
from fdfs_client.client import FdfsClient
client = FdfsClient('fastdfs.conf')
# 你想要下载的文件的 Remote file_id
remote_file_id = 'group1/M00/00/00/rBAQB2v6qUuAeX7aAAAAADaB5Xg412.txt'
# 本地保存路径
local_save_path = '/path/to/save/downloaded_file.txt'
try:
# 下载文件
result = client.download_to_file(local_save_path, remote_file_id)
# result 是一个布尔值,表示是否成功
if result:
print(f"File downloaded successfully to {local_save_path}")
else:
print("File download failed.")
except Exception as e:
print(f"An error occurred during file download: {e}")
4 删除文件
根据 Remote file_id 删除文件。
from fdfs_client.client import FdfsClient
client = FdfsClient('fastdfs.conf')
# 你想要删除的文件的 Remote file_id
remote_file_id = 'group1/M00/00/00/rBAQB2v6qUuAeX7aAAAAADaB5Xg412.txt'
try:
# 删除文件
result = client.delete_file(remote_file_id)
# result 是一个布尔值,表示是否成功
if result:
print(f"File {remote_file_id} deleted successfully.")
else:
print(f"Failed to delete file {remote_file_id}.")
except Exception as e:
print(f"An error occurred during file deletion: {e}")
5 获取文件信息
获取文件的元信息,如文件大小、创建时间等。
from fdfs_client.client import FdfsClient
client = FdfsClient('fastdfs.conf')
remote_file_id = 'group1/M00/00/00/rBAQB2v6qUuAeX7aAAAAADaB5Xg412.txt'
try:
# 获取文件信息
result = client.get_file_info(remote_file_id)
# result 是一个字典
print("File Info:", result)
# result 结构示例:
# {
# 'Group': 'group1',
# 'Size': 1024,
# 'CRC32': '00000000',
# 'SourceIpAddress': '192.168.1.101',
# 'CreateTimestamp': 1634567890
# }
except Exception as e:
print(f"An error occurred while getting file info: {e}")
完整示例代码
下面是一个完整的脚本,演示了上传、下载、获取信息和删除文件的全过程。
# fastdfs_example.py
from fdfs_client.client import FdfsClient
import os
# --- 配置 ---
CONFIG_FILE = 'fastdfs.conf'
# --- 配置结束 ---
def main():
"""
FastDFS 操作主函数
"""
try:
client = FdfsClient(CONFIG_FILE)
print("FastDFS client initialized.")
except Exception as e:
print(f"[ERROR] Failed to initialize FastDFS client: {e}")
return
# 1. 上传文件
local_file_to_upload = 'sample.txt'
# 创建一个示例文件
with open(local_file_to_upload, 'w') as f:
f.write("Hello, FastDFS! This is a test file.")
print(f"\n--- Step 1: Uploading file '{local_file_to_upload}' ---")
try:
upload_result = client.upload_by_filename(local_file_to_upload)
print("Upload Result:", upload_result)
if upload_result['Status'] == 'Upload successed.':
remote_file_id = upload_result['Remote file_id']
print(f"[SUCCESS] File uploaded. Remote ID: {remote_file_id}")
else:
print(f"[FAILED] Upload failed: {upload_result['Status']}")
return
except Exception as e:
print(f"[ERROR] Upload failed: {e}")
return
# 2. 获取文件信息
print(f"\n--- Step 2: Getting info for file '{remote_file_id}' ---")
try:
info_result = client.get_file_info(remote_file_id)
print("File Info:", info_result)
except Exception as e:
print(f"[ERROR] Get file info failed: {e}")
# 3. 下载文件
downloaded_file_path = 'downloaded_sample.txt'
print(f"\n--- Step 3: Downloading file to '{downloaded_file_path}' ---")
try:
download_success = client.download_to_file(downloaded_file_path, remote_file_id)
if download_success:
print(f"[SUCCESS] File downloaded.")
# 验证下载的文件内容
with open(downloaded_file_path, 'r') as f:
content = f.read()
print(f"Downloaded file content: '{content}'")
else:
print("[FAILED] Download failed.")
except Exception as e:
print(f"[ERROR] Download failed: {e}")
# 4. 删除文件
print(f"\n--- Step 4: Deleting file '{remote_file_id}' ---")
try:
delete_success = client.delete_file(remote_file_id)
if delete_success:
print(f"[SUCCESS] File deleted.")
else:
print("[FAILED] Delete failed.")
except Exception as e:
print(f"[ERROR] Delete failed: {e}")
# 清理本地创建的测试文件
if os.path.exists(local_file_to_upload):
os.remove(local_file_to_upload)
if os.path.exists(downloaded_file_path):
os.remove(downloaded_file_path)
if __name__ == '__main__':
main()
常见问题与调试
-
ConnectionError或No module named 'fdfs_client':- 原因: 通常是
libfastclientC 库没有安装成功,或者fastdfs-client-py安装失败。 - 解决: 仔细检查安装步骤,确保 Python 开发环境、
libffi-dev等依赖都已安装,尝试重新编译安装fastdfs-client-py。
- 原因: 通常是
-
[ERROR] Connect timeout:- 原因: 无法连接到配置文件中指定的
tracker_server。 - 解决:
- 检查 Tracker 服务器的 IP 地址和端口是否正确。
- 确认 Tracker 服务器正在运行。
- 检查网络是否通畅,防火墙是否阻止了端口
22122(Tracker 默认端口)。 - 检查
connect_timeout和network_timeout配置是否合理。
- 原因: 无法连接到配置文件中指定的
-
[ERROR] Storage error:- 原因: 成功连接到 Tracker,但 Tracker 无法分配或连接到可用的 Storage 服务器。
- 解决:
- 检查 Storage 服务器是否正在运行。
- 检查 Storage 服务器的配置,确保它已正确注册到对应的 Tracker。
- 检查 Storage 服务器的磁盘空间是否已满。
-
[ERROR] file save error:- 原因: 客户端在本地保存日志或临时文件时失败。
- 解决: 检查配置文件中的
base_path指定的目录是否存在且有写入权限。
官方与社区资源
- FastDFS 官方 GitHub: https://github.com/happyfish100/fastdfs
这里可以找到 FastDFS 的源码、文档和最新的更新信息。
fastdfs-client-pyGitHub: https://github.com/happyfish100/fastdfs-client-pythonPython 客户端的源码仓库,可以在这里找到问题报告和修复。
- FastDFS 官方文档: http://bbs.chinaunix.net/forum-240-1.html (ChinaUnix 论坛,有大量中文讨论和资料)
- 博客和教程: 在 CSDN、掘金、SegmentFault 等平台搜索 "Python FastDFS" 可以找到大量实战教程和踩坑记录。
希望这份详细的文档能帮助您顺利地在 Python 项目中使用 FastDFS!
