我一直在使用Synapse库从互联网上下载文件,但我最近将我的应用程序转换为使用INDY而我错过了Synapse库中的一个更好的功能,即能够轻松获取Mime - 在将服务器保存到本地计算机之前从服务器下载的文件的类型。 INDY是否具有此功能,如果有,我该如何访问它?
答案 0 :(得分:8)
您可以发出HTTP HEAD
请求并检查Content-Type
标头。在您真正GET
文件(下载)之前:
procedure TForm1.Button1Click(Sender: TObject);
var
Url: string;
Http: TIdHTTP;
begin
Url := 'http://yoursite.com/yourfile.png';
Http := TIdHTTP.Create(nil);
try
Http.Head(Url);
ShowMessage(Http.Response.ContentType); // "image/png"
finally
Http.Free;
end;
end;
您收到的ContentType
取决于Web服务器的实现,并且不保证在每台服务器上都是相同的。
另一个选项是实际GET
文件,并将其内容保存到内存流,例如TMemoryStream
(不是本地文件)。 Indy提供了一个过载:
Http.Get(Url, AStream);
然后检查Http.Response.ContentType
,并将流保存到文件:AStream.SaveToFile
。
不确定这里的相关性,但请注意Indy也可以返回/猜测本地文件的mime类型(给定文件扩展名)。使用GetMIMETypeFromFile
(使用IdGlobalProtocols
)。另请参阅here。
答案 1 :(得分:1)
或者你可以建立你的功能
function GetMIMEType(sFile: TFileName): string;
var aMIMEMap: TIdMIMETable;
begin
aMIMEMap:= TIdMIMETable.Create(true);
try
result:= aMIMEMap.GetFileMIMEType(sFile);
finally
aMIMEMap.Free;
end;
end;
然后致电
procedure HTTPServerGet(aThr: TIdPeerThread; reqInf: TIdHTTPRequestInfo;
respInf: TIdHTTPResponseInfo);
var localDoc: string;
ByteSent: Cardinal;
begin
//RespInfo.ContentType:= 'text/HTML';
Writeln(Format('Command %s %s at %-10s received from %s:%d',[ReqInf.Command, ReqInf.Document,
DateTimeToStr(Now),aThr.Connection.socket.binding.PeerIP,
aThr.Connection.socket.binding.PeerPort]));
localDoc:= ExpandFilename(Exepath+'/web'+ReqInf.Document);
RespInf.ContentType:= GetMIMEType(LocalDoc);
if FileExists(localDoc) then begin
ByteSent:= HTTPServer.ServeFile(AThr, RespInf, LocalDoc);
Writeln(Format('Serving file %s (%d bytes/ %d bytes sent) to %s:%d at %s',
[LocalDoc,ByteSent,FileSizeByName(LocalDoc), aThr.Connection.Socket.Binding.PeerIP,
aThr.Connection.Socket.Binding.PeerPort, dateTimeToStr(now)]));
end else begin
RespInf.ResponseNo:= 404; //Not found RFC
RespInf.ContentText:=
'<html><head><title>Sorry WebBox Error</title></head><body><h1>' +
RespInf.ResponseText + '</h1></body></html>';
end;
end;