Subscribe to this blog

Search This Blog

I/O Library Now Uses Streams

We have done a full re-design of the dart:io API (file, network, directories, etc) to use the classes and concepts in the core library and in dart:async. This means that there is almost no callback registration in dart:io any more. All async operations now use streams and futures.(These changes are available in bleeding_edge as of today, and should show up in a weekly build soon.)

We think this is a great step forward in aligning all of the “dart:” API's and for you to have fewer concepts to learn when using Dart for different tasks.However this is a breaking change which requires rewriting code using dart:io. The good news is that most of these changes should be mechanical. The following sections describe these changes in more details and give some examples on how to migrate code to the new API. For more information take a look on the API documentation for dart:io.Streams in dart:ioThe classes InputStream and OutputStream are gone and have been replaced with classes implementing IOSink and Stream<List<int>>.When reading from a Stream<List<int>> just use the listen method which have arguments matching the callbacks previously used. This shows how to migrate code using an InputStream to the streams-based API:dart:io v1 codeInputStream stream = ...stream.onData = () { var data = request.inputStream.read(); /* Process data. */};stream.onClosed = () { /* All data received. */};stream.onError = (e) { /* Error on input. */};dart:io v2 codeStream<List<int>> stream = ...stream.listen( (data) { /* Process data. */ }, onDone: () { /* All data received. */ }, onError: (e) { /* Error on input. */ });As the InputStream class is now gone so is the StringInputStream for turning a stream of bytes into strings and/or lines. Two new stream transformers StringDecoder and LineTransformer have been added to address this. The StringDecoder transforms a stream of List<int> to a stream of String and the LineTransformer transforms a stream of String to a new stream of String where each string is a line.dart:io v1 codeInputStream stream = ...StringInputStream stringStream = new StringInputStream(stream);stringStream.onLine = () { String line = stringStream.readLine(); /* Do something with line. */};stringStream.onClosed = () { /* No more lines */};stream.onError = (e) { /* Error on input. */};dart:io v2 codeStream<<int>> stream = ...stream .transform(new StringDecoder()) .transform(new LineTransformer()) .listen((String line) { /* Do something with line. */ }, onDone: () { /* No more lines */ }, onError: (e) { /* Error on input. */ });The IOSink replaces OutputStream and this shows how to migrate code using OutputStream to use an IOSink:dart:io v1 codeOutputStream stream = …stream.write([72, 101, 108, 108, 111]); // Hellostream.writeString(", world!");stream.close();dart:io v2 codeIOSink sink = …sink.add([72, 101, 108, 108, 111]); // Hellosink.addString(", world!");sink.close();The IOSink also allows you to pipe directly from a stream.HTTPThe main changes to the HTTP server and client part of dart:io are the following:* A new HttpServer listening for requests is created using the static method bind.* An HttpServer is a stream of HttpRequests.* The defaultRequestHandler setter and addRequestHandler method on HttpServer are gone.* The HttpRequest and HttpClientResponse objects implement Stream<List<int>>.* The HttpClientRequest and HttpResponse objects implement IOSink.To create a new listening HTTP server use the static method bind which returns a future.dart:io v1 codeHttpServer server = new HttpServer();server.defaultRequestHandler = …server.addRequestHandler(…);server.listen(“127.0.0.1”, 8080);// Now the HTTP server is bound and listening for requests.dart:io v2 codeHttpServer.bind(“127.0.0.1”, 8080) .then((HttpServer server) { server.listen( (HttpRequest request) { // Handle the request. });}The request routing through defaultRequestHandler and addRequestHandler is gone and any routing to specific request handling methods should be added to the listen handling. The HttpResponse is available as the response property on the HttpRequest object.For client side HTTP the HttpClient class still exists. The HttpClientConnection class is gone, and instead the request initiation methods get, post, open, etc. now returns a future for the HttpClientRequest object. The HttpClientRequest object has a response property which is a future for the HttpClientResponse. As a convenience the HttpClientRequest.close method also returns the future for the response. This shows how to migrate HTTP client code:dart:io v1 codeHttpClient client = new HttpClient();HttpClientConnection connection = client.get(...);connection.onRequest = (HttpClientRequest request) { // Prepare the request. request.outputStream.close();}connection.onResponse = (HttpClientResponse response) { // Process the response.}dart:io v2 codeHttpClient client = new HttpClient();client.get(...) .then((HttpClientRequest request) { // Prepare the request. return request.close(); }) .then((HttpClientResponse response) { // Process the response. });Web SocketsThe web socket interface has been simplified and now uses the same class for web socket connections on both the client and the server. The WebSocket class is a stream of events.On the server the web socket handling is implemented as a stream transformer. This transformer can transform a stream of HttpRequests into a stream of WebSockets.dart:io v1 codeHttpServer server = new HttpServer();server.listen(...);WebSocketHandler handler = new WebSocketHandler();handler.onOpen = (WebSocketConnection connection) { connection.onMessage = (Object message) { /* Handle message. */ }; connection.onClosed = (status, reason) { /* Handle closed. */ };};server.defaultRequestHandler = handler.onRequest;dart:io v2 codeHttpServer.bind(...).then((server) { server.transform(new WebSocketTransformer()).listen((WebSocket webSocket) { webSocket.listen((event) { if (event is MessageEvent) { /* Handle message. */ } else if (event is CloseEvent) { /* Handle closed. */ } }); });On the client connecting a web socket has become much simpler. Just use the WebSocket static method connect which returns a future for the web socket connection as shown here:dart:io v1 codeHttpClient client = new HttpClient();HttpClientConnection conn = client.openUrl(“https://127.0.0.1:8080”);WebSocketClientConnection wsconn = new WebSocketClientConnection(conn);wsconn.onMessage = (message) { /* Handle message. */}wsconn.onClosed = (status, reason) { /* Handle closed. */};dart:io v2 code

