0

摘要: 我正在使用 WebRequest 从我自己的互联网 DNS 中通过 FTP 下载 XML 文件。这是我第一次编写从 FTP 服务器下载文件的应用程序。我在下载中遇到了许多不一致的损坏,导致 XML 文件无法使用。下载文件的实际代码取自 Microsoft Windows 8 示例,名为:“Windows Store 应用程序中的 FTP 文件下载器”。我发现即使使用此 Windows 8 示例也会导致相同的损坏,因此它不一定是我的代码中的其他内容。

简介 My Windows Store App 使用 XML 文件存储数据。此数据最初来自 Excel。我需要每月更新这些数据,并使其无缝地提供给应用程序的用户。为此,我创建了一个网站,其中存储了最新版本的 XML 数据文件。这些文件是使用 Filezilla 以二进制传输模式上传的(顺便说一下,我发现 WebRequest 会从文件中删除所有的 CR/LF,如果它们是以 ASCII 格式上传的,使它们变得无用)。

我的应用程序将 Microsoft 示例中提供的代码用于 Windows 应用商店应用程序的 FTP 文件传输。它看起来像这样:

using System;
using System.IO;
using System.Net;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;

namespace CSWindowsStoreAppFTPDownloader.FTP
{
    public static class FTPClient
    {
        /// <summary>
        /// Download a single file from FTP server using WebRequest.
        /// </summary>
        public static async Task<DownloadCompletedEventArgs>
            DownloadFTPFileAsync(FTPFileSystem item,
            StorageFile targetFile, ICredentials credential)
        {
            var result = new DownloadCompletedEventArgs
            {
                RequestFile = item.Url,
                LocalFile = targetFile,
                Error=null 
            };

            // This request is FtpWebRequest in fact.
            WebRequest request = WebRequest.Create(item.Url);

            if (credential != null)
            {
                request.Credentials = credential;
            }

            request.Proxy = WebRequest.DefaultWebProxy;

            // Set the method to Download File
            request.Method = "RETR";
            try
            {
                // Open the file for write.
                using (IRandomAccessStream fileStream =
                      await targetFile.OpenAsync(FileAccessMode.ReadWrite))
                {

                    // Get response.
                    using (WebResponse response = await request.GetResponseAsync())
                    {

                        // Get response stream.
                        using (Stream responseStream = response.GetResponseStream())
                        {
                            byte[] downloadBuffer = new byte[2048];
                            int bytesSize = 0;

                            // Download the file until the download is completed.
                            while (true)
                            {

                                // Read a buffer of data from the stream.
                                bytesSize = responseStream.Read(downloadBuffer, 0,
                                    downloadBuffer.Length);
                                if (bytesSize == 0)
                                {
                                    break;
                                }

                                // Write buffer to the file.
                                await fileStream.WriteAsync(downloadBuffer.AsBuffer());
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Error=ex;
            }

            return result; 
        }
    }
}

问题 XML 文件的格式应如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Table>
    <Row>
        <Month>JAN</Month>
        <Year>1996</Year>
        <RPI>74.6</RPI>
    </Row>
    <Row>
        <Month>FEB</Month>
        <Year>1996</Year>
        <RPI>75.1</RPI>
    </Row>
    ...
</Table>

但是,当我使用 MS 示例代码下载一个小的、格式正确的 XML 文件时,结束标记总是被损坏,如下所示:

    <Row>
        <Month>APR</Month>
        <Year>2013</Year>
        <RPI>114.92</RPI>
    </Row>
</Table>/RPI>
    </Row>
    <Row>
        <Month>APR</Month>
        <Year>2011</Year>
        <RPI>111.33</RPI>
    </Row>
    <Row>
        <Month>MAY</

这段代码来自微软自己的网站,这让我有点担心。会不会是 FTP 服务器上的文件有问题?我使用 Filezilla 使用二进制传输模式下载这些文件没有问题。回顾以前的帖子,我可以看到二进制与 ASCII 是一个问题,但 WebRequest 没有 UseBinary 属性(与 Windows 8 中不可用的 FTPWebRequest 不同)。

我已经尝试了以下解决方法:

  • 改变用于读取 WebResponse 并写入输出流的缓冲区大小 - 这具有移动损坏位置但不能消除它的效果
  • 在每个读/写对之后将缓冲区重新初始化为新的 byte[] 数组 - 无效
  • 将 byte[] 缓冲区的值设置为 0 - 这消除了结束标记的损坏,但 XML 中的其他间隙随机出现

我认为我不应该陷入这种显然不是最佳的解决方法的水平。有谁知道这里可能存在什么问题?谢谢你。

4

0 回答 0