Open In App

Flutter – Read, Write and Override File Locally to Disk

Last Updated : 09 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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.

1

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.

2

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)

read_write

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.

Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads