2017-09-30 5 views
1

FileSavePickerを使用してストレージファイルを選択(または作成)したときに、既存のファイルを選択すると、置換が求められます。私が「はい」を押すと、後でファイルを置き換えることが期待されますが、そうではありません。ので、上記のコードで、既存のファイルがFileSavePickerによって選ばれFileSavePickerがファイルを置き換えないのはなぜですか?

// existing file is picked, I pressed yes when replace was requested. 
file = await picker.PickSaveFileAsync(); 

は、私はfileは今置き換えられますが、そのされていないことを期待しました。

await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders) 

これは書き込み用のファイルを開くだけで、置き換えることはできませんが、置き換える必要があります。私の問題はthis questionと同じですが、私はテキストファイルを書いていません、私はバイナリデータを書いています。

fileを新しいものに置き換えるにはどうすればよいですか?

Iveはこれを試しましたが、GetParentAsyncがnullを返すため、NREをスローします。

var file = await (await file.GetParentAsync()).CreateFileAsync(file.Name, 
         CreationCollisionOption.ReplaceExisting); 

古いファイルを削除して新しいファイルを作成することで、ユーザーが明示的に新しいファイルを作成しないようにしたいとします。私が望むのは、ユーザーが既存のファイルを選択し、FileSavePickerからの置換要求を受け入れる場合、ファイルを置き換える必要があるということです。


ここでは、お使いのマシンでテストできるコードを示します。

var picker = new FileSavePicker 
{ 
    SuggestedStartLocation = PickerLocationId.Desktop, 
    DefaultFileExtension = ".bin", 
    SuggestedFileName = "Binary file" 
}; 
picker.FileTypeChoices.Add("Binary File", new List<string> {".bin"}); 

// in second run, choose existing file. 
var file = await picker.PickSaveFileAsync(); 

using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders)) 
{ 
    using (var output = stream.GetOutputStreamAt(0)) 
    { 
     using (var writer = new DataWriter(output)) 
     { 
      writer.WriteBytes(Enumerable.Repeat<byte>(10, 10000).ToArray()); 
      await writer.StoreAsync(); 
      writer.DetachStream(); 
     } 
     await output.FlushAsync(); 
    } 
} 

これを2回実行し、最初に実行してファイルを作成します。 2番目の実行で既存のファイルを選択し、Repeat<byte>(10, 10000)Repeat<byte>(80, 50)のように小さく小さく異なるものに変更し、ファイルの内容を確認します。

+0

FileSavePickerはありませんファイルを置き換えるのではなく、単に名前を付けるだけです。その名前のついたことは重要です。 WinRTのファイル操作はトランザクション的です。誤ってファイルを上書きすることはできません。ファイルが正しく閉じられたときのみ、既存のファイルが置き換えられます。したがって、最も重要なコードはスニペットから抜けています。 –

+0

私に与えるStorageFileでファイルを作成するにはどうしたらいいですか? (FileSavePickerは、「既存のものと置き換える」と聞いているときに横たわっています)@HansPassant –

+0

あなたが何を言っているのか分かりません。あなたの主張を検証するためにSOユーザーが実際に自分自身を実行することができる郵便番号。 –

答えて

1

あなたは常にSetLengthあなた開かれたストリームの最初の0にすることができます - あなただけのストリームに新しいコンテンツを書き込むことができます。その後0にすべての古いコンテンツと設定し、ストリームの位置をクリアします:

var picker = new FileSavePicker 
{ 
    SuggestedStartLocation = PickerLocationId.Desktop, 
    DefaultFileExtension = ".bin", 
    SuggestedFileName = "Binary file" 
}; 
picker.FileTypeChoices.Add("Binary File", new List<string> { ".bin" }); 
var file = await picker.PickSaveFileAsync(); 

using (var stream = await file.OpenStreamForWriteAsync()) 
{ 
    stream.SetLength(0); 
    var bytes = Encoding.ASCII.GetBytes("Content"); 
    await stream.WriteAsync(bytes, 0, bytes.Length); 
    await stream.FlushAsync(); 
} 
+0

素晴らしいですが、なぜこれは誰にも問題になっていないのでしょうか?私のアプリがバグなくではなく、データ・リーダーを使いこなしている古いコンテンツであることに気付くには、私には1日かかりました。 –

+0

Writerの最後にSetLength、SetLength(bytesWritten)を書くことができるので、ライターが問題に遭遇した場合に古いデータが失われることはありません。 –

+0

@ M.kazemAkhgaryはい、* SetLength *は必要に応じてストリームをトランケートまたは拡張します。 – Romasz

関連する問題