Delphi 使用 HTTP 上传文本文件

标签 delphi http file-upload indy

我正在尝试上传一个多行文本文件以供 BING 进行地理编码。

1,en-US,,16630 Redmond Way,WA,USA,,,Redmond,98052,,,,,,,,,,,,,,,,,,,,,,
2,en-US,,16552 NE 74th St,WA,,,,Redmond,,,High,,,,,,,,,,,,,,,,,,,,,,
3,en-US,Seattle Space Needle,,,,,,,,,,,,,,,,,,,,,,,,,,,,
4,en-US,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
5,en-US,,W Jefferson Blvd,CA,,,,Los Angeles,90007,,,,,,,,,,,,,,,,,,,,,,,,
6,en-US,,,CA,,,,Los angeles,,,,,,,,,,,,,,,,,,,,,,,,,
7,en-ca,Montreal Canada,,,,,,,,,,,,,,,,,,,,,,,,,,,,
8,en-CA,,444 Kirkpatrick Cres NW,AB,Canada,,,Edmonton,,,,,,,,,,,,,,,,,,,,,,,,
9,en-gb,BD4 9JB,,,,,,,,,,,,,,,,,,,,,,,,,,,,
10,en-us,,,,,,,,,,,,,,,,,,,,,,,,,,,,47.673099,-122.11871
11,en-ca,,,,,,,,,,,,,,,,,,,,,,,,,,,,53.48021728,-113.4030925
12,en-gb,,,,,,,,,,,,,,,,,,,,,,,,,,,,53.77848387,-1.719561517

我目前正在使用 TIdHTTP,但在传输文件时似乎文本文件中的换行符被删除,因为它们 (Bing) 只对文件的第一行进行地理编码其余部分将被忽略。

lHTTP := TIdHTTP.Create(nil);
...

//Build the http request string
HTTPRequest := 'http://spatial.virtualearth.net/REST/v1/Dataflows/Geocode?input=csv&output=xml&key=' + BingKey;

//Setup the HTTP request parameters
lHTTP.Request.ContentType := 'text/plain';
lHTTP.Request.Method := 'POST';

//Send the request to Bing. Result in XMLResult StringStream
lHTTP.Post(HTTPRequest, lParamList, XMLResult);

以下示例来自Microsoft但我还不够专业,无法将使用流的 HTTPWebRequest 部分适应 Delphi。

//Parameters:
//   dataFilePath: The path to the file that contains the spatial data to geocode.
//   dataFormat: The format of the input data. Possible values are xml, csv, tab and pipe.
//   key: The Bing Maps Key to use for this job. The same key is used to get job status and download results.
//   description: Text that is used to describe the geocode dataflow job.
//Return value : A URL that defines the location of the geocode dataflow job that was created.
static string CreateJob(string dataFilePath, string dataFormat, string key, string description)
{
    //Define parameters for the HTTP request
    //
    // The 'Content-Type' header of the HTTP Request must be "text/plain" or "application/xml"
    // depending on the input data format.
    //
    string contentType = "text/plain";
    if (dataFormat.Equals("xml", StringComparison.OrdinalIgnoreCase))
        contentType = "application/xml";

    StringBuilder queryStringBuilder = new StringBuilder();

    //
    // The 'input'(input format) and 'key' (Bing Maps Key) parameters are required.
    //
    queryStringBuilder.Append("input=").Append(Uri.EscapeUriString(dataFormat));
    queryStringBuilder.Append("&");
    queryStringBuilder.Append("key=").Append(Uri.EscapeUriString(key));

    if (!String.IsNullOrEmpty(description))
    {
        //
        // The 'description' parameter is optional.
        //
        queryStringBuilder.Append("&");
        queryStringBuilder.Append("description=").Append(Uri.EscapeUriString(description));
    }

    //Build the HTTP URI that will upload and create the geocode dataflow job
    UriBuilder uriBuilder = new UriBuilder("http://spatial.virtualearth.net");
    uriBuilder.Path = "/REST/v1/dataflows/geocode";
    uriBuilder.Query = queryStringBuilder.ToString();

    //Include the data to geocode in the HTTP request
    using (FileStream dataStream = File.OpenRead(dataFilePath))
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriBuilder.Uri);

        //
        // The HTTP method must be 'POST'.
        //
        request.Method = "POST";
        request.ContentType = contentType;

        using (Stream requestStream = request.GetRequestStream())
        {
            byte[] buffer = new byte[16384];
            int bytesRead = dataStream.Read(buffer, 0, buffer.Length);
            while (bytesRead > 0)
            {
                requestStream.Write(buffer, 0, bytesRead);

                bytesRead = dataStream.Read(buffer, 0, buffer.Length);
            }
        }

        //Submit the HTTP request and check if the job was created successfully.
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            //
            // If the job was created successfully, the status code should be
            // 201 (Created) and the 'Location' header should contain a URL
            // that defines the location of the new dataflow job. You use this
            // URL with the Bing Maps Key to query the status of your job.
            //
            if (response.StatusCode != HttpStatusCode.Created)
                throw new Exception ("An HTTP error status code was encountered when creating the geocode job.");

            string dataflowJobLocation = response.GetResponseHeader("Location");
            if (String.IsNullOrEmpty(dataflowJobLocation))
                throw new Exception ("The 'Location' header is missing from the HTTP response when creating a goecode job.");

            return dataflowJobLocation;
        }
    }
}

最佳答案

比较代码的2个要点。首先,您将代码作为 text/plain 而不是 application/xml 发送,其次它们会转义数据,您只需发送 XML。您是否尝试过将其作为转义数据?

关于Delphi 使用 HTTP 上传文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5538908/

相关文章:

ios - 我可以在 Delphi XE + FireMonkey 表单上使用 ShowMessage 的第一个事件是什么

delphi - Firemonkey 和 TDownloadUrl

internet-explorer - 如何让 Web 浏览器将所有事件(包括请求、响应、cookie 事件)记录到我可以检查的日志文件中?

http - 如何通过 HTTP 请求将视频上传到 YouTube?

ruby-on-rails - 使用 VAPID : 400/401 Unauthorized Registration 进行网络推送

jquery-ui - jquery文件上传 - 如何覆盖文件而不重命名

delphi - TWebBrowser 可以撤消或重做

image - 带有上传图像预览的 Magnific Popup

c# - 删除上传的文件,如果它没有移动到另一个文件夹

Delphi 编译错误 F2048 单元格式错误