2016-06-12 5 views
2

Я пытаюсь прочитать файл 100GB через стандартный ввод на одну строку за один раз, используяКак предотвратить наводнение сообщений с помощью open_port?

Port = open_port({fd, 0, 1}, [in, binary, {line, 4096}]), 

но заливает мою систему с сообщениями, пока не кончится баран. Есть ли возможность сделать это как {active, once} с портами? Существует также io: get_line(), но мне было интересно, может ли это сработать.

ответ

2

Нет, контроль над портами отсутствует, поэтому, если вы не можете обработать достаточно быстро, вы должны использовать другой метод обработки. Вы можете установить двоичный режим на STDIN используя

ok = io:setopts(standard_io, [binary]), 

, а затем вы можете прочитать его с помощью file:read_line(standard_io), если вы используете версию 17 или более поздней версии (была производительность влияет ошибка).

+0

Эй, Хайнек, спасибо, что это работает. Я разбираю jsons размером 100k или больше, и read_line, кажется, возвращается, прежде чем найти новую строку, вероятно, потому, что она превышает размер буфера. Настройка таких вещей, как {readahead, X}, возвращает ошибку, которая не поддерживается в стандарте_io. Как это обойти? – ForeverConfused

+0

@ForeverConfused: Я не знаю, можно ли установить 'readahead' для' standard_io'. Вы можете сделать обходной контроль наличия конца строки и конкатенировать незавершенные линии. Он будет выполнять копирование в памяти, но я не знаю другого решения. –

+0

Я пробовал это, файл: get_chars и сам делать буфер. Но даже если я только буфер 1000 строк сразу, по некоторым причинам, вызывает переполнение памяти. В итоге мне пришлось подключить stdin к netcat, а затем использовать erlang с {active, once} – ForeverConfused

 Смежные вопросы

  • Нет связанных вопросов^_^