当前位置: 首页 > news >正文

Flutter 本地存储

文章目录

  • Flutter 本地存储
    • SharedPreferences
      • 添加依赖
      • 获取实例
      • 写入
      • 读取
      • 删除
      • 清空
    • SQLite
      • 添加依赖
      • 定义数据库
      • 定义数据模型
      • DAO(数据访问对象)
      • 使用
    • 文件存储
      • 添加依赖
      • 常用目录
      • 文件操作
      • 目录操作

Flutter 本地存储

SharedPreferences

  • 类型:键值对
  • 适应场景:存放简单配置、用户偏好、Token
  • 本质:SharedPreferences 本质是把键值对写到 Android 的SharedPreferences和 iOS 的NSUserDefaults

添加依赖

dependencies:shared_preferences:^2.2.3

获取实例

finalprefs=awaitSharedPreferences.getInstance();

写入

prefs.setString('name','小明');prefs.setInt('age',18);prefs.setDouble('weight',70.5);prefs.setBool('sex',true);prefs.setStringList('address',['北京','上海','重庆']);

读取

finalStringname=prefs.getString('name')??'';finalint age=prefs.getInt('age')??0;finaldouble weight=prefs.getDouble('weight')??0;finalbool sex=prefs.getBool('sex')??false;finalList<String>address=prefs.getStringList('address')??[];

删除

awaitprefs.remove('name');

清空

awaitprefs.clear();

SQLite

  • 类型:关系型数据库
  • 适应场景:结构化业务数据、列表分页

添加依赖

dependencies:sqflite:^2.3.3path:^1.9.0path_provider:^2.1.4

定义数据库

