DEV Community

Cover image for Working with Files in Flutter
David Serrano
David Serrano

Posted on • Originally published at davidserrano.io

Working with Files in Flutter

Odds are that if you work with Flutter, eventually you'll have to handle files and directories.

Let's do a quick summary of all the basic filesystem operations that we can do with Flutter:

📽 Video version available on YouTube and Odysee

List common directories

By using the path_provider plugin we can get the path to common directories designed for different purposes:

import 'package:path_provider/path_provider.dart';

// Put cache files in this directory
final temporaryDirectory = await getTemporaryDirectory();
// For files that our app uses but are not exposed to the user
final appSupport = await getApplicationSupportDirectory();
// For user-generated files
final appDocuments = await getApplicationDocumentsDirectory();
Enter fullscreen mode Exit fullscreen mode

Create a file

Let's create a random file in the temporary directory and write something inside:

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/sample_file.txt');

await file.writeAsString('Sample content to write');
Enter fullscreen mode Exit fullscreen mode

Delete a file

The delete method is just as crucial as the create method, as it helps clear out old files and thus saves valuable storage space.

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/sample_file.txt');

await file.delete();
Enter fullscreen mode Exit fullscreen mode

Create a directory

Now let's say that I want to create a new file, but within a certain directory:

final Directory tempDir = await getTemporaryDirectory();
final Directory newDirectory =
    Directory('${tempDir.path}/sample_directory');

// Always check that the directory exists
if (await newDirectory.exists() == false) {
  await newDirectory.create();
}

final File file = File('${newDirectory.path}/sample_file.txt');
await file.writeAsString('Sample content to write');
Enter fullscreen mode Exit fullscreen mode

Remove a directory

Now let's do the reverse and delete the directory:

final Directory tempDir = await getTemporaryDirectory();
final Directory newDirectory =
    Directory('${tempDir.path}/sample_directory');

await newDirectory.delete(recursive: true);
Enter fullscreen mode Exit fullscreen mode

List files

Sometimes you need to list all files within a directory to get some of its stats:

final Directory directory = await getTemporaryDirectory();
final List<FileSystemEntity> files = directory.listSync();

for (final FileSystemEntity file in files) {
  final FileStat fileStat = await file.stat();
  print('Path: ${file.path}');
  print('Type: ${fileStat.type}');
  print('Changed: ${fileStat.changed}');
  print('Modified: ${fileStat.modified}');
  print('Accessed: ${fileStat.accessed}');
  print('Mode: ${fileStat.mode}');
  print('Size: ${fileStat.size}');
}
Enter fullscreen mode Exit fullscreen mode

Read file

Let's open a file to see its content:

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/sample_file.txt');

final String fileContent = await file.readAsString();
Enter fullscreen mode Exit fullscreen mode

Copy file

Now, let's generate a duplicate of the previously created sample file:

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/sample_file.txt');

final File copy = await file.copy('${tempDir.path}/copy_file.txt');
Enter fullscreen mode Exit fullscreen mode

Rename file

Next, let's change the name of the file we just copied:

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/copy_file.txt');

await file.rename('${tempDir.path}/new_name.txt');
Enter fullscreen mode Exit fullscreen mode

Synchronously manage file operations

So far, I've demonstrated how to handle files asynchronously, which is the preferred method. However, if for some reason Futures aren't an option for you, synchronous file operations are also possible:

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/sample_file.txt');

file.writeAsStringSync('New content to add');
Enter fullscreen mode Exit fullscreen mode

Error handling

All file system operations should be performed safely since they are prone to throw exceptions. For simplicity, the previous examples did not include this, but it's critical to always encapsulate your I/O operations within a try-catch block:

final Directory tempDir = await getTemporaryDirectory();
final File file = File('${tempDir.path}/sample_file.txt');

try {
  await file.writeAsString('New content to add');
} catch (e) {
  // Handle IO error
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Dart and Flutter simplify working with files, as demonstrated above. I hope this summary was useful and clear.

Happy coding!

Sentry mobile image

App store rankings love fast apps - mobile vitals can help you get there

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read full post →

Top comments (0)

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay