Home > OS >  Why doesn't File provide an interface to read the contents to return Uint8List data in dart?
Why doesn't File provide an interface to read the contents to return Uint8List data in dart?

Time:03-05

I want to read the contents of a file piece by piece through an interface (instead of reading the whole file at once with readAsBytes()). openRead() seems to do the trick, but it returns a List<int> type. And I expect it to be Uint8List, because I want to do block operations on some of the contents.

If you convert the returned List<int> to Uint8List, it seems to make a copy of the contents, which is a big loss in efficiency.

Is this how it was designed?

CodePudding user response:

Historically Dart used List<int> for sequences of bytes before a more specific Uint8List class was added. A Uint8List is a subtype of List<int>, and in most cases where a Dart SDK function returns a List<int> for a list of bytes, it's actually a Uint8List object. You therefore usually can just cast the result:

var file = File('/path/to/some/file');
var stream = file.openRead();
await for (var chunk in stream) {
  var bytes = chunk as Uint8List;
}

If you are uncomfortable relying on the cast, you can create a helper function that falls back to creating a copy if and only if necessary.

There have been efforts to change the Dart SDK function signatures to use Uint8List types explicitly, and that has happened in some cases (e.g. File.readAsBytes). Such changes would be breaking API changes, so they cannot be done lightly. I don't know why File.openRead was not changed, but it's quite likely that the amount of breakage was deemed to be not worth the effort. (At a minimum, the SDK documentation should be updated to indicate whether it is guaranteed to return a Uint8List object. Also see https://github.com/dart-lang/sdk/issues/39947)

Alternatively, instead of using File.openRead, you could use File.open and then use RandomAccessFile.read, which is declared to return a Uint8List.

  •  Tags:  
  • dart
  • Related