0

Currently, I am trying to read a file byte by byte and add some specific values to a list of 8-bit bytes (which might be of type List<Uint8>). To read the file one byte at a time, I am using RandomAccessFile.readByte(), but it returns an int value which is not accepted by List<Uint8>.add() function.

Due to the function name and return type, it looks like RandomAccessFile.readByte() provides a single byte in 64 bits. So what is the proper way to get only the least significant byte of the 64 bit result and add it to _someUint8List considering different types of endianness?

Lastly, This page mentions Uint8 being a marker in Dart, but I am not sure what is meant by that. Thanks in advance.

Xfce4
  • 557
  • 5
  • 28

2 Answers2

1

You most likely don't want to use a List<Uint8>, but a Uint8List.

final list = Uint8List(<amount of bytes in the file>);

...

final byte = randomAccessFile.readByte();
list.add(byte);

you can also read the whole file into a List<int> buffer and then create a Uint8List from that with RandomAccessFile.readInto.

But what I suspect that you want to do is not using RandomAccessFile at all, but just read in your file directly to a Uint8List:

final file = File(path);
Uint8List uint8list = await file.readAsBytes();

Or if you really want to go from a List<int> to a Uint8List then you can do:

Uint8List.fromList(yourList);
spydon
  • 9,372
  • 6
  • 33
  • 63
  • Thanks a lot for your answer. Actually I want to read the file block by block as the file size may be too large to read at once. I use `openedRndAccssFile.read(blockSize)` to get the whole block into a list of type `List`. Then I call `readByte()` in the end to complete the final multibyte utf-8 character (if necessary), which means the list should be expandable and I need to figure out converting `int` output of `readByte()` to `Uint8`. Another option is to store everything as `int` but that would be an inefficient use of resources. – Xfce4 Jun 18 '23 at 20:05
  • @Xfce4 I see, I added another option for that in the end of the answer. :) – spydon Jun 18 '23 at 20:44
  • Thank you. The last part would be helpful. Though, I would like to do all the operation on Uint8List or List from the beginning -if possible. – Xfce4 Jun 18 '23 at 23:39
1

That depends on what type Uint8 is.

If it's the type from dart:ffi, then it's a native type, which means you cannot have a Dart value with that type. If you read a Pointer<Uint8>, it returns the value as an int, and you write an int to it as well, which gets truncated on write.

Which means that you most likely don't have a List<Uint8>. You cannot, since there are no values of type Uint8 in the Dart heap. It's a native type that has to be converted to a Dart value, an int, when you access it from native memory.

Use an Uint8List if the bytes are stored in the Dart heap, or a Uint8Array if they're stored in the native heap.

lrn
  • 64,680
  • 7
  • 105
  • 121
  • So when I use Uint8 do I utilize the native heap which is not reachable by Dart heap? Then theoratically, I could solve this issue by using file read functions from native libraries, right ? – Xfce4 Jun 18 '23 at 23:56
  • 1
    When you write `Uin8` in Dart code, you refer to a type which has no instances in the Dart heap. It's a marker type for `dart:ffi` to know the native argument or return value layout, so that the Dart arguments can be marshalled into the correct layout, and the return values converted back, when calling a native function. If you use native code to read a file, e.g., by calling native `fopen`, `malloc`,`fread` and `fclose` functions, then you can probably use a `Pointer` to refer to the data that you allocated in the native heap. Maybe even `Array`. (I'm not a `dart:ffi` expert.) – lrn Jun 19 '23 at 17:52