我想从网上下载一个 xml 文件,然后将它保存到本地存储,但我不知道该怎么做。请清楚地帮助我或给我一个例子。谢谢。
最佳答案
下载文件是一个庞大的主题,可以通过多种方式完成。我假设您知道要下载的文件的 Uri,并且希望您所说的 local 是 IsolatedStorage。
我将展示三个示例如何完成(还有其他方法)。
<强>1。最简单的示例 将通过 WebClient 下载字符串:
public static void DownloadFileVerySimle(Uri fileAdress, string fileName)
{
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, ev) =>
{
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
using (StreamWriter writeToFile = new StreamWriter(ISF.CreateFile(fileName)))
writeToFile.Write(ev.Result);
};
client.DownloadStringAsync(fileAdress);
}
如您所见,我直接将字符串(ev.Result
是一个 string
- 这是此方法的缺点)下载到 IsolatedStorage。
和用法 - 例如在按钮点击之后:
private void Download_Click(object sender, RoutedEventArgs e)
{
DownloadFileVerySimle(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt");
}
<强>2。在第二种方法中(简单但更复杂)我将再次使用 WebClient
并且我需要异步执行它(如果你是新手我建议阅读 MSDN , async-await on Stephen Cleary blog 和一些 tutorials )。
首先我需要Task
,它将从网络下载一个Stream
:
public static Task<Stream> DownloadStream(Uri url)
{
TaskCompletionSource<Stream> tcs = new TaskCompletionSource<Stream>();
WebClient wbc = new WebClient();
wbc.OpenReadCompleted += (s, e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wbc.OpenReadAsync(url);
return tcs.Task;
}
然后我将编写下载文件的方法 - 它也需要异步,因为我将使用 await DownloadStream:
public enum DownloadStatus { Ok, Error };
public static async Task<DownloadStatus> DownloadFileSimle(Uri fileAdress, string fileName)
{
try
{
using (Stream resopnse = await DownloadStream(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute)))
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (ISF.FileExists(fileName)) return DownloadStatus.Error;
using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))
resopnse.CopyTo(file, 1024);
return DownloadStatus.Ok;
}
}
catch { return DownloadStatus.Error; }
}
以及我的方法的用法,例如在单击按钮后:
private async void Downlaod_Click(object sender, RoutedEventArgs e)
{
DownloadStatus fileDownloaded = await DownloadFileSimle(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt");
switch (fileDownloaded)
{
case DownloadStatus.Ok:
MessageBox.Show("File downloaded!");
break;
case DownloadStatus.Error:
default:
MessageBox.Show("There was an error while downloading.");
break;
}
}
例如,如果您尝试下载非常大的文件(例如 150 Mb),此方法可能会出现问题。
<强>3。第三种方法 - 再次使用 WebRequest 和 async-await,但这种方法可以更改为通过缓冲区下载文件,因此不会占用太多内存:
首先,我需要通过一个异步返回 Stream
的方法来扩展我的 Webrequest
:
public static class Extensions
{
public static Task<Stream> GetRequestStreamAsync(this WebRequest webRequest)
{
TaskCompletionSource<Stream> taskComplete = new TaskCompletionSource<Stream>();
webRequest.BeginGetRequestStream(arg =>
{
try
{
Stream requestStream = webRequest.EndGetRequestStream(arg);
taskComplete.TrySetResult(requestStream);
}
catch (Exception ex) { taskComplete.SetException(ex); }
}, webRequest);
return taskComplete.Task;
}
}
然后我可以开始工作并编写我的下载方法:
public static async Task<DownloadStatus> DownloadFile(Uri fileAdress, string fileName)
{
try
{
WebRequest request = WebRequest.Create(fileAdress);
if (request != null)
{
using (Stream resopnse = await request.GetRequestStreamAsync())
{
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
{
if (ISF.FileExists(fileName)) return DownloadStatus.Error;
using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))
{
const int BUFFER_SIZE = 10 * 1024;
byte[] buf = new byte[BUFFER_SIZE];
int bytesread = 0;
while ((bytesread = await resopnse.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
file.Write(buf, 0, bytesread);
}
}
return DownloadStatus.Ok;
}
}
return DownloadStatus.Error;
}
catch { return DownloadStatus.Error; }
}
再次使用:
private async void Downlaod_Click(object sender, RoutedEventArgs e)
{
DownloadStatus fileDownloaded = await DownloadFile(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt");
switch (fileDownloaded)
{
case DownloadStatus.Ok:
MessageBox.Show("File downloaded!");
break;
case DownloadStatus.Error:
default:
MessageBox.Show("There was an error while downloading.");
break;
}
}
当然可以改进这些方法,但我认为这可以让您大致了解它的外观。这些方法的主要缺点可能是它们在前台工作,这意味着当您退出应用程序或点击开始按钮时,下载将停止。如果您需要在后台下载,您可以使用 Background File Transfers - 但那是另一回事。
如您所见,您可以通过多种方式实现目标。您可以在许多页面、教程和博客上阅读更多关于这些方法的信息,比较并选择最合适的方法。
希望这对您有所帮助。编码愉快,祝你好运。
关于windows-phone-8 - Windows 手机 8 : how to download xml file from web and save it to local?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21809545/