主题
读写文件 (Read and Write Files)
在某些情况下,你需要将文件读取或写入到本地磁盘中。例如,你可能需要实现应用多次启动之间的数据持久化,或者从互联网下载数据并保存,以便后续离线时使用。
Flet 使得在移动端/桌面端设备上操作文件和目录变得非常简单,如下面的示例所示。
存储路径 (Storage Paths)
Flet 提供了两个用于数据存储的目录路径,它们作为环境变量提供:FLET_APP_STORAGE_DATA 和 FLET_APP_STORAGE_TEMP。
它们的值可以通过如下方式获取:
python
import os
app_data_path = os.getenv("FLET_APP_STORAGE_DATA")
app_temp_path = os.getenv("FLET_APP_STORAGE_TEMP")写入文件 (Writing to a File)
要将数据写入新文件或已有的文件中,你可以使用 Python 内置的 open 函数。
例如:
python
import os
app_data_path = os.getenv("FLET_APP_STORAGE_DATA")
my_file_path = os.path.join(app_data_path, "test_file.txt")
with open(my_file_path, "w") as f:
f.write("Some file content...")读取文件
要从现有文件中读取数据,同样可以使用内置的 open 函数。
例如:
python
import os
app_data_path = os.getenv("FLET_APP_STORAGE_DATA")
my_file_path = os.path.join(app_data_path, "test_file.txt")
with open(my_file_path, "r") as f:
file_content = f.read()
print(file_content)此外,你还可以使用 os 模块(或任何其他第三方库)来执行各种文件和目录操作,如重命名、删除、列出目录中存在的文件等。
示例:计数器应用 (Example: Counter App)
下面的示例展示了一个基本的计数器应用,其数值在应用重新启动后依然能够保留。这是通过将计数器的值写入应用数据存储目录中的文件,并在应用启动时读取该文件来实现的。
python
import os
from datetime import datetime
import flet as ft
# 常量
FLET_APP_STORAGE_DATA = os.getenv("FLET_APP_STORAGE_DATA")
COUNTER_FILE_PATH = os.path.join(FLET_APP_STORAGE_DATA, "counter.txt")
FLET_APP_CONSOLE = os.getenv("FLET_APP_CONSOLE")
class Counter(ft.Text):
def __init__(self, storage_path=COUNTER_FILE_PATH):
super().__init__(theme_style=ft.TextThemeStyle.HEADLINE_LARGE)
self.storage_path = storage_path
self.count = self.__read_from_storage()
def increment(self):
"""递增计数器,存储新值,并返回它。"""
self.count += 1
self.update()
self.__write_to_storage()
def before_update(self):
super().before_update()
self.value = f"Button tapped {self.count} time{'' if self.count == 1 else 's'}"
def __log(self, action: str, value: int = None):
"""记录执行的操作日志。"""
if value is None:
value = self.count
print(f"{datetime.now().strftime('%Y/%m/%d %H:%M:%S')} - {action} = {value}")
def __read_from_storage(self):
"""读取计数器的值。如果发生错误,则默认使用 0。"""
try:
with open(self.storage_path, "r") as f:
value = int(f.read().strip())
except (FileNotFoundError, ValueError):
# 文件不存在或转换为 int 失败
value = 0
self.__log("READ", value)
return value
def __write_to_storage(self):
"""将当前计数器的值写入存储中。"""
with open(self.storage_path, "w") as f:
f.write(str(self.count))
self.__log("WRITE")
def main(page: ft.Page):
page.theme_mode = ft.ThemeMode.LIGHT
page.vertical_alignment = ft.MainAxisAlignment.CENTER
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
def show_logs(e: ft.ControlEvent):
if FLET_APP_CONSOLE is not None:
with open(FLET_APP_CONSOLE, "r") as f:
dlg = ft.AlertDialog(
title=ft.Text("App Logs"),
content=ft.Text(f.read()),
scrollable=True,
)
page.open(dlg)
counter = Counter()
page.appbar = ft.AppBar(
title=ft.Text("Storage Playground", weight=ft.FontWeight.BOLD),
center_title=True,
bgcolor=ft.Colors.BLUE,
color=ft.Colors.WHITE,
adaptive=True,
actions=[
ft.IconButton(
icon=ft.Icons.REMOVE_RED_EYE,
tooltip="Show logs",
visible=FLET_APP_CONSOLE is not None,
on_click=show_logs,
),
],
)
page.floating_action_button = ft.FloatingActionButton(
icon=ft.Icons.ADD,
text="Increment Counter",
foreground_color=ft.Colors.WHITE,
bgcolor=ft.Colors.BLUE,
on_click=lambda e: counter.increment(),
)
page.floating_action_button_location = ft.FloatingActionButtonLocation.CENTER_FLOAT
page.add(ft.SafeArea(counter))
ft.run(main)