如何在UWP中覆盖文件?

问题描述:

我试图用FileSavePicker覆盖UWP中的当前文件。我refered这样:https://msdn.microsoft.com/zh-cn/windows/uwp/files/quickstart-reading-and-writing-files 但当我使用更短的文件覆盖一个较长的文件,还有了一个问题:旧文件(长)的额外部分没有被删除,就像这样:如何在UWP中覆盖文件?

旧文件:

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(); 
     } 
    } 

感谢您帮助我!

+1

似乎是一种正常行为。如果你想用全新的数据覆盖文件,为什么不只是用* ReplaceExisting *选项创建文件而不是打开一个旧文件? – Romasz

+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); 
    } 
} 
+0

如果我不写文字会怎么样?我正在使用datawriter,如何解决这个问题? –

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

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