Reading Files in Dart

Reading and writing files are basic tasks needed for many Dart programs. First we’ll look at some examples of reading files.

import 'dart:io';
import 'dart:convert';

// Reading files requires checking most calls for errors.
// This helper will streamline our error checks below.
void check(Object? e) {
  if (e != null) {
    throw e;
  }
}

void main() {
  // Perhaps the most basic file reading task is
  // slurping a file's entire contents into memory.
  try {
    String contents = File('/tmp/dat').readAsStringSync();
    print(contents);
  } catch (e) {
    check(e);
  }

  // You'll often want more control over how and what
  // parts of a file are read. For these tasks, start
  // by opening a file to obtain a File object.
  File file;
  try {
    file = File('/tmp/dat');
  } catch (e) {
    check(e);
    return; // Exit if file couldn't be opened
  }

  // Read some bytes from the beginning of the file.
  // Allow up to 5 to be read but also note how many
  // actually were read.
  try {
    List<int> bytes = file.readAsBytesSync(length: 5);
    print('${bytes.length} bytes: ${utf8.decode(bytes)}');
  } catch (e) {
    check(e);
  }

  // You can also seek to a known location in the file
  // and read from there.
  RandomAccessFile raf;
  try {
    raf = file.openSync();
    raf.setPositionSync(6);
    List<int> bytes = raf.readSync(2);
    print('2 bytes @ 6: ${utf8.decode(bytes)}');
  } catch (e) {
    check(e);
  } finally {
    raf?.closeSync();
  }

  // The dart:io package provides some functions that may
  // be helpful for file reading. For example, reads
  // like the ones above can be more robustly
  // implemented with readAsBytes.
  try {
    raf = file.openSync();
    raf.setPositionSync(6);
    List<int> bytes = raf.readSync(2);
    print('2 bytes @ 6: ${utf8.decode(bytes)}');
  } catch (e) {
    check(e);
  } finally {
    raf?.closeSync();
  }

  // There is no built-in rewind, but
  // setPositionSync(0) accomplishes this.
  try {
    raf = file.openSync();
    raf.setPositionSync(0);
  } catch (e) {
    check(e);
  } finally {
    raf?.closeSync();
  }

  // The dart:io package implements buffered I/O
  // that may be useful both for its efficiency
  // with many small reads and because of the additional
  // reading methods it provides.
  try {
    Stream<List<int>> inputStream = file.openRead();
    List<int> bytes = await inputStream.first;
    print('${bytes.length} bytes: ${utf8.decode(bytes.sublist(0, 5))}');
  } catch (e) {
    check(e);
  }

  // Close the file when you're done (usually this would
  // be scheduled immediately after opening with
  // a try-finally block).
  file.closeSync();
}

To run this program:

$ echo "hello" > /tmp/dat
$ echo "dart" >>   /tmp/dat
$ dart run reading_files.dart
hello
dart
5 bytes: hello
2 bytes @ 6: da
2 bytes @ 6: da
5 bytes: hello

Next, we’ll look at writing files.