Flask 文件上传服务器 - 知识点总结

目录

  1. Flask 框架基础
  2. HTTP 协议
  3. 文件与路径处理
  4. Python 基础知识
  5. Linux 权限管理
  6. 服务器部署

1. Flask 框架基础

1.1 Flask 核心组件

组件 说明
Flask 核心应用类,用于创建 Web 应用实例
request 请求对象,用于获取客户端请求数据
jsonify() 将 Python 对象转换为 JSON 响应
from flask import Flask, request, jsonify

app = Flask(__name__)

1.2 应用实例化

app = Flask(__name__)
  • __name__:Python 特殊变量,表示当前模块名称
  • 直接运行脚本时:__name__ == '__main__'
  • 作为模块导入时:__name__ 为模块名
  • Flask 用它来确定应用的根目录

1.3 路由装饰器

@app.route('/path', methods=['GET', 'POST'])
def handler():
    pass
  • 将 URL 路径与 Python 函数绑定
  • 支持多个装饰器指向同一函数(多路由)
  • methods 参数指定允许的 HTTP 方法

1.4 Flask 配置管理

app.config['KEY'] = value
app.config['MAX_CONTENT_LENGTH'] = 500 * 1024 * 1024  # 500MB
  • app.config 是 Flask 的配置字典
  • 可存储自定义配置项
  • 支持通过配置文件或环境变量覆盖

2. HTTP 协议

2.1 常用 HTTP 方法

方法 说明 典型用途
GET 获取资源 查询、列表
POST 提交数据 文件上传、表单提交
DELETE 删除资源 删除文件

2.2 Flask Request 对象

request.files    # 获取上传文件 (字典)
request.form     # 获取表单数据 (字典)
request.args     # 获取 URL 参数 (字典)
request.json     # 获取 JSON 请求体

2.3 文件上传格式

  • 前端使用 multipart/form-data 格式
  • Flask 通过 request.files 获取
  • 返回 FileStorage 对象

2.4 HTTP 状态码

状态码 含义 使用场景
200 OK 成功响应
400 Bad Request 请求格式错误
404 Not Found 资源不存在
413 Request Entity Too Large 文件过大
500 Internal Server Error 服务器内部错误

3. 文件与路径处理

3.1 os.path 模块

os.path.abspath(__file__)    # 获取文件的绝对路径
os.path.dirname(path)        # 获取目录部分
os.path.join(a, b)           # 拼接路径(跨平台)
os.path.basename(path)      # 获取文件名
os.path.splitext(path)       # 分离文件名和扩展名

3.2 文件操作

os.listdir(path)            # 列出目录内容
os.path.isfile(path)        # 判断是否为文件
os.path.exists(path)        # 判断路径是否存在
os.path.getsize(path)       # 获取文件大小(字节)
os.path.getmtime(path)      # 获取修改时间(时间戳)
os.remove(path)             # 删除文件
os.makedirs(path)           # 创建目录(递归)

3.3 FileStorage 对象

Flask/Werkzeug 提供的上传文件封装类,继承自 Python 的 io.IOBase

from werkzeug.datastructures import FileStorage
file = request.files['file']  # 返回 FileStorage 对象
3.3.1 核心属性
属性 说明 示例
filename 上传文件的原始文件名 "app-debug.apk"
name 表单字段名称 (name 属性) "file"
content_type MIME 类型 "application/vnd.android.package-archive"
content_length 文件大小(字节) 11507896
3.3.2 核心方法
方法 说明 返回值
save(destination) 保存文件到磁盘 None
read(size) 读取文件内容 bytes
stream 文件数据流对象 FileStorage stream
seek(offset) 移动文件指针 None
tell() 获取当前指针位置 int
close() 关闭文件流 None
3.3.3 使用示例
# 获取文件对象
file = request.files['file']

# 方式1:直接保存(推荐)
file.save(os.path.join(UPLOAD_FOLDER, file.filename))

# 方式2:读取内容后处理
content = file.read()           # 读取全部内容
file.seek(0)                     # 重置指针
chunk = file.read(1024)         # 分块读取

# 方式3:使用 stream 流式处理
with open(os.path.join(UPLOAD_FOLDER, file.filename), 'wb') as f:
    while True:
        chunk = file.stream.read(8192)
        if not chunk:
            break
        f.write(chunk)
3.3.4 安全注意事项
# 1. 验证文件类型
ALLOWED_EXTENSIONS = {'apk', 'ipa', 'exe'}
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1]. in ALLOWED_EXTENSIONS

# 2. 防止路径遍历攻击
# 绝对禁止直接将用户输入的文件名拼接到路径
# 错误示例(危险!):
filename = request.files['file'].filename
os.path.join(UPLOAD_FOLDER, filename)  # 用户可能传入 "../etc/passwd"

