afsina
afsina

Reputation: 132

DataOutputStream equivalent for Dart

I am looking for a Java DataOutputStream equivalent for Dart where I can write arbitrary types (int, string, float, byte array etc). There is RandomAccessFile but it does not provide byte array or float-double values. ByteArray seems to have some necessary functions but I am not sure how to write it to a file or an OutputStream.

Upvotes: 3

Views: 1702

Answers (5)

Bill Foote
Bill Foote

Reputation: 421

This has been around for a while, but I searched and didn't find good DataInput/OutputStream interoperability classes. I wanted a version that works with streams, so I could process files that don't comfortably fit in RAM. So I wrote one.

It's published over at https://pub.dev/packages/jovial_misc in io_streams, or if you prefer, https://github.com/zathras/misc/tree/master/dart/jovial_misc. I made it so it interoperates with java.io.DataInputStream and java.io.DataOutputStream. Code using it looks a little like this:

import 'package:convert/convert.dart';
import 'package:jovial_misc/io_utils.dart';

void main() async {
  final acc = ByteAccumulatorSink();
  final out = DataOutputSink(acc);
  out.writeUTF8('Hello, world.');
  out.close();

  final stream = Stream<List<int>>.fromIterable([acc.bytes]);
  final dis = DataInputStream(stream);
  print(await dis.readUTF8());
  await dis.close();
}

The Stream<List<int>> would of course typically come from a socket, or File.openRead(), etc. There's also a DataInputStream variant that is synchronous and takes an Iterable, if you do have all the byte data available up front.

DataInputStream and DataOutputSink are pretty much the obvious mapping of the java.io classes. The tricky part is the buffer management, since a stream shoves data at you in List<int> instances that probably aren't lined up with the data you want. And, of course, it's necessary to do everything asynchronously.

HTH.

Upvotes: 1

Mark
Mark

Reputation: 4935

You could use this class: https://github.com/TomCaserta/dart_io/blob/master/lib/data_output.dart

Unfortunately (a) it doesn't handle streams; (b) writeLong doesn't take a single integer. I have raised an issue for the Dart SDK: https://github.com/dart-lang/sdk/issues/31166

Edit: I have forked the dart_io package and fixed the two problems described above. My new package is published as dart_data_io: https://github.com/markmclaren2/dart_data_io

Upvotes: 0

Mark
Mark

Reputation: 4935

The closest thing I could find is this package: https://github.com/TomCaserta/dart_io/ . Unfortunately there is a bug when reading to the end of the byte array - see my pull request in GitHub.

Upvotes: 0

Ladicek
Ladicek

Reputation: 6617

You are essentially asking for arbitrary object serialization. And while the Dart VM has one, it isn't exposed to programmers (it is only used for snapshotting and message passing). I'd say that it would be a mistake to expose it -- in different situations, we have different requirements for serialization and "one true solution" isn't gonna work (Java showed us that already).

For example, I'm working on a MsgPack implementation for Dart, I know that Protobuf port is also in the works, maybe someone will start a Thrift port... the possibilities are endless.

Upvotes: 0

Cutch
Cutch

Reputation: 3575

Here is some simple code showing how to write a ByteArray into an OutputStream:

#import('dart:io');
#import('dart:scalarlist');

main() {
        File file = new File("c:\\temp\\foo.txt");
        OutputStream os = file.openOutputStream();
        os.onNoPendingWrites = () {
                print('Finished writing. Closing.');
                os.flush();
                os.close();
        };
        Uint8List byteList = new Uint8List(64);
        ByteArray byteArray = byteList.asByteArray();
        int offset = 0;
        offset = byteArray.setUint8(offset, 72);
        offset = byteArray.setUint8(offset, 101);
        offset = byteArray.setUint8(offset, 108);
        offset = byteArray.setUint8(offset, 108);
        offset = byteArray.setUint8(offset, 111);
        offset = byteArray.setUint8(offset, 0);
        byteArray.setFloat32(offset, 1.0);
        os.write(byteList);
}

Upvotes: 2

Related Questions