2017-10-08 54 views
0

我在一个节点上创建一个文件流,我担心文件访问,如果我从另一个节点启动流,该怎么办?从另一个节点开始流?

一样,在节点A,我没有启动它创建流:

stream= File.stream!(path) 
Agent.start(fn -> %{"stream" => stream} end, name: {:global, :my_stream}) 

然后,在节点B,我开始流:

stream= Agent.get({:global, :my_stream}, fn %{"stream" => stream } -> stream end) 
Task.start_link(Stream, :run, [stream]) 

请问流中查找文件在预期的节点A上?或者它会在节点B上查找它(考虑节点B是流的启动位置),因为如果这样做会失败,因为文件实际上存在于节点A上。

我应该关联哪个节点该文件存储?我会怎么做?我一定要吗?

有什么想法?

+0

这是什么路径?如果是文件,则必须从两个节点同样可见。这在远程节点上不一定是正确的。 – GavinBrelstaff

+0

'path'是文件(包括路径),我有每个节点都在一个单独的服务器上,所以,你认为我的方法不安全吗?或者至少,不保证工作? – simo

+0

根据我在网络连接节点上使用'File.stream'的经验,您需要每个erlang-VM上的文件的本地副本,其路径名适用于每个文件系统/操作系统 - 否则它不会工作。 “文件”不是一个URL。 – GavinBrelstaff

回答

0

File.stream!返回File.Stream结构含有4个字段:pathmodesraw,和line_or_bytes。该文件实际上只在流执行时才使用,例如, Stream.run/1或任何Enum功能。当您使用Agent将该结构传递给另一个节点时,只传递此4字段结构,并且如果您在该另一个节点上调用Stream.run,则该节点将尝试打开path所指向的文件,如果文件不' t存在于该节点的文件系统上。所以,你的问题的答案是,除非文件存在于相同的路径,否则操作将失败。

另一方面,Elixir中的文件句柄是内部存储对打开的文件的引用的PID。它们可以被创建,例如使用File.open!/1。如果您将通过此调用返回的PID传递给另一个节点,然后对其执行操作,例如该节点上的IO.read(不是File.read),它将成功,因为操作作为消息发送到PID。如果文件句柄的PID来自另一个节点,则文件操作将透明地通过连接传输)。所以,如果你想访问这样的文件,你可以使用File.open!,然后从另一个节点使用IO.read

相关问题