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.