【问题标题】:How can I overwrite a file in UWP?如何覆盖 UWP 中的文件?
【发布时间】:2019-07-04 02:08:41
【问题描述】:

我尝试使用 FileSavePicker 覆盖 UWP 中的当前文件。我参考了这个:https://msdn.microsoft.com/zh-cn/windows/uwp/files/quickstart-reading-and-writing-files 但是当我使用较短的文件覆盖较长的文件时,出现了一个问题:旧文件(较长)的多余部分没有被删除,如下所示:

旧文件:

abcdefg

还有我要保存的文件:

hij

但保存操作后,我得到了这个:

hijdefg

我的代码在这里:

        private async void Save_Click(object sender, RoutedEventArgs e)
    {
        XmlDocument Line = SaveToXml();

        //Save it
        FileSavePicker fileSaving = new FileSavePicker();
        fileSaving.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        fileSaving.SuggestedFileName = "NewLine";
        fileSaving.FileTypeChoices.Add("Simple Line Files", new List<string>() { ".Line" });
        StorageFile file = await fileSaving.PickSaveFileAsync();

        if (file != null)
        {
            CachedFileManager.DeferUpdates(file);
            var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
            //var stream = await file.OpenStreamForWriteAsync();
            using (var outputStream = stream.GetOutputStreamAt(0))
            {
                using (var dataWriter = new Windows.Storage.Streams.DataWriter(outputStream))
                {
                    string xmlDoc = Line.OuterXml;
                    Debug.WriteLine(Line.OuterXml);
                    dataWriter.WriteString(xmlDoc);
                    await dataWriter.StoreAsync();
                    await outputStream.FlushAsync();
                }
            }
            stream.Dispose();
        }
    }

谢谢你帮助我!

【问题讨论】:

  • 似乎是正常行为。如果您想用全新的数据覆盖文件,为什么不直接使用 ReplaceExisting 选项创建文件而不是打开旧文件?
  • 方法错误,你想创建而不是打开。

标签: c# file win-universal-app


【解决方案1】:

您也可以在打开流后立即调用Stream.SetLength(0) 将其清除,然后再开始写入。

var streamToWrite = await file.OpenStreamForWriteAsync().ConfigureAwait(false);
streamToWrite.SetLength(0);
using (var streamWriter = new StreamWriter(streamToWrite))
{
    streamWriter.Write(data);
    streamWriter.Flush();                        
}

【讨论】:

    【解决方案2】:

    您的代码var outputStream = stream.GetOutputStreamAt(0) 在文件流的开始位置返回一个输出流。 现在,当您写入文件时,它将从您设置的位置替换文件。当您要写入的新字符串小于文件中的旧字符串时,它不能替换所有旧字符串。所以使用这种方法,不能保证旧文件中的每个字母都可以替换。

    您可以使用FileIO.WriteTextAsync(IStorageFile, String) 方法将文本写入指定文件。它可以覆盖旧文件。

    例如:

    private async void Save_Click(object sender, RoutedEventArgs e)
    {
        FileSavePicker savePicker = new FileSavePicker();
        savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        savePicker.FileTypeChoices.Add("Simple Line Files", new List<string>() { ".line" });
        savePicker.SuggestedFileName = "NewLine";
        StorageFile file = await savePicker.PickSaveFileAsync();
        if (file != null)
        {
            CachedFileManager.DeferUpdates(file);
            await FileIO.WriteTextAsync(file, "hello");
            FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
        }
    }
    

    【讨论】:

    • 如果我不写文字怎么办?我正在使用数据写入器,如何解决?
    【解决方案3】:

    在调用 OpenStreamForWriteAsync() 之前,使用 FileIO.WriteBytesAsync 并写入一个零字节数组。这将清除文件。

    public async Task<Stream> ClearAndGetStream(StorageFile storageFile)
    {
        await FileIO.WriteBytesAsync(storageFile, new byte[0]);
        return await storageFile.OpenStreamForWriteAsync();
    }
    

    【讨论】:

      【解决方案4】:

      虽然仍在使用 DataWriter,但有一个解决方案。我和你有同样的问题,并通过这样做解决了它。

      替换:

      await dataWriter.StoreAsync();
      

      与:

      stream.size = await dataWriter.StoreAsync();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-26
        • 1970-01-01
        • 2017-07-31
        • 2020-03-23
        • 2021-05-29
        • 2016-03-15
        相关资源
        最近更新 更多