Flutter – Read, Write and Override File Locally to Disk
In many cases, we need to save files locally so that we can read and write them while the device is offline. For example, we might need to persist data across the app. To save files to disk on mobile or desktop apps, we need to add package path_provider to our project. There are Four Steps to Read and Write files to a local disk.
- Step 1: Find the local Path
- Step 2: Create an Address to the File’s Location
- Step 3: Write data to File.
- Step 4: Read data from the File.
A sample video is given below to get an idea about what we are going to do in this article. The video below shows that data entered by the user persists even after closing the app from the background.
Let’s Build UI to Show Saved Credentials
Creating HomePage class by extending stateful widget to build below UI.
Dart
import 'package:flutter/material.dart' ; import 'package:readwritegfg/credpage.dart' ; import 'package:readwritegfg/readwrite.dart' ; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } String username = "Username saved by user will be visible here" ; String userPass = "Password saved by user will be visible here" ; String readName = "" ; String readPass = "" ; Future< void > getCred() async { ReadWrite read = ReadWrite(); readName = await read.readTextFile( 'username.txt' ); readPass = await read.readTextFile( 'userPass.txt' ); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( backgroundColor: Colors.lightBlue, title: const Text( "Saved Credentials" , style: TextStyle(fontSize: 40), ), centerTitle: true , ), body: Padding( padding: const EdgeInsets.all(8), child: Column( children: [ Text( "Username" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), Text( username, style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), Text( "Password" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), Text( userPass, style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), ElevatedButton( onPressed: () async { await getCred(); setState(() { if (readName.isNotEmpty && readPass.isNotEmpty) { username = readName; userPass = readPass; } }); }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), child: const Text( "Click here to See Credentials" , style: TextStyle(color: Colors.white, fontSize: 20), ), ), SizedBox( height: 50, ), ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const CredPage())); }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), child: const Text( "Click here to Change Credentials" , style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], ), ), )); } } |
Let’s Build UI to Save User Input To Local Disk
Creating CredPage class by extending stateless widget to build below UI.
Dart
import 'package:flutter/material.dart' ; import 'package:readwritegfg/readwrite.dart' ; class CredPage extends StatelessWidget { const CredPage({super.key}); @override Widget build(BuildContext context) { TextEditingController getUserName = TextEditingController(); TextEditingController getUserPassword = TextEditingController(); return SafeArea( child: Scaffold( appBar: AppBar( backgroundColor: Colors.lightBlue, title: const Text( "Credentials" , style: TextStyle(fontSize: 40), ), centerTitle: true , ), body: Padding( padding: const EdgeInsets.all(8), child: Column( children: [ Text( "Username" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), TextField( controller: getUserName, decoration: const InputDecoration(hintText: "Username" ), style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), Text( "Password" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), TextField( controller: getUserPassword, decoration: const InputDecoration(hintText: "Password" ), style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), ElevatedButton( onPressed: ()async { final store = ReadWrite(); await store.writeTextFile( 'username.txt' , getUserName.text); await store.writeTextFile( 'userPass.txt' , getUserPassword.text); }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), child: const Text( "Click here to Save Credentials" , style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], ), ), )); } } |
Lets Code to Store Inputted Data by User
Create Class to write code to Store and Read Text from local disk:
As, discussed above in this article, to save files to disk on mobile or desktop apps, we need to add package path_provider to our project.
Step 1: Inside pubspec.yaml add path_provider: ^2.1.1
dependencies:
flutter:
sdk: flutter
path_provider: ^2.1.1
Step 2: Run flutter pub get in terminal
flutter pub get
Step 3: Find Local Path to store your file
Using path_provider we can find path on local storage to Write and Read our application files. We can use getApplicationDocumentsDirectory() to get path of the local storage where our application can store files locally, it is not necessarily visible to user through device file manager. Else, getExternalStorageDirectory() can be used, It returns directory on External Local Storage (SD card on Android) which might be available or not in user’s device.
Future<String> get _directoryPath async {
Directory? directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Step 4: Create Address to File’s Location
Here we will Create File , (for example: username.txt) so that we can write and read in that file in future.
Future<File> getFile(String fileNameWithExtension) async {
final path = await _directoryPath;
return File("$path/$fileNameWithExtension");
}
Step 5: Write Data to Text file
Now, we have file where we can write, override and read.
writeTextFile(String fileNameWithExtension, String content) async {
File file = await getFile(fileNameWithExtension);
file.writeAsString(content);
}
Step 6: Read Data From Text File
Now, you have data on your disk, you can read it.
readTextFile(String fileNameWithExtension) async {
final file = await getFile(fileNameWithExtension);
final fileContent = await file.readAsString();
return fileContent;
}
Step 7: Create class ReadWrite and code all the above functions in one class
(class can have any name as per your preference)
Dart
import 'dart:io' ; import 'package:path_provider/path_provider.dart' ; class ReadWrite { Future<String> get _directoryPath async { Directory? directory = await getApplicationDocumentsDirectory(); return directory.path; } Future<File> getFile(String fileNameWithExtension) async { final path = await _directoryPath; return File( "$path/$fileNameWithExtension" ); } writeTextFile(String fileNameWithExtension, String content) async { File file = await getFile(fileNameWithExtension); file.writeAsString(content); } readTextFile(String fileNameWithExtension) async { final file = await getFile(fileNameWithExtension); final fileContent = await file.readAsString(); return fileContent; } } |
Let’s Merge UI and Backend Code
Step 1: Storing Data from CredPage
Create object of the ReadWrite class in CredPage class, and implement the function writeTextFile. store is the object of ReadWrite class through which we can access functions inside ReadWrite class. Text from TextEditingController will get stored in file with name username.txt (or whatever you provide here)
Dart
import 'package:flutter/material.dart' ; import 'package:readwritegfg/readwrite.dart' ; class CredPage extends StatelessWidget { const CredPage({super.key}); @override Widget build(BuildContext context) { TextEditingController getUserName = TextEditingController(); TextEditingController getUserPassword = TextEditingController(); return SafeArea( child: Scaffold( appBar: AppBar( backgroundColor: Colors.lightBlue, title: const Text( "Credentials" , style: TextStyle(fontSize: 40), ), centerTitle: true , ), body: Padding( padding: const EdgeInsets.all(8), child: Column( children: [ Text( "Username" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), TextField( controller: getUserName, decoration: const InputDecoration(hintText: "Username" ), style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), Text( "Password" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), TextField( controller: getUserPassword, decoration: const InputDecoration(hintText: "Password" ), style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), ElevatedButton( onPressed: ()async { /* store is the object of ReadWrite class through which we can access functions inside ReadWrite hence, store.writeTextFile('username.txt',getUsername.text) Text from TextEditingController will get stored in file with name username.txt (or whatever you provide here) */ final store = ReadWrite(); await store.writeTextFile( 'username.txt' , getUserName.text); await store.writeTextFile( 'userPass.txt' , getUserPassword.text); }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), child: const Text( "Click here to Save Credentials" , style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], ), ), )); } } |
Dart
ElevatedButton( onPressed: ()async { /* store is the object of ReadWrite class through which we can access functions inside ReadWrite hence, store.writeTextFile('username.txt',getUsername.text) Text from TextEditingController will get stored in file with name username.txt (or whatever you provide here) */ final store = ReadWrite(); await store.writeTextFile( 'username.txt' , getUserName.text); await store.writeTextFile( 'userPass.txt' , getUserPassword.text); }, |
Step 2: To read the saved Credentials in HomePage, create object of ReadWrite class and implement readTextFile.
Future<void> getCred() async {
/* read is object of ReadWrite class through which we will access stored data in file*/
ReadWrite read = ReadWrite();
readName = await read.readTextFile('username.txt');
readPass = await read.readTextFile('userPass.txt');
}
Dart
import 'package:flutter/material.dart' ; import 'package:readwritegfg/credpage.dart' ; import 'package:readwritegfg/readwrite.dart' ; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } String username = "Username saved by user will be visible here" ; String userPass = "Password saved by user will be visible here" ; String readName = "" ; String readPass = "" ; Future< void > getCred() async { ReadWrite read = ReadWrite(); readName = await read.readTextFile( 'username.txt' ); readPass = await read.readTextFile( 'userPass.txt' ); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( backgroundColor: Colors.lightBlue, title: const Text( "Saved Credentials" , style: TextStyle(fontSize: 40), ), centerTitle: true , ), body: Padding( padding: const EdgeInsets.all(8), child: Column( children: [ Text( "Username" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), Text( username, style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), Text( "Password" , style: TextStyle(fontSize: 30, color: Colors.green.shade900), ), Text( userPass, style: TextStyle(fontSize: 30, color: Colors.orange.shade900), ), const SizedBox( height: 50, ), ElevatedButton( onPressed: () async { await getCred(); setState(() { if (readName.isNotEmpty && readPass.isNotEmpty) { username = readName; userPass = readPass; } }); }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), child: const Text( "Click here to See Credentials" , style: TextStyle(color: Colors.white, fontSize: 20), ), ), SizedBox( height: 50, ), ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const CredPage())); }, style: ElevatedButton.styleFrom(backgroundColor: Colors.blue), child: const Text( "Click here to Change Credentials" , style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], ), ), )); } } |
Dart
Future< void > getCred() async { /* read is object of ReadWrite class through which we will access stored data in file*/ ReadWrite read = ReadWrite(); readName = await read.readTextFile( 'username.txt' ); readPass = await read.readTextFile( 'userPass.txt' ); } |
To Rewrite/Override just save the data again to that referenced file location, In the below output it is shown that saved data is overridden and data stored by user is persisted.
Contact Us