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.