2015-03-01 2 views
2

У меня есть программа командной строки дротика, которые хотят, чтобы иметь возможность данных труб от оболочки к программе Дарта (например, cat file.txt | dart my_program.dart или принимать входной, пока пользователь использует Ctrl + д). Просматривая учебники онлайн, единственная документация, которую я нашел при сохранении ввода от stdin, была stdin.readLineSync(). Однако, как следует из названия, это только чтение первой строки.Как записать stdin (более одной строки) в String в Dart?

Как можно захватить все содержимое stdin в String? Кроме того, будут ли проблемы с безопасностью, если пользователь попытается подключиться к огромному файлу? Есть ли ограничение на длительность строки? Как я могу защититься от этого?

Благодарим за помощь!

ответ

0

Я изучил код stdin.readLineSync() и был в состоянии изменить его, чтобы соответствовать моим потребностям:

import 'dart:convert'; 
import 'dart:io'; 

String readInputSync({Encoding encoding: SYSTEM_ENCODING}) { 
    final List input = []; 
    while (true) { 
    int byte = stdin.readByteSync(); 
    if (byte < 0) { 
     if (input.isEmpty) return null; 
     break; 
    } 
    input.add(byte); 
    } 
    return encoding.decode(input); 
} 

void main() { 
    String input = readInputSync(); 
    myFunction(input); // Take the input as an argument to a function 
} 

мне нужно было читать синхронно с стандартного ввода для того, чтобы приостановить программу пока не закончится весь stdin (до конца файла или Ctrl + d).

Спасибо за вашу помощь! Я не думаю, что смог бы понять это без вашей помощи.

0

Вы можете использовать

импорт 'дротик: Io', как гипергликемии; Импорт 'дротик: async' show Future, Stream, StreamSubscription; Импорт 'дротик: конвертировать' шоу UTF8;

void main() { 
    StreamSubscription subscr = io.stdin.transform(UTF8.decoder).listen((data) => 
     print(data)); 
} 

Вы можете контролировать, будет ли больше данных должны быть получены или нет с

subscr.pause(); 
subscr.resume(); 

Слушайте на стандартном вводе передает данные в кусках 16kb, если я правильно помню (ИО размер буфера определяется Dart), это позволяет для получения объема данных, которые вы можете обрабатывать. Если вы хотите сохранить одну большую строку в памяти, вам нужно иметь доступную память.

Смотрите также
- https://stackoverflow.com/a/26343041/217408 (набор VM памяти)
- https://stackoverflow.com/a/12691502/217408
- https://stackoverflow.com/a/28039661/217408

+0

Спасибо, Гюнтер. Я попробовал ваше предложение, но я все еще не уверен, как это может захватить stdin в String в Dart. Можете ли вы расширить свой ответ немного больше? Еще раз спасибо! –

+0

Я обновил свой ответ. Если вы хотите получить более конкретный ответ, предоставьте дополнительную информацию о том, что вы пытаетесь выполнить, и что именно вас беспокоит. –

+0

Эй, Гюнтер. Извините, я опоздал с тобой вернуться к тебе. Ваше предложение работает, но я не смог его изменить, чтобы удовлетворить мои потребности. В основном, я пытаюсь сделать что-то вроде 'String input = stdin.readLineSync()', но уметь сохранять несколько строк вместо одного. Для фона я работаю над предварительным процессором CSS. Поэтому мне нужно сохранить stdin в строку, а затем обработать строку. –

3

Следующая программа в интерактивном режиме, отзовется ваш вклад, но выгоды каждого символа.

Вы также можете отправить файл к нему.

dart upper_cat.dart < file.txt 

Это выводит файл с каждым символом, заглавным.

import 'dart:convert'; 
import 'dart:io'; 

main() { 

    // Stop your keystrokes being printed automatically. 
    stdin.echoMode = false; 

    // This will cause the stdin stream to provide the input as soon as it 
    // arrives, so in interactive mode this will be one key press at a time. 
    stdin.lineMode = false; 

    var subscription; 
    subscription = stdin.listen((List<int> data) { 

    // Ctrl-D in the terminal sends an ascii end of transmission character. 
    // http://www.asciitable.com/ 
    if (data.contains(4)) { 
     // On my computer (linux) if you don't switch this back on the console 
     // will do wierd things. 
     stdin.echoMode = true; 

     // Stop listening. 
     subscription.cancel(); 
    } else { 

     // Translate character codes into a string. 
     var s = LATIN1.decode(data); 

     // Capitalise the input and write it back to the screen. 
     stdout.write(s.toUpperCase()); 
    } 
    }); 

} 

Существует также console библиотеки, чтобы помочь с такого рода вещи. Я не пробовал, но дайте ему снимок и отчитайтесь;)

В следующем примере обрабатывается вход UTF8 - в приведенном выше примере для ввода требуется 1 байтовый символ.

import 'dart:convert'; 
import 'dart:io'; 

main() { 

    stdin.echoMode = false; 
    stdin.lineMode = false; 

    var subscription; 
    subscription = stdin 
    .map((List<int> data) { 
     if (data.contains(4)) { 
     stdin.echoMode = true; 
     subscription.cancel(); 
     } 
     return data; 
    }) 
    .transform(UTF8.decoder) 
    .map((String s) => s.toUpperCase()) 
    .listen(stdout.write); 
} 
+0

Привет, Грег! Спасибо за ваше предложение. Я не мог понять, как изменить код в соответствии с моими потребностями. См. Мой комментарий к решению Гюнтера. В основном, я пытаюсь сделать что-то вроде 'String input = stdin.readLineSync()', но уметь сохранять несколько строк вместо одного. Если у вас есть другие предложения, пожалуйста, дайте мне знать! Благодаря! –

+1

Я думаю, вам нужно быть более ясным о проблеме, которую вы пытаетесь решить. то есть функция может прослушивать ввод и возвращать строку при достижении Ctrl + D. Или программа может ждать символа новой строки и возвращать строку, содержащую строку. Если программа должна читать несколько строк, как она знает, что это делается чтение? Будет ли он ждать, пока он не прочитает пустую строку? Или будет ждать, пока он прочитает строку со словом «end» на нем? –