如果两台服务器都使用 erlang 分发协议连接,则可以使用 Erlang File I/O。 (您也可以通过 TCP 或 UDP 或任何其他网络进行此操作,但更复杂)。
让我们使用在同一台机器上运行的两个“服务器”来演示它(它在网络上的工作方式相同,但您必须正确连接它们)。首先我们为每个服务器创建目录和文件foo的内容进行传输:
$ mkdir a b
$ echo Hello World > a/foo
让我们在不同的目录中启动两个服务器:
$ cd a
a$ erl -sname a
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
(a@hynek-notebook)1>
和另一个控制台中的第二个服务器:
$ cd b
b$ erl -sname b
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
(b@hynek-notebook)1>
现在我们检查b 服务器上还没有任何内容:
(b@hynek-notebook)1> ls().
ok
(b@hynek-notebook)2>
现在我们可以连接节点,检查它们是否连接并读取文件foo。
(a@hynek-notebook)1> net_kernel:connect('b@hynek-notebook').
true
(a@hynek-notebook)2> net_adm:ping('b@hynek-notebook').
pong
(a@hynek-notebook)3> ls().
foo
ok
(a@hynek-notebook)4> {ok, Bin} = file:read_file("foo").
{ok,<<"Hello World\n">>}
(a@hynek-notebook)5>
并使用rpc:call/4 将文件写入服务器b:
(a@hynek-notebook)5> rpc:call('b@hynek-notebook', file, write_file, ["bar", Bin]).
ok
(a@hynek-notebook)6>
在服务器b上查看结果:
(b@hynek-notebook)2> ls().
bar
ok
(b@hynek-notebook)3> {ok, Bin} = file:read_file("bar").
{ok,<<"Hello World\n">>}
(b@hynek-notebook)4>
对于较大的文件,您不应在一个大二进制文件中传输整个文件。不幸的是,您至少需要来自发送方或接收方的一些代码支持。您可以将文件处理程序从一个节点传输到另一个节点,但调用 file:open/2 的进程必须继续运行。这就是你不能只使用{ok, FH} = rpc:call(Node, file, open, [FN, [write]]). 的原因,这太糟糕了。一种方法是制作一个非常简单的服务器,它可以打开一个文件并继续运行。
(b@hynek-notebook)4> Self = self().
<0.40.0>
(b@hynek-notebook)5> F = fun() -> Self ! file:open("baz", [write]), receive close -> ok end end.
#Fun<erl_eval.20.54118792>
(b@hynek-notebook)6> FS = spawn_link('a@hynek-notebook', F).
<7329.48.0>
(b@hynek-notebook)7> {ok, FH} = receive X -> X end.
{ok,<7329.49.0>}
(b@hynek-notebook)8> file:write(FH, Bin).
ok
(b@hynek-notebook)9> FS ! close.
close
(b@hynek-notebook)10>
我们希望文件baz 在服务器a 上有适当的内容:
(a@hynek-notebook)6> ls().
baz foo
ok
(a@hynek-notebook)7> {ok, _} = file:read_file("baz").
{ok,<<"Hello World\n">>}
(a@hynek-notebook)8>
另一种选择是编写一个服务器,它将接收块并写入它们而不是发送文件处理程序。还有许多其他选项,如何使用 HTTP 或您自己的协议以及使用file:send_file/2,5 和许多其他方式使用直接 TCP 连接。