Open In App

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.

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.






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.




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)




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)




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),
              ),
            )
          ],
        ),
      ),
    ));
  }
}




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');
}




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),
              ),
            )
          ],
        ),
      ),
    ));
  }
}




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:


Article Tags :