Info

Programmer by day, artist by night

The problem: From page 37, Exercise 4, Chapter 2, Programming Erlang by Joe Armstrong

Run the file client and server code. Add a command called put_file. What messages do you need to add? Find out how to consult manual pages. Consult the manual pages for the file module.

Additional Specifications

  • We should be able to run “erl” from a directory of our choice other than where the .erl source files are located
  • We should be able to specify a directory of our choice in afile_server:start Dir argument
  • We should be able to put a file from a directory other than the current directory to the directory specified in Dir argument above

Solution

{Client, {put_file, File}} ->
  Source = filename:absname(File),
  Destination = filename:join(Dir, filename:basename(File)),
  Client ! {self(), file:copy(Source, Destination)}</pre>
  • We will use the file:copy function. copy/2 has a source and a destination
  • source = the absolute filename
  • destination = dir name + base filename

Testing the solution

1> c("../erlang/afile_server").
{ok,afile_server}
2> c("../erlang/afile_client").
{ok,afile_client}
3> FS = afile_server:start("../erlang").
<0.46.0>
4> afile_client:ls(FS).
{ok,[".idea","afile_client.beam","afile_client.erl",
     "afile_server.beam","afile_server.erl","erlang.iml","foo",
     "geometry.beam","geometry.erl","hello.beam","hello.erl",
     "shop.beam","shop.erl","shop1.beam","shop1.erl"]}
5> afile_client:put_file(FS, "../foo").
{ok,5}
6> afile_client:put_file(FS, "Test.java").
{ok,382}
7> afile_client:ls(FS).
{ok,[".idea","afile_client.beam","afile_client.erl",
     "afile_server.beam","afile_server.erl","erlang.iml","foo",
     "geometry.beam","geometry.erl","hello.beam","hello.erl",
     "shop.beam","shop.erl","shop1.beam","shop1.erl",
     "Test.java"]}

The files foo and Test.java are now showing up in the response from aflile_client:ls(FS) in line 7 above.

Full source code

afile_server.erl

-module(afile_server).
-export([start/1, loop/1]).

start(Dir) -> spawn(afile_server, loop, [Dir]).

loop(Dir) ->
  receive
    {Client, list_dir} ->
      Client ! {self(), file:list_dir(Dir)};
    {Client, {get_file, File}} ->
      Full = filename:join(Dir, File),
      Client ! {self(), file:read_file(Full)};
    {Client, {put_file, File}} ->
      Source = filename:absname(File),
      Destination = filename:join(Dir, filename:basename(File)),
      Client ! {self(), file:copy(Source, Destination)}
  end,
  loop(Dir).

afile_client.erl

-module(afile_client).
-export([ls/1, get_file/2, put_file/2]).

ls(Server) ->
  Server ! {self(), list_dir},
  receive
    {Server, FileList} ->
      FileList
  end.

get_file(Server, File) ->
  Server ! {self(), {get_file, File}},
  receive
    {Server, Content} ->
      Content
  end.

put_file(Server, File) ->
  Server ! {self(), {put_file, File}},
  receive
    {Server, Status} ->
      Status
  end.

Comments

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS