0

How can I detect a new file being added to a specific directory?

What I am looking for is something like an event_listener for when a new file is created. I am not interested in using a loop that keeps searching the directory for new files because I need the name of the file when it is added to the directory.

Jean-François Corbett
  • 37,420
  • 30
  • 139
  • 188

3 Answers3

1

Unfortunately, there is no native Erlang API to perform what you are looking for.

Any non-polling solution has to rely on specific APIs from the operating system. On MacOS X and FreeBSD, you could use kqueue(2) API. On Linux, you could use inotify(7) API. Both APIs work with select(2) and you can use Erlang's driver_select function to select on the file descriptors provided by these APIs. Writing such a driver is not extremely difficult.

You can find on Github several drivers for inotify and one driver for kqueue.

Paul Guyot
  • 6,257
  • 1
  • 20
  • 31
0

In case you are working on Unix like OS you should consider using inotifywait tool. I just found nice Erlang wrapper around useful system tools: https://github.com/sdanzan/erlang-systools

Łukasz Ptaszyński
  • 1,639
  • 1
  • 12
  • 11
  • this seems to be using a loop too and i am looking for something like a trigger – Nuno Gouveia Oct 22 '14 at 12:37
  • It's efficient triggered based loop. By using this tool you are subscribing to a file system for specific changes and get notified. It's fine. Read about that: [link1](http://www.infoq.com/articles/inotify-linux-file-system-event-monitoring) [link2](http://blog.lagentz.com/general/automate-your-shell-scripts-using-inotify-and-inotifywait/) – Łukasz Ptaszyński Oct 22 '14 at 12:54
0

inoteefy gives you a nice listener based api on top of the Linux inotify api. Example for listening to updates to /tmp/:

1> inoteefy:watch("/tmp/", fun(X) -> io:format("File event: ~p~n", [X]) end).       
ok
File event: {"/tmp/",[create],0,"foo.txt"}
File event: {"/tmp/",[open],0,"foo.txt"}
File event: {"/tmp/",[attrib],0,"foo.txt"}
File event: {"/tmp/",[close_write],0,"foo.txt"}

here I'm doing touch /tmp/foo.txt after starting the watch

johlo
  • 5,422
  • 1
  • 18
  • 32