ProcessThe Process class uses Stream<List<int>> for stdout and stderr and IOSink for stdin. The exit code for the process is now available through the exitCode future.dart:io v1 codeProcess process = ...process.stdout.onData = ...process.stdout.onDone = ...process.onExit = (exitCode) { /* do something with exitCode. */ }dart:io v2 codeProcess process = ...process.stdout.listen(...);p.exitCode.then((exitCode) { /* do something with exitCode. */ });Likewise the types of the top level properties stdin, stdout and stderr have been changed. stdio is a Stream<List<int>> and stdout and stderr are IOSinks.File and directoryReading and writing a file also uses Stream<List<int>> and IOSink. To read a file change the use of openInputStream to openRead which returns a stream of type Stream<List<int>>. Likewise change the use of openOutputStream to openWrite which returns an IOSink.The Directory.list function now returns a stream of FileSystemEntity objects. The FileSystemEntity is a superclass of both File and Directory. The previous DirectoryLister where callbacks were set is now gone.dart:io v1 codeDirectory dir = ...DirectoryLister lister = dir.list();lister.onDir = (Directory directory) { /* Do something with directory. */ };lister.onFile = (File file) { /* Do something with file. */ };lister.onDone = (bool complete) { /* Listing ended.*/ };lister.onError = (error) { /* Listing error.*/ };dart:io v2 codeDirectory dir = ...dir.list().listen( (FileSystemEntity fse) { if (fse is Directory) { Directory directory = fse; /* Do something with directory. */ } else if (fse is File) { File file = fse; /* Do something with file. */ } }, onDone: () { /* Listing ended.*/ }, onError: (error) { /* Listing error.*/ });SocketsThe classes Socket and SecureSocket both implement Stream<List<int>> and IOSink as they support bidirectional communication. This replaces all the reading and writing previously provided through a combination of callbacks, read and write methods, and InputStream and OutputStream objects backed by sockets.Connecting a socket now uses a static method returning a future instead of a callback.dart:io v1 codeSocket socket = new Socket(host, port);socket.onConnect = () { /* Socket connected. */ }dart:io v2 codeSocket.connect(host, port).then((Socket socket) { /* Socket connected. */};The classes ServerSocket and SecureServerSocket now uses a static method returning a future when binding to an interface. A listening server socket delivers the socket connections as a stream instead of through the onConnection callback.dart:io v1 codeServerSocket socket = new ServerSocket(host, port);socket.onConnection = (Socket clientSocket) { /* Do something with the clientSocket. */}dart:io v2 codeServerSocket.bind(host, port).then((ServerSocket socket) { socket.listen((Socket clientSocket) { /* Do something with the clientSocket. */ })});Raw socketsIn order to provide a low level socket API we introduced raw sockets. Raw sockets give you access to low-level socket events without giving you data in your hand (think of this as the events you get from epoll on a socket file descriptor on Linux systems). Based on the low-level events you can read out data from the socket and decide when to write more data to the socket. The high-level Socket and ServerSocket classes are built on top of the RawSocket and RawServerSocket classes. Check out the API documentation on the Raw* classes.(Photo Credit: Maroonedcc)

Get link

Facebook

Twitter

Pinterest

Google+

Email

Other Apps

Labels

Popular posts from this blog

We are constantly asking ourselves:
How do we make developers even more productive when writing Dart apps?
We believe that a critical part of the answer to this question is to make strongmode – a sound static type system for Dart – the standard for all Dart developers.

Teams that use Dart to build apps like Soundtrap, AdWords, AdSense, and Greentea say they really enjoy using strong mode features, such as early error detection. In fact, teams that have switched completely to strong mode cite not only early error detection but also better code readability and maintainability as major benefits. We hear this both from small teams and – even more so – from large teams with hundreds of developers writing and maintaining millions of lines of Dart code. As Björn Sperber from Soundtrap says,
Strong mode and the smooth integration with IntelliJ is a joy to use and a huge improvement.
If you’ve tried out Flutter, you’ve already used strong mode checks from the Dart analyzer.

AngularDart v4 is now available. We've been busy since the release angular2
v3.1.0 in May. Not only did we "drop the 2", but we also improved the compiler
and tightened up the framework to give you smaller code, we updated the package
structure to improve usability, and we added several new features. Check out the
updated documentation to get
started.
Just angular
Upgrading to v4 will require more than updating your version constraint. The
package has changed names (back) to angular – dropping the 2.
You'll need to update your pubspec.yaml and the corresponding imports in your
code. In most instances, find-and-replace should do the trick. Going forward,
the package will be called package:angular. We'll just update the version
number.
Smaller code
The updated compiler in 4.0 allows type-based optimizations that not only
improve runtime performance but generate better code because we are able to
strongly type templates. A big result of the update is that many ap…

Dart 1.24 is now available. It includes the Dart Development Compiler and supports a new generic function type syntax. Get it now!

Figure 1: DDC debugging in Chrome.

Some notable changes in this release:pub serve now has support for the Dart Development Compiler. Unlike dart2js, this new compiler is modular, which allows pub to do incremental re-builds for pub serve.In practice what that means is you can edit your Dart files, refresh in Chrome (or other supported browsers), and see your edits almost immediately. This is because pub is only recompiling your package, not all packages that you depend on.There is one caveat with the new compiler, which is that your package and your dependencies must all be strong mode clean.You can also use the new compiler to run your tests in Chrome much more quickly than you can with dart2js.Read more in the changelog.You can now publish packages that depend on the Flutter SDK to pub. Moreover, pub.dartlang.org has started tagging Flutter plugins with …