Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么FileSavePicker不替换文件?_C#_Uwp_Filesavepicker - Fatal编程技术网

C# 为什么FileSavePicker不替换文件?

C# 为什么FileSavePicker不替换文件?,c#,uwp,filesavepicker,C#,Uwp,Filesavepicker,当我使用FileSavePicker选择(或创建)存储文件时,如果我选择现有文件,它将提示替换。当我按yes时,我希望该文件稍后会被替换,但事实并非如此 // existing file is picked, I pressed yes when replace was requested. file = await picker.PickSaveFileAsync(); 使用上面的代码,现有文件由FileSavePicker拾取,我希望文件现在被替换,但它不是 await file.Open

当我使用FileSavePicker选择(或创建)存储文件时,如果我选择现有文件,它将提示替换。当我按yes时,我希望该文件稍后会被替换,但事实并非如此

// existing file is picked, I pressed yes when replace was requested.
file = await picker.PickSaveFileAsync();
使用上面的代码,现有文件由FileSavePicker拾取,我希望
文件
现在被替换,但它不是

await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.AllowOnlyReaders)
这将只打开文件进行写入,它不会替换它,但我希望它被替换。我的问题与相同,但我不是在写文本文件,而是在写二进制数据

如何用新文件替换
文件

我尝试了以下操作,但它抛出了NRE,因为GetParentAsync返回null

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();
    }
}
var picker=newfilesavepicker
{
SuggestedStartLocation=PickerLocationId.Desktop,
DefaultFileExtension=“.bin”,
SuggestedFileName=“二进制文件”
};
添加(“二进制文件”,新列表{.bin});
//在第二次运行中,选择现有文件。
var file=await picker.PickSaveFileAsync();
使用(var stream=await file.OpenAsync(FileAccessMode.ReadWrite,StorageOpenOptions.AllowOnlyReaders))
{
使用(var output=stream.GetOutputStreamAt(0))
{
使用(var编写器=新数据编写器(输出))
{
WriteBytes(可枚举.Repeat(101000.ToArray());
等待writer.StoreAsync();
writer.DetachStream();
}
等待输出。FlushAsync();
}
}
运行两次,在第一次运行中,创建文件。在第二次运行中,选择现有文件,并将
Repeat(10,10000)
更改为更小和不同的内容,如
Repeat(80,50)
,然后检查文件的内容。

您始终可以先将打开的流的位置设置为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();
}
var picker=newfilesavepicker
{
SuggestedStartLocation=PickerLocationId.Desktop,
DefaultFileExtension=“.bin”,
SuggestedFileName=“二进制文件”
};
添加(“二进制文件”,新列表{.bin});
var file=await picker.PickSaveFileAsync();
使用(var stream=await file.OpenStreamForWriteAsync())
{
stream.SetLength(0);
var bytes=Encoding.ASCII.GetBytes(“内容”);
wait stream.WriteAsync(字节,0,字节.长度);
等待stream.FlushAsync();
}

FileSavePicker不会替换文件,它只提供一个名称。你下一步用这个名字做什么很重要。WinRT中的文件操作是事务性的,不能意外覆盖文件。只有当文件正确关闭时,它才会替换现有文件。因此,代码片段中缺少了最重要的代码。好的,如何使用它提供给我的StorageFile创建一个文件?(那么FileSavePicker问“替换为现有文件”是在撒谎。)@HansPassantI不知道你在说什么。发布代码,以便用户能够实际运行自己来验证您的声明。@HansPassant我已经为您提供了示例,如果可以,请测试此代码,并告诉我您观察到了什么。谢谢。WinRT没有足够的理由截断现有文件。考虑StutalFutRe.CurATelFielyCyc,这样您就可以指定CreationCollisionOption.ReplaceExistingAwesome了,我想知道为什么还没有对任何人提出这个问题?我花了一天的时间才意识到,我的应用程序工作正常,但它的旧内容正在干扰数据读取器。我还可以在写入结束时设置长度,
SetLength(bytesswrite)
,这样,如果写入者遇到问题,旧数据就不会丢失。@M.kazemAkhgary是的,SetLength将在需要时截断或扩展流。