classDBManager{staticfinalDBManagerinstance=DBManager();Database?_db;Future<Database>getdbasync{_db??=awaitopen();return_db!;}Future<Database>open()async{finalStringdir=awaitgetDatabasesPath();finalStringdbPath=path.join(dir,'app.db');returnopenDatabase(dbPath,version:1,onCreate:_create);}void_create(Databasedb,int version)async{finalbatch=db.batch();finalStringsql=''' CREATE TABLE note( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT, category TEXT DEFAULT 'DEFAULT', pinned INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL ); ''';batch.execute(sql);batch.execute('CREATE INDEX idx_note_category ON note(category);');batch.execute('CREATE INDEX idx_note_updated_at ON note(updated_at DESC);');// execute将操作添加到队列中// commit执行有操作awaitbatch.commit(noResult:true);}voidclose()async{await_db?.close();_db=null;}}

定义数据模型

classNote{finalint?id;finalStringtitle;finalString?content;finalStringcategory;finalint pinned;latefinalDateTimecreatedAt;latefinalDateTimeupdatedAt;Note({this.id,requiredthis.title,this.content,this.category='default',this.pinned=0,DateTime?createdAt,DateTime?updatedAt,}){this.createdAt=createdAt??DateTime.now();this.updatedAt=updatedAt??DateTime.now();}Map<String,Object?>toMap(){return{'id':id,'title':title,'content':content,'category':category,'pinned':pinned,'created_at':createdAt.millisecondsSinceEpoch,'updated_at':updatedAt.millisecondsSinceEpoch,};}factoryNote.fromMap(Map<String,Object?>map){returnNote(id:map['id']asint?,title:map['title']asString,content:map['content']asString?,category:map['category']asString,pinned:map['pinned']asint,createdAt:DateTime.fromMicrosecondsSinceEpoch(map['created_at']asint),updatedAt:DateTime.fromMicrosecondsSinceEpoch(map['updated_at']asint),);}@overrideStringtoString(){return'Note{id:$id, title:$title, content:$content, category:$category, pinned:$pinned, createdAt:$createdAt, updatedAt:$updatedAt}';}}

DAO(数据访问对象)

classNoteDao{staticfinalNoteDaoinstance=NoteDao();Future<Database>get_db=>DBManager.instance.db;// 增Future<Note>insert(Notenode)async{finalid=await(await_db).insert('note',node.toMap()..remove('id'),conflictAlgorithm:ConflictAlgorithm.replace,);returnNote(id:id,title:node.title,content:node.content,category:node.category,pinned:node.pinned,createdAt:node.createdAt,updatedAt:node.updatedAt,);}// 删Future<int>delete(int id)async{return(await_db).delete('note',where:'id=?',whereArgs:[id]);}// 改Future<int>update(int id,Stringcontent)async{return(await_db).update('note',{'content':content,'updated_at':DateTime.now().millisecond},where:'id=?',whereArgs:[id],);}// 查Future<Note?>get(int id)async{finalrows=await(await_db).query('note',where:'id=?',whereArgs:[id],limit:1,);returnrows.isEmpty?null:Note.fromMap(rows.first);}// 查询多条Future<List<Note>>getList(int page,int pageSize,{String?category,String?keyword,})async{finalList<String>where=[];finalList<Object?>args=[];if(category!=null&&category.isNotEmpty){where.add('category=?');args.add(category);}if(keyword!=null&&keyword.isNotEmpty){where.add('(title LIKE ? OR content LIKE ?)');args.add('%${keyword}%');args.add('%${keyword}%');}finalrows=await(await_db).query('note',where:where.isEmpty?null:where.join(' AND '),whereArgs:args.isEmpty?null:args,orderBy:'pinned DESC, updated_at DESC',limit:pageSize,offset:page*pageSize,);varnoteList=rows.map(Note.fromMap).toList(growable:false);returnnoteList;}}

使用

增:

vardao=NoteDao();dao.insert(Note(title:'日记1',content:'这是日记1的内容'));
vardao=NoteDao();dao.insert(Note(title:'日记2',content:'这是日记2的内容',category:'日记2的分类',pinned:1,),);

删:

vardao=NoteDao();dao.delete(1);

改:

vardao=NoteDao();dao.update(3,'hello world');

查:

vardao=NoteDao();varnote=awaitdao.get(3);print('note:${note}');
ar dao=NoteDao();varlist=awaitdao.getList(0,30,keyword:'hello world');print('noteList:${list}');

文件存储

path_provider是一个 Flutter 插件,本身不提供文件操作功能,负责获取跨平台的目录路径。

因为不同操作系统、不同设备的目录结构不同,手动硬编码路径会导致兼容性问题。path_provider提供了跨平台的统一 API。

添加依赖

dependencies:path_provider:^2.1.5

常用目录

// 应用文档目录:存储用户数据,不会被系统自动清理finalDirectorydocDir=awaitgetApplicationDocumentsDirectory();// Android: /data/data/<包名>/app_flutter// iOS: /var/mobile/Containers/Data/Application/<UUID>/Documents// 应用支持目录:存储持久化数据finalDirectorysupportDir=awaitgetApplicationSupportDirectory();// Android: /data/data/<包名>/files(即 context.getFilesDir())// iOS: /var/mobile/Containers/Data/Application/<UUID>/Library/Application Support// 应用缓存目录:在空间不足是会自动清理finalDirectorycacheDir=awaitgetApplicationCacheDirectory();// Android: /data/data/<包名>/cache// iOS: /var/mobile/Containers/Data/Application/<UUID>/Library/Caches// 临时目录:每次应用重启可能被清理finalDirectorytmpDir=awaitgetTemporaryDirectory();// Android: /data/data/<包名>/cache// iOS: /var/mobile/Containers/Data/Application/<UUID>/tmp// 下载目录finalDirectory?downloadDir=awaitgetDownloadsDirectory();// Android: /storage/emulated/0/Download// macOS: ~/Downloads// 外部存储目录:Android专用需要申请权限finalDirectory?externalDir=awaitgetExternalStorageDirectory();// Android: /storage/emulated/0/Android/data/<包名>/files

文件操作

  • File:文件操作
  • Directory:目录操作
  • FileSystemEntity:文件系统实体基类
  • Platform:获取操作系统信息
finaldir=awaitgetApplicationDocumentsDirectory();finalfile=File('${dir.path}/myfile.txt');// 写入文本awaitfile.writeAsString('hello');// 写入awaitfile.writeAsString('world',mode:FileMode.append);// 追加写入// 读取文本finalcontent=awaitfile.readAsString();// 流式写入finalsink=file.openWrite(mode:FileMode.append);sink.write('hello\n');sink.write('world\n');awaitsink.flush();awaitsink.close();// 文件信息finalstat=awaitfile.stat();// 获取文件元数据print('文件大小(字节):${stat.size}');print('文件修改时间:${stat.modified}');print('文件类型:${stat.type}');// 文件是否存在awaitfile.exists();// 文件移动/重命名finalnewDir=Directory('${dir.path}/abc');if(!awaitnewDir.exists()){awaitnewDir.create();}finalnewPath='${newDir.path}/efg.txt';file.rename(newPath);// 文件复制file.copy(newPath);// 文件删除awaitfile.delete();

目录操作

// 创建目录finalparentDir=awaitgetApplicationDocumentsDirectory();finalDirectorydir=Directory('${parentDir.path}/mydir');awaitdir.create();// 递归创建目录awaitdir.create(recursive:true);// 递归创建目录awaitdir.delete(recursive:true);// 支持递归删除// 展示目录内容finaldir=awaitgetApplicationDocumentsDirectory();finalfiles=awaitdir.list().toList();for(finalentityinfiles){print('entity:${entity}');}// 深度遍历,展示目录内finalfiles=awaitdir.list(recursive:true).toList();for(finalentityinfiles){print('entity:${entity}');}
http://www.jsqmd.com/news/1308825/

相关文章:

  • 014、MobileNetv4轻量级骨干替换YOLOv11 Backbone——通道适配与性能对比涨点实验
  • 合肥本地拆除挖机租赁出租靠谱口碑推荐,家装旧房拆改 / 商铺工装拆除 / 厂房高空拆除一站式施工方案 - 知汇研习社
  • 免费版AI生成原型工具靠谱吗?深度实测优缺点与避坑指南
  • 如何用DyberPet打造你的专属桌面伙伴?PySide6框架完整指南
  • RS232转RS485转换器设计:从原理到实践,打通工业通信桥梁
  • docker安装elasticsearch,保姆级教程
  • 界面组件DevExpress ASP.NET Core v23.1 - 进一步升级UI组件
  • 如何用SMUDebugTool免费掌控AMD Ryzen处理器:终极调试指南
  • 选型指导聚氨酯脱泡机正规厂家哪家好:破解脱泡痛点的八步精准适配方法论 - 全域品牌推荐
  • 2026年7月靠谱的多语种培训辅导班推荐,CPE考级/PTE口语培训/雅思备考/IGCSE课程培训,多语种培训机构哪家强 - 品牌推荐师
  • 猫抓浏览器插件:从网页中捕获视频资源的智能解决方案
  • 列表输出控制:有序、无序与嵌套列表的精准控制
  • 2026精选合肥评价高的挖掘机租赁服务商深度解析 - 知汇研习社
  • 合肥本地拆除挖机租赁出租靠谱口碑推荐,小区室内局部拆除 / 大面积厂房整拆 / 混凝土静力切割专业落地方案 - 知汇研习社
  • 移动端图片优化神器Progressively:自适应加载技术让页面加载速度提升2倍
  • USB转串口通信:从芯片选型到工业协议实战全解析
  • 常用环境部署(五)——Docker部署airflow和Centos安装Python3.5
  • 013、DEA动态集成注意力与SGE空间组增强的轻量级注意力集成——即插即用涨点方案
  • 耶鲁OpenHand开源机械手:如何用3D打印打造你的低成本机器人抓取系统
  • 递归对抗(RAE/RAD)核心机制深度研究报告
  • 124.华为路由器:BGP的通告原则分析及详解
  • 2026年山东铺路垫厂家选购指南:恒峻诚诚等优质企业盘点 - 八方八方
  • 2026 年现阶段,邢台资质齐全的二甲胺 CAS号:124-40-3源头厂家推荐,这玩意儿竟是很多化工生产的关键原料,你知道它的CAS号藏着多少行业秘密吗? - 企业推荐官【认证官方】
  • 「Qt Widget中文示例指南」如何模拟一个时钟?
  • ESP32-P4 Wi-Fi 6 PoE网关:硬件设计、网络冗余与混合组网实战
  • 012、CBAMv2改进版与PKINet上下文注意力即插即用模块——提升小目标检测性能
  • 合肥建工设备租赁服务口碑榜推荐,附避坑指南 - 知汇研习社
  • 企业大模型API成本估算实操教程:用一段脚本算出月度预算
  • 基于SenseCraft AI平台与XIAO ESP32S3的边缘AI开发实战
  • 2026 年更新:鱼台有实力的麦田压地机加工厂推荐几家,这玩意儿一进场,竟能让小麦产量翻出你想不到的惊喜? - 行业推荐官【认证】