Skip to content

dart:io:File class inconsistently using both List<int> and Uint8List to represent bytes #39947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
renatoathaydes opened this issue Dec 29, 2019 · 2 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. closed-invalid Closed as we don't believe the reported issue is generally actionable library-io type-question A question about expected behavior or functionality

Comments

@renatoathaydes
Copy link

Dart SDK Version (dart --version)

Dart VM version: 2.7.0 (Unknown timestamp) on "linux_x64"

Description

The dart:io:File class currently represents bytes using the new Uint8List type in the following methods:

Future<Uint8List> readAsBytes();
Uint8List readAsBytesSync();

The related RandomAccessFile also uses Uint8List in the following methods:

Future<Uint8List> read(int bytes);
Uint8List readSync(int bytes);

Confusingly, dart:io:File also uses List<int> to represent byte sequences:

Stream<List<int>> openRead([int start, int end]);
Future<File> writeAsBytes(List<int> bytes,
      {FileMode mode: FileMode.write, bool flush: false});
void writeAsBytesSync(List<int> bytes,
      {FileMode mode: FileMode.write, bool flush: false});

And RandomAccessFile also has methods using List<int>:

Future<int> readInto(List<int> buffer, [int start = 0, int end]);
int readIntoSync(List<int> buffer, [int start = 0, int end]);
Future<RandomAccessFile> writeFrom(List<int> buffer,
      [int start = 0, int end]);
void writeFromSync(List<int> buffer, [int start = 0, int end]);

Expected behaviour

Sequences of bytes should be represented using the same data type in all methods of a class, and hopefully soon, in the whole SDK. I understand that the transition to the more efficient Uint8List has not been fully completed yet, but have this kind of inconsistency even within single classes is very concerning.

Notice that Utf8Codec seems to still use List<int> for everything, as well as other closely-related types like IOSink, making the ecosystem broken in many places.

For example, it seems that some packages have already been updated to use Uint8List in some methods wher dart:io still uses List<int>. See package:file's File for example, which has been using Uint8List for several versions now (since at least 5.0.8 from what I can see) but is currently unusable with the stable Dart SDK because of this, even if I try to use older versions like 5.0.7, because then some methods that should use Uint8List still are using List<int>.

@devoncarew devoncarew added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-io labels Dec 29, 2019
@sortie
Copy link
Contributor

sortie commented Jan 6, 2020

The use of Uint8List and List<int> is by design, see breaking change #36900.

These APIs used to formally return List<int> but always returned an Uint8List in practice. We strengthened the API definition to formally return a Uint8List so people could rely on it. However, we were not able to change the inputs from List<int> to a Uint8List as that would break many callers. However, you can still pass Uint8List types into these interfaces and they may use a more efficient implementation under the hood when you do so.

There are no plans that I know of at this time to make a breaking change changing the inputs to Uint8List.

@sortie sortie closed this as completed Jan 6, 2020
@sortie sortie added closed-invalid Closed as we don't believe the reported issue is generally actionable type-question A question about expected behavior or functionality labels Jan 6, 2020
@jamesderlin
Copy link
Contributor

At a minimum, can we at least document the APIs declared to return List<int> but that actually return Uint8List objects so that there's an implicit guarantee of behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. closed-invalid Closed as we don't believe the reported issue is generally actionable library-io type-question A question about expected behavior or functionality
Projects
None yet
Development

No branches or pull requests

4 participants