> Erlang中文手册 > sendfile/5 通过套接字端口 Socket 发送文件数据

file:sendfile/5

通过套接字端口 Socket 发送文件数据

用法:

sendfile(RawFile, Socket, Offset, Bytes, Opts) -> -> {ok, BytesSent} | {error, Reason}

内部实现:

-define(MAX_CHUNK_SIZE, (1 bsl 20)*20). %% 20 MB, has to fit in primary memory

-spec sendfile(RawFile, Socket, Offset, Bytes, Opts) ->
   {'ok', non_neg_integer()} | {'error', inet:posix() | 
				closed | badarg | not_owner} when
      RawFile :: fd(),
      Socket :: inet:socket(),
      Offset :: non_neg_integer(),
      Bytes :: non_neg_integer(),
      Opts :: [sendfile_option()].
sendfile(File, _Sock, _Offet, _Bytes, _Opts) when is_pid(File) ->
    {error, badarg};
sendfile(File, Sock, Offset, Bytes, []) ->
    sendfile(File, Sock, Offset, Bytes, ?MAX_CHUNK_SIZE, [], [],
	     false, false, false);
sendfile(File, Sock, Offset, Bytes, Opts) ->
    ChunkSize0 = proplists:get_value(chunk_size, Opts, ?MAX_CHUNK_SIZE),
    ChunkSize = if ChunkSize0 > ?MAX_CHUNK_SIZE ->
			?MAX_CHUNK_SIZE;
		   true -> ChunkSize0
		end,
    %% Support for headers, trailers and options has been removed because the
    %% Darwin and BSD API for using it does not play nice with
    %% non-blocking sockets. See unix_efile.c for more info.
    sendfile(File, Sock, Offset, Bytes, ChunkSize, [], [],
	     false,false,false).

从文件 RawFile 的第 Offset 字节开始,通过 Socket 发送 Bytes 字节的文件数据,如果 Bytes 设置为0,则 Offset 后的所有数据都被发送。如果发送成功,则返回 {ok, BytesSent},否则,返回 {error, Reason}。

case file:open(Filename, [read, raw, binary]) of
    {error, Reason} ->
        {error, Reason};
    {ok, Fd} ->
        Res = sendfile(Fd, Sock, 0, 0, []),
        file:close(Fd),
        Res
end.