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!

Top comments (0)