入门 Eva J Patel(freeCodeCamp) 2026-09-10 16:14:02 · 2 阅读

第11章 文件上传与文件处理

在实际应用中,文件无处不在。

用户可能想要上传:

  • PDF

  • Word 文档

  • 电子表格

  • CSV 文件

  • 图片

  • JSON 文件

  • 文本文件

  • 数据集

  • 演示文稿

Gradio 应用可以把这些文件变成实用的工作流。

比如:

上传 PDF → 提取文本 → 生成摘要。

或者:

上传 CSV → 分析数据 → 展示表格。

再或者:

上传图片 → 进行分类 → 显示预测结果。

File 组件

最基础的文件上传组件是:

file = gr.File()

更完整的写法如下:

file = gr.File(
    label="Upload your document"
)

处理上传的文件

Python 函数接收到的上传文件信息,取决于组件的配置和 Gradio 版本。

常见的做法是使用上传文件的路径。

例如:

def process_file(file):
    if file is None:
        return "Please upload a file."

    return f"Received: {file}"

建议先检查应用实际收到的值,再决定如何处理。

限制文件类型

如果应用只支持特定的文件格式,可以相应地配置文件组件。

例如,一个文档分析应用可能只接受 PDF:

file = gr.File(
    file_types=[".pdf"],
    label="Upload a PDF"
)

这样可以避免用户上传应用无法处理的文件。

允许多文件上传

有些应用需要处理多个文件。

根据 Gradio 版本和组件配置,你可以启用多文件上传。

例如:

files = gr.File(
    file_count="multiple",
    label="Upload files"
)

此时你的函数需要处理的是一组文件,而不是单个文件。

处理文本文件

Python 标准库让文本文件的处理变得很直接。

def read_text_file(file):
    if file is None:
        return "No file uploaded."

    with open(file.name, "r", encoding="utf-8") as f:
        return f.read()

对象的具体表示形式可能有所不同,请始终确认你所安装的 Gradio 版本中组件实际返回的值。

错误处理

文件处理可能因多种原因失败。

文件可能已损坏、编码不可预期、结构不受支持、体积过大,或包含格式错误的数据。

不要假设每个上传的文件都是合法的。

例如:

def read_text_file(file):
    if file is None:
        return "Please upload a file."

    try:
        with open(file.name, "r", encoding="utf-8") as f:
            return f.read()

    except UnicodeDecodeError:
        return "This file does not appear to be UTF-8 text."

    except Exception as error:
        return f"Could not process the file: {error}"

在生产环境中,不要将内部错误细节直接暴露给用户。

CSV 文件

CSV 处理是 Gradio 的常见使用场景。

使用 pandas:

import pandas as pd

def analyze_csv(file):
    if file is None:
        return "Please upload a CSV file."

    df = pd.read_csv(file.name)

    return df

可以用 gr.Dataframe 展示结果。

import gradio as gr
import pandas as pd

def analyze_csv(file):
    if file is None:
        return pd.DataFrame()

    return pd.read_csv(file.name)

with gr.Blocks() as demo:
    file = gr.File(
        file_types=[".csv"],
        label="Upload CSV"
    )

    button = gr.Button("Load Data")

    table = gr.Dataframe(
        label="Dataset"
    )

    button.click(
        fn=analyze_csv,
        inputs=file,
        outputs=table
    )

demo.launch()

这已经是一个实用的小应用了。

展示统计数据

让我们把这个 CSV 应用做得更有意思一些。

import gradio as gr
import pandas as pd

def analyze_csv(file):
    if file is None:
        return pd.DataFrame(), "No file uploaded."

    df = pd.read_csv(file.name)

    summary = (
        f"Rows: {len(df)}\n"
        f"Columns: {len(df.columns)}"
    )

    return df, summary

with gr.Blocks() as demo:
    file = gr.File(
        file_types=[".csv"],
        label="Upload CSV"
    )

    button = gr.Button("Analyze")

    table = gr.Dataframe(
        label="Dataset"
    )

    summary = gr.Textbox(
        label="Summary"
    )

    button.click(
        fn=analyze_csv,
        inputs=file,
        outputs=[table, summary]
    )

demo.launch()

现在应用同时提供数据展示和基础统计。

文件大小很重要

用户上传了文件,并不意味着应用就该不加限制地直接处理它。

大文件会占用:

  • 内存

  • CPU

  • 磁盘空间

  • 模型 tokens

  • 处理时间

生产环境中,务必设定合理的限制。

PDF 处理

PDF 文件在 AI 应用中非常常见。

典型流程会用到 PDF 提取库,基本模式如下:

def extract_pdf(file):
    if file is None:
        return ""

    # Open the PDF.
    # Extract text.
    # Return the text.

根据具体需求,可以选择 PyMuPDF 等库。

Gradio 的核心逻辑始终不变:

File component
→ Python function
→ extracted content
→ output component

DOCX 处理

Word 文档同理,可以用 python-docx 等库来处理。

例如:

from docx import Document

def extract_docx(file):
    document = Document(file.name)

    paragraphs = [
        paragraph.text
        for paragraph in document.paragraphs
    ]

    return "\n".join(paragraphs)

将它与以下组件关联:

file = gr.File(file_types=[".docx"])

以及:

output = gr.Textbox(lines=15)

JSON 文件

在构建开发者工具时,JSON 尤其实用。

import json

def read_json(file):
    if file is None:
        return {}

    with open(file.name, "r", encoding="utf-8") as f:
        return json.load(f)

然后:

output = gr.JSON()

就能展示结构化数据了。

文件处理流水线

一个实用的应用往往遵循这样的流水线:

上传
→ 校验
→ 提取
→ 转换
→ 分析
→ 展示

如果工作流变得难以维护,就不要把所有操作都塞进一个巨大的代码块里。

把功能拆分成独立的函数,会让应用更容易测试。

示例:CSV 清洗工具

import gradio as gr
import pandas as pd

def clean_csv(file):
    if file is None:
        return pd.DataFrame(), "Please upload a CSV."

    df = pd.read_csv(file.name)

    before = len(df)

    df = df.drop_duplicates()
    df = df.dropna(how="all")

    after = len(df)

    message = (
        f"Original rows: {before}\n"
        f"Rows after cleaning: {after}\n"
        f"Rows removed: {before - after}"
    )

    return df, message

with gr.Blocks() as demo:
    gr.Markdown("# CSV Cleaner")

    file = gr.File(
        file_types=[".csv"],
        label="Upload CSV"
    )

    button = gr.Button("Clean Dataset")

    table = gr.Dataframe(
        label="Cleaned Data"
    )

    report = gr.Textbox(
        label="Cleaning Report"
    )

    button.click(
        fn=clean_csv,
        inputs=file,
        outputs=[table, report]
    )

demo.launch()

这是一个真正能用的工具,而不仅仅是演示。

文件下载

有些应用不仅接收文件,还会生成文件。

比如,用户可以上传 CSV 格式的文件,清洗后,再下载清洗好的 CSV。

Gradio 支持把生成的文件作为输出返回。

Python 函数可以先保存结果:

df.to_csv("cleaned.csv", index=False)

然后把生成的文件路径返回给相应的输出组件。

文件输出的具体行为请以你安装的 Gradio 版本为准。

临时文件

应用生成文件时,要考虑存储位置和保留时长。

临时输出不应当作永久存储使用。

需要长期存储时,建议使用专门的存储服务。

安全注意事项

文件上传会带来安全风险。

不能仅凭文件经由你的界面上传就认为它安全。

根据应用场景,可考虑以下措施:

  • 文件类型校验

  • 文件大小限制

  • 安全的文件命名

  • 恶意软件扫描

  • 受限处理

  • 沙箱隔离

  • 避免执行上传的代码

  • 及时清理临时文件

当应用对外公开时,上述措施尤为重要。

切勿随意执行上传的代码

假设有人上传了一个 Python 文件,不要直接这样做:

exec(uploaded_code)

这会让上传的内容获得执行任意 Python 代码的能力。

文件上传不等于文件可信。

文件名是不可信的输入

不要直接用上传的文件名拼接 shell 命令。

避免如下写法:

import os

os.system(f"process {file.name}")

因为文件名及其他用户可控值,在没有适当防护的情况下不应拼入 shell 命令。

更好的做法是尽量避免使用 shell 执行。

动手试一试

构建一个 CSV 分析应用,要求:

  • 接受 CSV 文件上传

  • 展示数据集

  • 显示行数和列数

  • 展示列名

  • 识别缺失值

再添加一个按钮用于删除重复行。

这是很好的练习,因为它综合了:

  • 文件上传

  • pandas

  • 多种输出形式

  • 数据校验

  • Gradio events

关键要点

  • gr.File 允许用户上传文件。

  • 尽量限制可接受的文件类型。

  • 文件处理通常在普通的 Python 函数中完成。

  • CSV 文件与 pandas 搭配效果尤佳。

  • PDF、DOCX、JSON 及其他格式均可用 Python 库处理。

  • 处理前应先校验上传的文件。

  • 大文件可能引发性能问题。

  • 上传的文件应视为不可信输入。

  • 除非有严谨的安全设计,否则切勿执行上传的代码。

评论 (0)