You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Erlang中读取标准输入(STDIN)的全部数据?

在Erlang中读取全部STDIN并解析JSON

要一次性读取管道传入的全部STDIN数据,核心思路是循环读取输入直到遇到EOF,累加所有数据后再进行JSON解析。以下是具体实现方案:

核心读取函数

通过循环调用file:read/2读取标准输入(standard_io)的块数据,直到返回eof,最终拼接出完整的输入二进制:

read_all_stdin() ->
    read_all_stdin(<<>>).

read_all_stdin(Accumulator) ->
    case file:read(standard_io, 4096) of
        {ok, Data} ->
            read_all_stdin(<<Accumulator/binary, Data/binary>>);
        eof ->
            Accumulator;
        {error, Reason} ->
            error({stdin_read_error, Reason})
    end.
  • 选择4096字节作为每次读取的块大小是权衡性能和内存使用的常见做法,可根据实际场景调整。
  • 使用二进制累加是因为JSON数据通常以UTF-8编码存储,二进制处理既高效又能避免字符编码转换问题。

结合JSON解析的完整示例

以常用的jsx库为例,实现读取全部STDIN并解析JSON的逻辑:

-module(stdin_json_parser).
-export([main/0]).

main() ->
    try
        StdinData = read_all_stdin(),
        ParsedJson = jsx:decode(StdinData, [return_maps]),
        % 此处添加你的JSON处理逻辑
        io:format("Successfully parsed JSON: ~p~n", [ParsedJson])
    catch
        error:{stdin_read_error, Reason} ->
            io:format("Failed to read STDIN: ~p~n", [Reason]),
            halt(1);
        {error, {json_decode_error, Details}} ->
            io:format("Failed to parse JSON: ~p~n", [Details]),
            halt(1)
    end.

read_all_stdin() ->
    read_all_stdin(<<>>).

read_all_stdin(Accumulator) ->
    case file:read(standard_io, 4096) of
        {ok, Data} ->
            read_all_stdin(<<Accumulator/binary, Data/binary>>);
        eof ->
            Accumulator;
        {error, Reason} ->
            error({stdin_read_error, Reason})
    end.

编译与运行

  1. 确保项目依赖jsx(可通过rebar3管理,在rebar.config中添加{deps, [{jsx, "~> 3.0"}]})
  2. 编译代码:erlc stdin_json_parser.erl
  3. 通过管道传入数据运行:
echo '{"name": "Erlang", "version": "26.0"}' | erl -noshell -s stdin_json_parser main -s init stop

Escript便捷版本

如果需要更易用的可执行文件,可以写成escript格式:

#!/usr/bin/env escript
%% -*- erlang -*-
%%! -noshell -noinput

main(_Args) ->
    try
        StdinData = read_all_stdin(<<>>),
        case jsx:decode(StdinData, [return_maps]) of
            {error, Err} ->
                io:format("JSON parse error: ~p~n", [Err]),
                halt(1);
            Json ->
                io:format("Parsed result: ~p~n", [Json])
        end
    catch
        error:{read_error, Reason} ->
            io:format("STDIN read error: ~p~n", [Reason]),
            halt(1)
    end.

read_all_stdin(Acc) ->
    case file:read(standard_io, 4096) of
        {ok, Data} -> read_all_stdin(<<Acc/binary, Data/binary>>);
        eof -> Acc;
        {error, R} -> error({read_error, R})
    end.

赋予执行权限后即可直接运行:

chmod +x json_parser.escript
cat sample.json | ./json_parser.escript

内容的提问来源于stack exchange,提问作者Sam Weaver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:30:42