1

ファイルとそのファイル名を送信するのは興味深いです。サーバーのオプション:

-define(TCP_OPTIONS_SERVER, [binary, {packet, 0}, {active, false}]).

これがレシーバーループです。

file_receiver_loop(Socket,Bs)->
case gen_tcp:recv(Socket, 0) of
    {ok, B} ->
        file_receiver_loop(Socket, [Bs, B]);
    {error, closed} ->
        io:format("~nReceived!~n ~p",[Bs]),
        save_file(Bs)
end.

私は次のファイルを送信します:

file:sendfile(FilePath, Socket),

ファイルとファイル名を送信するとき

gen_tcp:send(Socket,Filename),
file:sendfile(FilePath, Socket),

バイナリデータは可変構造です。

皆さんありがとう!

4

2 に答える 2

0

このコードを作成して問題を解決します。
ファイル名として30バイトを送信します。
ファイル名が30未満の場合、白い文字のパディングを使用します。
接続が受け入れられたら、ファイル名を受け取る関数file_name_receiver(Socket)を呼び出します。

file_name_receiver(Socket)->
    {ok,FilenameBinaryPadding}=gen_tcp:recv(Socket,30),
    FilenamePadding=erlang:binary_to_list(FilenameBinaryPadding),
    Filename = string:strip(FilenamePadding,both,$ ),
    file_receiver_loop(Socket,Filename,[]).

この関数は、バイナリデータファイルを使用します。

file_receiver_loop(Socket,Filename,Bs)->
    io:format("~nRicezione file in corso~n"),
    case gen_tcp:recv(Socket, 0) of
    {ok, B} ->
        file_receiver_loop(Socket, Filename,[Bs, B]);
    {error, closed} ->
        save_file(Filename,Bs)
end.

最後に、この関数はファイルを保存します。

%%salva il file
save_file(Filename,Bs) ->
    io:format("~nFilename: ~p",[Filename]),
    {ok, Fd} = file:open("../script/"++Filename, write),
    file:write(Fd, Bs),
    file:close(Fd).

送信者は単純な関数を使用します。

%%Permette l'invio di un file specificando host,filename e path assoluto
send_file(Host,Filename,FilePath,Port)->
    {ok, Socket} = gen_tcp:connect(list_to_atom(Hostname), Port,          TCP_OPTIONS_CLIENT),
    FilenamePadding = string:left(Filename, 30, $ ), %%Padding with white space
    gen_tcp:send(Socket,FilenamePadding),
    Ret=file:sendfile(FilePath, Socket),
    ok = gen_tcp:close(Socket).
于 2012-12-11T14:49:58.887 に答える
0

メッセージパッシングでバイナリファイルを送信できる2つの関数を作成しました。

%Zip a file or a folder
send_zip(Pid, FolderName) ->
    %Name of you zip file
    FolderNameZip= FolderName++".zip",   
    %Zip the folder/file from the computer and name the zip file by FornderNameZip                    
    {ok, ZipFile} = zip:create(FolderNameZip, [FolderName]),
    %Put the Zipfile in a variable 
    {ok, ZipHandle} = file:read_file(ZipFile),
    %Send the zipfile to the other PID, sends the zipfile and his name to name it the same way.
    Pid ! {finish, ZipHandle, FolderNameZip}.


%save and unzip the in the computer 
register_zip_bash(Dir, ZipHandle, FolderNameZip) -> 
    file:write_file(FolderNameZip, ZipHandle),
    Cmd2 = io_lib:format("unzip -o -j ~p -d ~p/",[FolderNameZip, Dir]),
    _=os:cmd(Cmd2).

FoldeNameは、コンピューター内のファイルまたはフォルダーの名前にすることができます。Pidは、メッセージを送信したい人です。

ZipHandleとFolderNameZipを受け取ったら、register_zip_bash(...)関数を使用してデータをコンピューターに保存します。Dirは、データを保存する場所のディレクトリです。ZipHandleは、PID関数から受け取るバイナリファイルです。FolderNameZipは、ZipHandleがコンピューターに保存される場所の名前です。

ご覧のとおり、send_zip(...)はerlang関数を使用し、register_zip_bash(...)はbashコマンドを使用します。データを送信するためにファイルを圧縮する必要はありません。自分に合うようにコードを変更することを躊躇しないでください。

これがお役に立てば幸いです、乾杯。

于 2019-12-16T14:48:30.553 に答える