Erlang 文件截断

发布于 2024-08-14 16:49:01 字数 1856 浏览 1 评论 0原文

我正在尝试编写一个基本的 Erlang 程序,该程序在一个进程中读取文件并在另一个进程中写入该文件。我发现有时输出文件会被截断。

例如我写了 eunit 测试。如果我运行单个测试 drive_test:write_file_test() 输出将被正确写入。但是运行 drive_test:test() 每次都会在不同的位置截断输出文件。

我是否需要做一些特殊的事情来确保进程在关闭之前完成写入?

drive.erl:

-module(drive).
-include("library.hrl").
-export([init/1]).

init(Drive) ->
  loop(Drive).

loop(Drive) ->
  receive
    {write, Data} ->
      write(Drive,Data),
      loop(Drive);
    close -> 
      close(Drive)
  end.

write(Drive,Data) ->
  %io:format("~p", [Data]),
  Handler = Drive#drive.volume,
  file:write(Handler, [Data]).

close(Drive) ->
  Handler = Drive#drive.volume,
  file:close(Handler),
  io:format("closed ~w~n", [Drive]).

drive_test.erl

-module(drive_test).
-include_lib("eunit/include/eunit.hrl").
-include("library.hrl").

startupShutdown_test() ->
  DrivePid = spawn(drive,init,[#drive{number=1}]),
  DrivePid ! close.

write_basic_test() ->
  {ok, F} =file:open("test/library/eunit.txt", write),
  DrivePid = spawn(drive,init,[#drive{number=1,volume=F}]),
  DrivePid ! {write, "Some Data"},
  DrivePid ! close.

write_file_test() ->
  {ok, Fin} = file:open("cathedral.pdf", read),
  {ok, Fout} =file:open("test/library/eunit2.txt", write),
  DrivePid = spawn(drive,init,[#drive{number=1,volume=Fout}]),
  write_file( Fin, DrivePid),
  DrivePid ! close.

write_file(F, DrivePid ) ->
  Rd = file:read(F, 256),
  case Rd of
    {ok, Data} -> 
      DrivePid ! {write, Data}, 
      write_file(F, DrivePid );
    eof -> file:close(F);
    _ -> ?_assert(false)
  end.

截断的文件:

$ ls -l cathedral.pdf test/library/eunit2.txt
-rwx------+ 1 218879 Sep 16 22:21 cathedral.pdf
-rwxr-xr-x  1  60928 Dec 17 09:31 test/library/eunit2.txt

I'm trying to write a basic Erlang program that reads in a file in one process and writes the file in another process. I'm finding that sometimes the output file gets truncated.

For instance I wrote eunit test. If I run the single test drive_test:write_file_test() the output is correctly written. But running drive_test:test() truncates the output file in a different place each time.

Do I need to do something special to make sure that the process finishes writing before it closes?

drive.erl:

-module(drive).
-include("library.hrl").
-export([init/1]).

init(Drive) ->
  loop(Drive).

loop(Drive) ->
  receive
    {write, Data} ->
      write(Drive,Data),
      loop(Drive);
    close -> 
      close(Drive)
  end.

write(Drive,Data) ->
  %io:format("~p", [Data]),
  Handler = Drive#drive.volume,
  file:write(Handler, [Data]).

close(Drive) ->
  Handler = Drive#drive.volume,
  file:close(Handler),
  io:format("closed ~w~n", [Drive]).

drive_test.erl

-module(drive_test).
-include_lib("eunit/include/eunit.hrl").
-include("library.hrl").

startupShutdown_test() ->
  DrivePid = spawn(drive,init,[#drive{number=1}]),
  DrivePid ! close.

write_basic_test() ->
  {ok, F} =file:open("test/library/eunit.txt", write),
  DrivePid = spawn(drive,init,[#drive{number=1,volume=F}]),
  DrivePid ! {write, "Some Data"},
  DrivePid ! close.

write_file_test() ->
  {ok, Fin} = file:open("cathedral.pdf", read),
  {ok, Fout} =file:open("test/library/eunit2.txt", write),
  DrivePid = spawn(drive,init,[#drive{number=1,volume=Fout}]),
  write_file( Fin, DrivePid),
  DrivePid ! close.

write_file(F, DrivePid ) ->
  Rd = file:read(F, 256),
  case Rd of
    {ok, Data} -> 
      DrivePid ! {write, Data}, 
      write_file(F, DrivePid );
    eof -> file:close(F);
    _ -> ?_assert(false)
  end.

truncated file:

$ ls -l cathedral.pdf test/library/eunit2.txt
-rwx------+ 1 218879 Sep 16 22:21 cathedral.pdf
-rwxr-xr-x  1  60928 Dec 17 09:31 test/library/eunit2.txt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

贱人配狗天长地久 2024-08-21 16:49:01

这很可能是与“计时”相关的问题。我怀疑这与“Eunit”执行处理的方式有关:“EUnit”可能没有给您的模块足够的时间来关闭,然后退出并终止所有进程。

It is most probably a "timing" related problem. I suspect it is related to how "Eunit" performs its processing: "EUnit" probably doesn't give enough time to your module to close before exiting and thus terminating all processes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文