【问题标题】:How to properly read and write a file using Windows.Storage on Windows Phone 8如何在 Windows Phone 8 上使用 Windows.Storage 正确读取和写入文件
【发布时间】:2013-03-15 10:17:52
【问题描述】:

我只需要在 Windows Phone 8 中使用 Windows.Storage API 简单地写入文件和读取文件。使用旧的 IsolatedStorage 方法相对容易,但使用新的 WinRT API 则要困难得多。

我一直在尝试写它,但似乎有所有这些奇怪的东西,比如 IBuffer。等等。使用完整版的 WinRT,使用似乎存在的 Windows.Storage.FileIO 非常容易,以防止像我这样的开发人员发疯。但是,它没有在电话版本中实现。另外,我观看了一个 Channel9 视频,其中显示了一些代码示例,但他们犯了一个错误,因为他们使用了标记为 Security Critical 的方法来获取常规流。显然,不允许获得常规流。

那么,有人可以为我提供一个简洁且正确的 sn-p,说明如何将文件读入字符串以及如何将字符串写入文件,以及正确的使用和处理技术吗?

【问题讨论】:

  • 根据您要执行的操作,请查看Akavache。如果它解决了您的问题,您可以使用它,或者查看源代码以了解它们如何解决这些问题。
  • @vcsjones 好东西要记住,但我们不能包含任何依赖项 :( 此外,它在 WP8 上使用了 IsolatedStorage
  • PCL Storage 项目为可移植类库的 I/O 操作提供了一个通用接口。也许这能给你一些提示?
  • using (StreamReader sr = new StreamReader(File.OpenRead(strFileLoc)))... 样式代码对您不起作用有什么原因吗?我有一个app deployed on my dev registered WP8,标准文件写入似乎可以正常工作。

标签: c# file-io windows-runtime windows-phone-8


【解决方案1】:

我没有在 Windows Phone 8 上尝试过,但here's WinRT XAML Toolkit 为 Windows 8 提供的东西可以工作。



using System;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;

namespace WinRTXamlToolkit.IO.Extensions
{
    /// <summary>
    /// Extensions for simple writing and reading of strings to/from files.
    /// </summary>
    /// <remarks>
    /// Note that these were created before FileIO class existed in WinRT, but they still serve a purpose.
    /// </remarks>
    public static class StringIOExtensions
    {
        /// <summary>
        /// Reads a string from a text file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="folder">The folder.</param>
        /// <returns></returns>
        public static async Task<string> ReadFromFile(
            string fileName,
            StorageFolder folder = null)
        {
            folder = folder ?? ApplicationData.Current.LocalFolder;
            var file = await folder.GetFileAsync(fileName);

            using (var fs = await file.OpenAsync(FileAccessMode.Read))
            {
                using (var inStream = fs.GetInputStreamAt(0))
                {
                    using (var reader = new DataReader(inStream))
                    {
                        await reader.LoadAsync((uint)fs.Size);
                        string data = reader.ReadString((uint)fs.Size);
                        reader.DetachStream();

                        return data;
                    }
                }
            }
        }

        /// <summary>
        /// Writes a string to a text file.
        /// </summary>
        /// <param name="text">The text to write.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="folder">The folder.</param>
        /// <param name="options">
        /// The enum value that determines how responds if the fileName is the same
        /// as the name of an existing file in the current folder. Defaults to ReplaceExisting.
        /// </param>
        /// <returns></returns>
        public static async Task WriteToFile(
            this string text,
            string fileName,
            StorageFolder folder = null,
            CreationCollisionOption options = CreationCollisionOption.ReplaceExisting)
        {
            folder = folder ?? ApplicationData.Current.LocalFolder;
            var file = await folder.CreateFileAsync(
                fileName,
                options);
            using (var fs = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                using (var outStream = fs.GetOutputStreamAt(0))
                {
                    using (var dataWriter = new DataWriter(outStream))
                    {
                        if (text != null)
                            dataWriter.WriteString(text);

                        await dataWriter.StoreAsync();
                        dataWriter.DetachStream();
                    }

                    await outStream.FlushAsync();
                }
            }
        }
    }
}

【讨论】:

  • 这比“简单示例”效果更好。可能是因为这段代码使用 FlushAsync 之类的方法进行了清理。我正在使用 VS2013 更新 2,这方面的情况发生了很大变化!
【解决方案2】:

这是一个简单的例子:

public async Task WriteDataToFileAsync(string fileName, string content)
{
    byte[] data = Encoding.Unicode.GetBytes(content);

    var folder = ApplicationData.Current.LocalFolder;
    var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

    using (var s = await file.OpenStreamForWriteAsync())
    {
        await s.WriteAsync(data, 0, data.Length);
    }
}

public async Task<string> ReadFileContentsAsync(string fileName)
{
    var folder = ApplicationData.Current.LocalFolder;

    try
    {
        var file = await folder.OpenStreamForReadAsync(fileName);

        using (var streamReader = new StreamReader(file))
        {
            return streamReader.ReadToEnd();
        }
    }
    catch (Exception)
    {
        return string.Empty;
    }
}

像这样使用它们:

await this.WriteDataToFileAsync("afile.txt", "some text to save in a file");

var contents = await this.ReadFileContentsAsync("afile.txt");

【讨论】:

  • 几个问题: 1. 你应该在 write 方法上返回 Task,所以它是可等待的。 2. 看起来你是在写 UTF8 并读回 UTF16,还是 StreamReader 足够聪明,可以在不被告知的情况下告诉编码?
  • @PaulAnnetts 好地方。会教我从随机的互联网资源中复制和粘贴;)
  • 另外,使用OpenStreamForReadAsync 是安全关键
  • @Earlz 请问为什么OpenStreamForReadAsync 是安全关键的很重要?微软在示例代码 (msdn.microsoft.com/en-us/library/windowsphone/develop/…) 中使用了它,所以看来我们应该使用这些。
  • @StefanWexel 是的,结果没关系。我现在甚至不明白安全关键是什么意思,但是我没有收到任何从非安全关键代码调用安全关键函数的认证错误..所以我想这一切都很好
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多