# 正确做法:使用安全文件名
from werkzeug.utils import secure_filename
filename = secure_filename(file.filename)

# 3. 限制文件大小
app.config['MAX_CONTENT_LENGTH'] = 500 * 1024 * 1024
3.3.5 常见问题处理
# 问题1:文件名乱码
from werkzeug.utils import secure_filename
filename = secure_filename(file.filename)

# 问题2:文件已存在覆盖
# FileStorage.save() 默认覆盖,不提示
# 可添加检查:
import os
file_path = os.path.join(UPLOAD_FOLDER, file.filename)
if os.path.exists(file_path):
    # 处理重复文件,如重命名
    pass

# 问题3:大文件内存溢出
# 使用 stream 分块处理,避免 read() 一次性加载

3.4 时间戳转换

import time
timestamp = os.path.getmtime(path)
formatted = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp))

4. Python 基础知识

4.1 字符串格式化

# f-string (Python 3.6+)
name = "Alice"
f"Hello, {name}"

# 格式化数字
f"{size} bytes"
f"{size / 1024 / 1024:.2f} MB"

4.2 异常处理

try:
    # 可能引发异常的代码
    pass
except Exception as e:
    # 捕获异常,e 是异常对象
    print(f"Error: {e}")
finally:
    # 无论是否异常都会执行
    pass

4.3 主程序入口

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
  • __name__ == '__main__' 确保只在直接运行时执行
  • 作为模块导入时不执行

4.4 运算符

'in' in dict_or_list       # 成员运算符
not in                     # 不包含

4.5 列表操作

# 列表推导式
files = [{'name': f, 'size': os.path.getsize(f)} for f in filenames if os.path.isfile(f)]

# append 添加元素
files.append({'name': filename})

5. Linux 权限管理

5.1 权限表示法

八进制表示:

权限 二进制
0 --- 000
1 --x 001
2 -w- 010
3 -wx 011
4 r-- 100
5 r-x 101
6 rw- 110
7 rwx 111

5.2 常见权限组合

权限 八进制 说明
rwxr-xr-x 755 所有者全部权限,其他人读和执行
rw-r--r-- 644 所有者读写,其他人读
rwxrwxrwx 777 所有人全部权限(谨慎使用)

5.3 Python os.chmod()

import os

os.chmod(path, 0o755)   # 设置权限(八进制)
os.chmod(path, 0o644)   # 设置文件权限

5.4 权限作用对象

drwxr-xr-x
│││││││││
││││││││└─ 其他用户: 执行权限
│││││││└── 其他用户: 写权限
││││││└─── 其他用户: 读权限
│││││└──── 组用户: 执行权限
││││└───── 组用户: 写权限
│││└────── 组用户: 读权限
││└─────── 所有者: 执行权限
│└──────── 所有者: 写权限
└──────── 所有者: 读权限

d = 目录 (- = 文件)

6. 服务器部署

6.1 Flask 开发服务器

app.run(
    host='0.0.0.0',    # 监听所有接口
    port=5000,         # 端口号
    debug=False        # 调试模式
)
  • host='0.0.0.0':允许局域网访问
  • host='127.0.0.1':仅本地访问
  • debug=True:代码修改自动重启,显示详细错误

6.2 生产环境服务器

Flask 内置服务器不适合生产环境,推荐使用:

服务器 说明
Gunicorn 轻量级,推荐 Python WSGI 项目
uWSGI 功能强大,适合大型项目
Nginx 反向代理服务器

Gunicorn 示例:

gunicorn -w 4 -b 0.0.0.0:92 app:app

6.3 守护进程运行

# 使用 nohup 后台运行
nohup python app.py &

# 使用 systemd (推荐)
# /etc/systemd/system/upload.service
[Unit]
Description=Upload Server
After=network.target

[Service]
ExecStart=/usr/bin/python3 /path/to/app.py
Restart=always

[Install]
WantedBy=multi-user.target
sudo systemctl start upload
sudo systemctl enable upload

附录:代码结构速查

upload_server.py
├── 导入模块
│   ├── flask.Flask
│   ├── flask.request
│   ├── flask.jsonify
│   └── os
│
├── 配置
│   ├── UPLOAD_FOLDER         # 上传目录
│   ├── DIR_PERMISSIONS       # 目录权限 0o755
│   ├── FILE_PERMISSIONS      # 文件权限 0o644
│   └── MAX_CONTENT_LENGTH    # 最大上传大小
│
├── 路由
│   ├── POST /upload          # 上传文件
│   ├── GET /files            # 文件列表
│   └── DELETE /delete/<file> # 删除文件
│
└── 启动
    └── if __name__ == '__main__':

学习资源

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