Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: src/site/docs/tutorials/cmdline/index.markdown

Issue 116673004: adding new command-line app tutorial (Closed) Base URL: https://github.com/dart-lang/dartlang.org.git@master
Patch Set: fixed one final tweak from seth Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 ---
2 layout: default
3 title: "Write Command-Line Apps"
4 description: "Basics for command-line apps"
5 has-permalinks: true
6 tutorial:
7 id: dart-io
8 next: /
9 next-title: "Home"
10 prev: indexeddb/
11 prev-title: "Use IndexedDB"
12 ---
13
14 {% capture whats_the_point %}
15
16 * Command-line applications need to do input and output.
17 * The dart:io library provides I/O functionality.
18 * The args package helps define and parse command-line arguments.
19 * Most input and output requires the use of Streams.
20 * Streams provide a series of asynchronous data events.
21 * To handle asynchronous data, you need to use Futures.
22
23 {% endcapture %}
24
25 {% capture sample_links %}
26
27 <p> This tutorial features these examples:</p>
28 * helloworld
29 * dcat
30
31 <p>
32 Don't have the source code?
33 <a href="https://github.com/dart-lang/dart-tutorials-samples/archive/master.zip" >
34 Download it.
35 </a>
36
37 {% endcapture %}
38
39 {% capture content %}
40
41 <div class="tute-target-title">
42 <h1>{{page.title}}</h1>
43 <h3>An introduction to standalone apps</h3>
44 </div>
45
46 This tutorial teaches you how to build command-line apps
47 and shows you a few small command-line applications.
48 These programs use resources that most command-line applications need,
49 including the standard output, error, and input streams,
50 command-line arguments, files and directories, and more.
51
52 * [Running an app with the standalone Dart VM](#run-the-first-app)
53 * [Review briefly the dcat example code](#dcat-code)
54 * [Parsing command-line arguments](#cmd-line-args)
55 * [Reading and writing with stdin, stdout, and stderr](#std-in-out-err)
56 * [Getting info about a file](#filesystementity)
57 * [Reading a file](#reading-a-file)
58 * [Writing a file](#writing-a-file)
59 * [Getting environment information](#env-var)
60 * [Setting exit codes](#exit-codes)
61 * [Summary](#summary)
62 * [Other resources](#other-resources)
63 * [What next?](#what-next)
64
65 ## Running an app with the standalone Dart VM {#run-the-first-app}
66
67 To run a command-line app, you need the Dart VM (`dart`),
68 which comes in the [Dart SDK download](/tools/sdk/).
69 (If you downloaded Dart Editor, you already have the Dart VM.)
70
71 If you installed the Dart download in a directory called `~/myDartDownload`,
72 you can find `dart`
73 in `~/myDartDownload/dart-sdk/bin`.
74
75 <div markdown="1">
76
77 ![The path to the Dart VM](images/filestructure.png)
78
79 </div>
80
81 By putting this directory in your PATH
82 you can refer to the `dart` command and other commands,
83 such as the dart analyzer, by name.
84
85 Let's run a small program.
86
87 <ol>
88 <li markdown="1">
89 Create a file called `helloworld.dart` that contains this code:
90
91 {% prettify dart %}
92 void main() {
93 print('Hello, World!');
94 }
95 {% endprettify %}
96 </li>
97
98 <li markdown="1">
99 In the directory that contains the file you just created,
100 run the program with the command as shown by the highlighted text.
101
102 {% prettify bash %}
103 % [[highlight]]dart helloworld.dart[[/highlight]]
104 Hello, World!
105 %
106 {% endprettify %}
107
108 </li>
109 </ol>
110
111 The Dart VM supports many options.
112 Use `dart --help` to see commonly used options.
113 Use `dart --verbose` to see all options.
114
115 ## Review briefly the dcat example code {#dcat-code}
116
117 Take a quick look at the code for a small sample called `dcat`,
118 which displays the contents of any files listed on the command line.
119 This program uses various classes, functions, and properties
120 available to command-line apps.
121 This tutorial goes into detail about this app in the following sections.
122 For a brief look now, hover over the highlighted code below for explanations.
123
124 <pre class="prettyprint lang-dart">
125 import 'dart:async';
126 import 'dart:convert';
127 import 'dart:io';
128
129 import 'package:args/args.dart';
130
131 const LINE_NUMBER = 'line-number';
132 var NEWLINE = '\n';
133
134 ArgResults argResults;
135
136 void main(<a href="#" class="dart-popover" data-toggle="popover" title="Command- line arguments" data-html="true" data-trigger="hover focus" data-content="Comman d-line arguments are passed in by the system when the program starts.">List&lt;S tring&gt; arguments</a>) {
137 final parser = new ArgParser()
138 ..addFlag(LINE_NUMBER, negatable: false, abbr: 'n');
139
140 <a href="#" class="dart-popover" data-toggle="popover" title="Arguments parser " data-html="true" data-trigger="hover focus" data-content="The ArgParser class provides help with parsing command-line arguments.">argResults = parser.parse(ar guments);</a>
141 List&lt;String&gt; paths = argResults.rest;
142
143 dcat(paths, argResults[LINE_NUMBER]);
144 }
145
146 Future dcat(List&lt;String&gt; paths, bool showLineNumbers) {
147 if (paths.isEmpty) {
148 // No files provided as arguments. Read from stdin and print each line.
149 return <a href="#" class="dart-popover" data-toggle="popover" title="Standar d I/O streams" data-html="true" data-trigger="hover focus" data-content="This co de reads from the standard input stream and pipes the data to the standard outpu t stream.">stdin.pipe(stdout);</a>
150 } else {
151 return Future.forEach(paths, (path) {
152 int lineNumber = 1;
153 <a href="#" class="dart-popover" data-toggle="popover" title="Open a file for reading" data-html="true" data-trigger="hover focus" data-content="Use the F ile class to represent a file on the native file system.">Stream&lt;List&lt;int& gt;&gt; stream = new File(path).openRead();</a>
154 return stream
155 <a href="#" class="dart-popover" data-toggle="popover" title="Data con verters" data-html="true" data-trigger="hover focus" data-content="Convert data as it becomes available on a stream.">.transform(UTF8.decoder)</a>
156 .transform(const LineSplitter())
157 <a href="#" class="dart-popover" data-toggle="popover" title="Get data from a stream" data-html="true" data-trigger="hover focus" data-content="Listen to a stream to get data when it becomes available.">.listen((line)</a> {
158 if (showLineNumbers) {
159 stdout.write('${lineNumber++} ');
160 }
161 stdout.writeln(line);
162 }).asFuture().catchError((_) =&gt; _handleError(path));
163 });
164 }
165 }
166
167 _handleError(String path) {
168 <a href="#" class="dart-popover" data-toggle="popover" title="Test a path" dat a-html="true" data-trigger="hover focus" data-content="You can get information a bout the file system on which your program is running.">FileSystemEntity.isDirec tory(path)</a>.then((isDir) {
169 if (isDir) {
170 print('error: $path is a directory');
171 } else {
172 print('error: $path not found');
173 }
174 });
175 <a href="#" class="dart-popover" data-toggle="popover" title="Exit code" data- html="true" data-trigger="hover focus" data-content="A well-behaved command-line app sets an exit code to indicate whether the program was successful.">exitCode = 2;</a>
176 }
177
178 </pre>
179
180 ## Parsing command-line arguments {#cmd-line-args}
181
182 The
183 <a href="https://api.dartlang.org/args.html" target="_blank">args</a>
184 package, a software bundle that contains a library of Dart code, provides
185 parser support for transforming raw command-line arguments
186 into a set of options, flags, and additional values.
187 Import the library as follows:
188
189 {% prettify dart %}
190 import 'package:args/args.dart';
191 {% endprettify %}
192
193 The args library contains two classes:
194
195 | Library | Description |
196 |---|---|
197 | <a href="https://api.dartlang.org/args/ArgParser" target="_blank">ArgParser</a > | A class that parses command-line arguments |
198 | <a href="https://api.dartlang.org/args/ArgResults" target="_blank">ArgResults< /a> | The result of parsing command-line arguments using ArgParser. |
199 {: .table }
200
201 Let's take a look at the `dcat` sample,
202 which uses ArgParser and ArgResults to parse and store its command-line argument s.
203
204 <ol>
205 <li markdown="1">
206 Copy the sample file from the github repo:
207 <a href="https://github.com/dart-lang/dart-tutorials-samples/blob/master/bin/dca t.dart">dcat.dart</a>.
208 </li>
209
210 <li markdown="1">
211 Run the program from the command line as shown by the highlighted text.
212
213 {% prettify bash %}
214 $ [[highlight]]dart dcat.dart -n quotes.txt[[/highlight]]
215 1 Be yourself. Everyone else is taken. -Oscar Wilde
216 2 Don't cry because it's over, smile because it happened. -Dr. Seuss
217 3 You only live once, but if you do it right, once is enough. -Mae West
218 ...
219 {% endprettify %}
220
221 The program displays the contents of the source code file and
222 preceeds each line with a line number.
223 </li>
224
225 </ol>
226
227 The following diagram shows how the `dcat` command line used above
228 is parsed into the `ArgResults` object.
229
230 ![ArgsParser parses command-line arguments](images/commandlineargs.png)
231
232 You can access flags and options by name,
233 treating the ArgResults object like a Map.
234 You can access other values with properties such as `rest`.
235
236 Here's the code from `dcat` that deals with command-line arguments:
237
238 <pre class="prettyprint lang-dart">
239
240 ...
241 <a href="#" class="dart-popover" data-toggle="popover" title="Parsed arguments" data-html="true" data-trigger="hover focus" data-content="This object contains p arsed options and flags.">ArgResults argResults;</a>
242
243 void main(<a href="#" class="dart-popover" data-toggle="popover" title="Command- line arguments" data-html="true" data-trigger="hover focus" data-content="The sy stem passes command-line arguments into the program in a list of strings.">List& lt;String&gt; arguments</a>) {
244 final parser = new ArgParser()
245 <a href="#" class="dart-popover" data-toggle="popover" title="Define a val id flag" data-html="true" data-trigger="hover focus" data-content="Add a flag de finition to the command-line argument parser. This code defines the flag -n, whi ch when used displays line numbers.">..addFlag(LINE_NUMBER, negatable: false, ab br: 'n')</a>;
246
247 argResults = parser.<a href="#" class="dart-popover" data-toggle="popover" tit le="Parse the arguments" data-html="true" data-trigger="hover focus" data-conten t="Parse the arguments that were passed into the main() function. The parser sto ps parsing if it finds an undefined option or flag.">parse(arguments)</a>;
248 List&lt;String&gt; paths = <a href="#" class="dart-popover" data-toggle="popov er" title="Remaining arguments" data-html="true" data-trigger="hover focus" data -content="To get the arguments that remain after parsing all of the valid option s and flags, use the rest property.">argResults.rest</a>;
249
250 dcat(paths, <a href="#" class="dart-popover" data-toggle="popover" title="Refe r to options and flags by name" data-html="true" data-trigger="hover focus" data -content="You can refer to an option or flag by name treating the ArgResults obj ect like a Map.">argResults[LINE_NUMBER])</a>;
251 }
252 ...
253 </pre>
254
255 The
256 <a href="https://api.dartlang.org/args.html" target="_blank">API docs</a>
257 for the args library
258 provide detailed information
259 to help you use ArgsParser and ArgResults classes.
260
261 ## Reading and writing with stdin, stdout, and stderr {#std-in-out-err}
262
263 Like other languages,
264 Dart has standard output, standard error, and standard input streams.
265 The standard I/O streams are defined at the top level of the dart:io library,
266
267 | Stream | Description |
268 |---|---|
269 | <a href="https://api.dartlang.org/dart_io.html#stdout" target="_blank">stdout< /a> | The standard output |
270 | <a href="https://api.dartlang.org/dart_io.html#stderr" target="_blank">stderr< /a> | The standard error |
271 | <a href="https://api.dartlang.org/dart_io.html#stdin" target="_blank">stdin</a > | The standard input |
272 {: .table }
273
274 Import the dart:io library as follows:
275
276 {% prettify dart %}
277 import 'dart:io';
278 {% endprettify %}
279
280 Only command-line applications, not web applications,
281 can use the dart:io library.
282
283 ### stdout
284
285 Here's the code from the `dcat` program that writes the line number to the `stdo ut`
286 (if the -n flag is set) followed by the line from the file.
287
288 {% prettify dart %}
289 if (showLineNumbers) {
290 [[highlight]]stdout.write('${lineNumber++} ');[[/highlight]]
291 }
292
293 [[highlight]]stdout.writeln(line);[[/highlight]]
294 {% endprettify %}
295
296 The `write()` and `writeln()` methods take an object of any type,
297 convert it to a string, and print it. The `writeln()` method
298 also prints a newline character.
299 `dcat` uses the `write()` method to print the line number so the
300 line number and the text appear on the same line.
301
302 You can also use the `writeAll()` method to print a list of objects,
303 or use `addStream()` to asynchronously print all of the elements from a stream.
304
305 `stdout` provides more functionality than the `print()` function.
306 For example, you can display the contents of a stream with `stdout`.
307 However, you must use `print()` instead of `stdout`
308 for programs that are converted to and run in JavaScript.
309
310 ### stderr
311
312 Use `stderr` to write error messages to the console.
313 The standard error stream has the same methods as `stdout`,
314 and you use it in the same way.
315 Although both `stdout` and `stderr` print to the console,
316 their output is separate
317 and can be redirected or piped at the command line
318 or programmatically to different destinations.
319
320 This code from `dcat` prints an error message if the user
321 tries to list a directory or if the file is not found.
322
323 {% prettify dart %}
324 if (isDir) {
325 [[highlight]]stderr.writeln('error: $path is a directory');[[/highlight]]
326 } else {
327 [[highlight]]stderr.writeln('error: $path not found');[[/highlight]]
328 }
329 {% endprettify %}
330
331 ### stdin
332
333 The standard input stream typically
334 reads data synchronously from the keyboard,
335 although it can read asynchronously
336 and it can get input piped in from the standard
337 output of another program.
338
339 Here's a small program that reads a single line from `stdin`:
340
341 {% prettify dart %}
342 import 'dart:io';
343
344 void main() {
345 stdout.writeln('Type something');
346 String input = stdin.readLineSync();
347 stdout.writeln('You typed: $input');
348 }
349 {% endprettify %}
350
351 The `readLineSync()` method reads text from the standard input stream,
352 blocking until the user types in text and presses return.
353 This little program prints out the typed text.
354
355 In the `dcat` program,
356 if the user does not provide a filename on the command line,
357 the program instead reads synchronously from stdin
358 using the `pipe()` method.
359
360 {% prettify dart %}
361 return [[highlight]]stdin[[/highlight]].pipe(stdout);
362 {% endprettify %}
363
364 In this case,
365 the user types in lines of text and the program copies them to stdout.
366 The user signals the end of input by typing &lt;ctl-d&gt;.
367
368 {% prettify bash %}
369 $ [[highlight]]dart dcat.dart[[/highlight]]
370 [[highlight]]The quick brown fox jumped over the lazy dog.[[/highlight]]
371 The quick brown fox jumped over the lazy dog.
372 ...
373 {% endprettify %}
374
375 ## Getting info about a file {#filesystementity}
376
377 The
378 <a href="https://api.dartlang.org/dart_io/FileSystemEntity.html" target="_blank" >FileSystemEntity</a>
379 class in the dart:io library provides
380 properties and static methods that help you inspect and manipulate the file syst em.
381
382 For example, if you have a path,
383 you can determine whether the path is a file, a directory, a link, or not found
384 by using the `type()` method from the `FileSystemEntity` class.
385 Because the `type()` method accesses the file system,
386 it performs the check asynchronously within a Future.
387
388 The following code from
389 the `dcat` example uses `FileSystemEntity` to determine if the path provided
390 on the command line is a directory.
391 The Future returns a boolean that indicates
392 if the path is a directory or not.
393
394 {% prettify dart %}
395 [[highlight]]FileSystemEntity.isDirectory(path)[[/highlight]].then((isDir) {
396 if (isDir) {
397 stderr.writeln('error: $path is a directory');
398 } else {
399 stderr.writeln('error: $path not found');
400 }
401 exit(2);
402 });
403 {% endprettify %}
404
405 Other interesting methods in the `FileSystemEntity` class
406 include `isFile()`, `exists()`, `stat()`, `delete()`,
407 and `rename()`,
408 all of which also use a Future to return a value.
409
410 FileSystemEntity is the superclass for the File, Directory, and Link classes.
411
412 ## Reading a file {#reading-a-file}
413
414 `dcat` opens each file listed on the command line
415 with the `openRead()` method,
416 which returns a stream.
417 The `listen()` method registers a callback function that runs
418 when data becomes available on the stream.
419 The callback function writes that data to stdout.
420
421 {% prettify dart %}
422 return Future.forEach(paths, (path) {
423 int lineNumber = 1;
424 Stream<List<int>> stream = new File(path).openRead();
425
426 return stream
427 ...
428 [[highlight]].listen((line) {
429 if (showLineNumbers) {
430 stdout.write('${lineNumber++} ');
431 }
432 stdout.writeln(line);
433 })[[/highlight]].asFuture()
434 .catchError((_) => _handleError(path));
435 });
436 {% endprettify %}
437
438 The following shows the rest of the
439 code, which uses two decoders that transform the data before the
440 `listen()` callback function runs.
441 The UTF8 decoder converts the data into Dart strings.
442 `LineSplitter` splits the data at newlines.
443
444 {% prettify dart %}
445 return Future.forEach(paths, (path) {
446 int lineNumber = 1;
447 Stream<List<int>> stream = new File(path).openRead();
448
449 return stream
450 [[highlight]].transform(UTF8.decoder)
451 .transform(const LineSplitter())[[/highlight]]
452 .listen((line) {
453 if (showLineNumbers) {
454 stdout.write('${lineNumber++} ');
455 }
456 stdout.writeln(line);
457 }).asFuture()
458 .catchError((_) => _handleError(path));
459 });
460 {% endprettify %}
461
462 The dart:convert library contains these and other data converters, including
463 one for JSON.
464 To use these converters you need to import the dart:convert library:
465
466 {% prettify dart %}
467 import 'dart:convert';
468 {% endprettify %}
469
470 ## Writing a file {#writing-a-file}
471
472 The easiest way to write text to a file is to
473 create a
474 <a href="https://api.dartlang.org/dart_io/File.html" target="_blank">File</a>
475 object and use the `writeAsString()` method:
476
477 {% prettify dart %}
478 File quotesFile = new File('quotes.txt');
479 String stronger = 'That which does not kill us makes us stronger. -Nietzsche';
480
481 quotesFile.writeAsString(stronger, mode: FileMode.APPEND)
482 .then((_) { print('Data written.'); });
483 {% endprettify %}
484
485 The `writeAsString()` method writes the data asynchronously via a Future.
486 It opens the file before writing and closes the file when done.
487 To append data to an existing file, you can use the optional
488 parameter `mode` and set its value to `FileMode.APPEND`.
489 Otherwise, the mode is `FileMode.WRITE` and the previous contents of the file,
490 if any, are overwritten.
491
492 If you want to write more data, you can open the file for writing.
493 The `openWrite()` method returns an IOSink (the same type as stdin and stderr).
494 You can continue to write to the file until done,
495 at which time, you must close the file.
496 The `close()` method is asynchronous and returns a Future.
497
498 {% prettify dart %}
499 IOSink quotes = new File('quotes.txt').openWrite(mode: FileMode.APPEND);
500
501 quotes.write('A woman is like a tea bag; ');
502 quotes.write("you never know how strong it is until it's in hot water.");
503 quotes.writeln(" -Eleanor Roosevelt");
504 quotes.close().then((_) { print('done'); } );
505 {% endprettify %}
506
507 ## Getting environment information {#env-var}
508
509 Use the
510 <a href="https://api.dartlang.org/dart_io/Platform.html" target="_blank">Platfor m</a>
511 class
512 to get information about the machine and OS that the program is running on.
513 Note: Use the Platform class from the dart:io library,
514 not from the dart:html library.
515
516 `Platform.environment` provides a copy of the environment
517 variables in a mutable map.
518
519 {% prettify dart %}
520 Map environmentVars = Platform.environment;
521
522 print('PWD = ${environmentVars["PWD"]}');
523 print('LOGNAME = ${environmentVars["LOGNAME"]}');
524 print('PATH = ${environmentVars["PATH"]}');
525 {% endprettify %}
526
527 `Platform` provides other useful properties that give
528 information about the machine, OS, and currently
529 running program.
530 For example:
531
532 * `Platform.isMacOS()`
533 * `Platform.numberOfProcessors`
534 * `Platform.script.path`
535
536 ## Setting exit codes {#exit-codes}
537
538 The dart:io library defines a top-level property,
539 `exitCode`, that you can change to set the exit code for
540 the current invocation of the Dart VM.
541 An exit code is a number passed from
542 the Dart program to the parent process
543 to indicate the success, failure, or other state of the
544 execution of the program.
545
546 The `dcat` program sets the exit code
547 in the `_handleError()` function to indicate that an error
548 occcurred during execution.
549
550 {% prettify dart %}
551 _handleError(String path) {
552 FileSystemEntity.isDirectory(path).then((isDir) {
553 if (isDir) {
554 stderr.writeln('error: $path is a directory');
555 } else {
556 stderr.writeln('error: $path not found');
557 }
558 [[highlight]]exitCode = 2;[[/highlight]]
559 });
560 }
561 {% endprettify %}
562
563 An exit code of 2 indicates that the program encountered an error.
564
565 An alternative to using `exitCode` is to use the top-level `exit()` function,
566 which sets the exit code and quits the program immediately.
567 For example, the `_handleError()` function could call `exit(2)`
568 instead of setting `exitCode` to 2,
569 but `exit()` would quit the program
570 and it might not process all of the files on the command line.
571
572 <aside class="alert alert-info" markdown="1">
573 Generally speaking, you are better off using the `exitCode` property,
574 which sets the exit code but allows the program to continue through to its
575 natural completion.
576 </aside>
577
578 Although you can use any number for an exit code,
579 by convention, the codes in the table below have the following meanings:
580
581 | Code | Meaning |
582 |---|---|
583 | 0 | Success |
584 | 1 | Warnings |
585 | 2 | Errors |
586 {: .table }
587
588 ## Summary {#summary}
589
590 This tutorial described some basic API found in these classes from the dart:io l ibrary:
591
592 | API | Description |
593 |---|---|
594 | <a href="https://api.dartlang.org/dart_io/IOSink.html" target="_blank">IOSink< /a> | Helper class for objects that consume data from streams. |
595 | <a href="https://api.dartlang.org/dart_io/File.html" target="_blank">File</a> | Represents a file on the native file system |
596 | <a href="https://api.dartlang.org/dart_io/Directory.html" target="_blank">Dire ctory</a> | Represents a directory on the native file system |
597 | <a href="https://api.dartlang.org/dart_io/FileSystemEntity.html" target="_blan k">FileSystemEntity</a> | Superclass for File and Directory |
598 | <a href="https://api.dartlang.org/dart_io/Platform.html" target="_blank">Platf orm</a> | Provides information about the machine and operating system |
599 | <a href="https://api.dartlang.org/dart_io.html#stdout" target="_blank">stdout< /a> | The standard output |
600 | <a href="https://api.dartlang.org/dart_io.html#stderr" target="_blank">stderr< /a> | The standard error |
601 | <a href="https://api.dartlang.org/dart_io.html#stdin" target="_blank">stdin</a > | The standard input |
602 | <a href="https://api.dartlang.org/dart_io.html#exitCode" target="_blank">exitC ode</a> | Sets the exit code |
603 | <a href="https://api.dartlang.org/dart_io.html#exit" target="_blank">exit()</a > | Sets the exit code and quits |
604 {: .table }
605
606 In addition, this tutorial covers two classes that help with command-line argume nts:
607
608 | Class | Description |
609 |---|---|
610 | <a href="https://api.dartlang.org/args/ArgParser" target="_blank">ArgParser</a > | A class that transforms a list of raw arguments and into a set of options, f lags, and remaining values. |
611 | <a href="https://api.dartlang.org/args/ArgResults" target="_blank">ArgResults< /a> | The result of parsing raw command line arguments using ArgParser. |
612 {: .table }
613
614 ## Other resources {#other-resources}
615
616 Check out the [Command-line Apps Programmers' Guide](/docs/serverguide.html)
617 to find more resources related to writing command-line apps.
618
619 See the
620 [Dartiverse Search walkthrough](/docs/dart-up-and-running/contents/ch05.html)
621 for an example of another kind of command-line app: an HTTP server.
622
623 Refer to the API docs for <a href="https://api.dartlang.org/dart_io.html" target ="_blank">dart:io</a>,
624 <a href="https://api.dartlang.org/dart_async.html" target="_blank">dart:async</a >,
625 <a href="https://api.dartlang.org/dart_convert.html" target="_blank">dart:conver t</a>,
626 and the
627 <a href="https://api.dartlang.org/dart_args.html" target="_blank">args</a>
628 package for more classes, functions, and properties.
629
630 ## What next? {#what-next}
631
632 The [Get Input from a Form](/docs/tutorials/forms/) tutorial
633 features a client-server.
634 The code for the server, which uses CORS headers and handles
635 POST requests, is explained in detail.
636
637 {% endcapture %}
638
639 {% include tutorial.html %}
OLDNEW
« no previous file with comments | « src/site/docs/tutorials/cmdline/images/sourceforhomepage.png ('k') | src/site/docs/tutorials/index.markdown » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698