【问题标题】:UWP Check If File ExistsUWP 检查文件是否存在
【发布时间】:2016-09-04 07:21:14
【问题描述】:

我目前正在开发 Windows 10 UWP 应用。 App需要检查是否存在名为“01-introduction”的某个PDF文件,如果存在则打开它。 如果文件不存在,我已经有了代码。 下面的代码是我目前拥有的:

        try
        {
            var test = await DownloadsFolder.CreateFileAsync("01-Introduction.pdf", CreationCollisionOption.FailIfExists); 
        }
        catch
        {

        }

此代码无法正常工作,因为要检查文件是否存在于此,我尝试创建文件。但是,如果该文件不存在,则会创建一个空文件。如果文件不存在,我不想创建任何东西,如果存在,只需打开 PDF。

如果可能,我想查看下载文件夹中名为“我的手册”的文件夹。

任何帮助将不胜感激。

【问题讨论】:

  • “Swift Manuals”文件夹是由您的应用创建的吗?默认情况下,您的应用只能访问您的应用创建的用户下载文件夹中的文件和文件夹。但是,您可以通过调用文件选择器(FileOpenPickerFolderPicker)来访问用户下载文件夹中的文件和文件夹,以便用户可以导航和选择文件或文件夹供您的应用访问。
  • @JayZuo-MSFT 谢谢杰伊的澄清。这是我们一直遇到的问题。这样我们就可以获得对 Downloads 的目录访问权限。我们需要研究另一种方法并进行更多阅读。
  • 如果您在“下载”文件夹中创建文件或文件夹,我们建议您将该项目添加到您应用的FutureAccessList,以便您的应用将来可以轻松访问该项目。欲了解更多信息,请参阅File access permissions

标签: c# pdf win-universal-app windows-10-universal windows-10-mobile


【解决方案1】:

基于another answer here,我喜欢

public static async Task<bool> DoesFileExist(string filePath) {
  var directoryPath = System.IO.Path.GetDirectoryName(filePath);
  var fileName = System.IO.Path.GetFileName(filePath);
  var folder = await StorageFolder.GetFolderFromPathAsync(directoryPath);
  var file = await folder.TryGetItemAsync(fileName);
  return file != null;
}

【讨论】:

    【解决方案2】:
    public async Task<bool> IsFilePresent(string fileName)
    {
        var item = await ApplicationData.Current.LocalFolder.TryGetItemAsync(fileName);
        return item != null;
    }
    

    但不支持Win8/WP8.1

    https://blogs.msdn.microsoft.com/shashankyerramilli/2014/02/17/check-if-a-file-exists-in-windows-phone-8-and-winrt-without-exception/

    【讨论】:

    • 那不是下载文件夹。
    • 找不到项目时会抛出异常。
    • @Reynevan 它不会抛出异常。
    • 确实,它不会抛出任何异常,尽管文档说他们会这样做
    • 这不是下载文件夹,而是在部署和更新之间被覆盖的本地应用程序文件夹,请注意。
    【解决方案3】:

    CreateFileSync 公开了一个重载,让您可以选择在目录中找到同名的现有文件时要执行的操作,如下所示:

    StorageFile localDbFile = await DownloadsFolder.CreateFileAsync(LocalDbName, CreationCollisionOption.OpenIfExists);
    

    CreationCollisionOption 是您需要设置的对象。在我的示例中,我打开文件而不是创建新文件。

    【讨论】:

      【解决方案4】:
      public override bool Exists(string filePath)
          {
              try
              {
                  string path = Path.GetDirectoryName(filePath);
                  var fileName = Path.GetFileName(filePath);
                  StorageFolder accessFolder = StorageFolder.GetFolderFromPathAsync(path).AsTask().GetAwaiter().GetResult();
                  StorageFile file = accessFolder.GetFileAsync(fileName).AsTask().GetAwaiter().GetResult();
                  return file != null;
              }
              catch
              {
                  return false;
              }
          }
      

      【讨论】:

        【解决方案5】:

        这样System.IO.File.Exists(filePath)我无法测试DocumentLibrary 因为KnownFolders.DocumentsLibrary.Path返回空字符串

        下一个解决方案很慢await DownloadsFolder.GetFileAsync("01-Introduction.pdf")

        恕我直言,最好的方法是从文件夹中收集所有文件并检查文件名是否存在。

        List<StorageFile> storageFileList = new List<StorageFile>();
        
        storageFileList.AddRange(await KnownFolders.DocumentsLibrary.GetFilesAsync(CommonFileQuery.OrderByName));
        
        bool fileExist = storageFileList.Any(x => x.Name == "01-Introduction.pdf");
        

        【讨论】:

          【解决方案6】:

          这对我在 Windows 10 上运行我的 UWP C# 应用程序很有用...

              StorageFolder app_StorageFolder = await StorageFolder.GetFolderFromPathAsync( @App.STORAGE_FOLDER_PATH );
              var item = await app_StorageFolder.TryGetItemAsync(relative_file_pathname);
              return item != null;
          

          【讨论】:

            【解决方案7】:

            这对我有帮助:

            ApplicationData.Current.LocalFolder.GetFileAsync(path).AsTask().ContinueWith(item => { 
                if (item.IsFaulted)
                    return; // file not found
                else { /* process file here */ }
            });
            

            【讨论】:

              【解决方案8】:

              在 Window 10 上,对我来说,这是最“优雅”的方式:

              private static bool IsFileExistent(StorageFile file)
              {
                  return File.Exists(Path.Combine(file.Path));
              }
              

              或者,如果您愿意并会广泛使用它,可以作为扩展:

              static class Extensions
              {
                  public static bool Exists(this StorageFile file)
                  {
                      return File.Exists(Path.Combine(file.Path));
                  }
              }
              

              【讨论】:

              • 路径太长时文件失败:stackoverflow.com/questions/11210408/…
              • @visc 在线程上,您可以在评论中看到,当尝试访问文件时发生任何错误时,此方法应返回 false。因此,如果系统将“path to long”视为错误,这种方法仍然是正确的。正如作者确认的那样,在另一个线程上提出的解决方案效率低下,我在这里尝试提出最“优雅”的解决方案。而且它在 99.9% 的情况下都有效,因此我认为将该解决方案集成到此提案中没有用处。
              【解决方案9】:

              System.IO.File.Exists 也是 UWP 方式。我现在在 Windows IOT 中进行测试。它只是工作。

              【讨论】:

                【解决方案10】:

                我正在做一个 Win10 IoT Core UWP 应用程序,我必须检查文件长度而不是“存在”,因为CreateFileAsync() 已经立即创建了一个空文件存根。但我需要先调用该调用来确定文件所在的整个路径。

                原来如此:

                    var destinationFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("MyFile.wow", ...);
                
                    if (new FileInfo(destinationFile.Path).Length > 0)
                        return destinationFile.Path;
                

                【讨论】:

                  【解决方案11】:

                  您可以使用 System.IO.File。 示例:

                  // If file located in local folder. You can do the same for other locations.
                  string rootPath = ApplicationData.Current.LocalFolder.Path;
                  string filePath = Path.Combine(rootPath, "fileName.pdf");
                  
                  if (System.IO.File.Exists(filePath))
                  {
                      // File exists
                  }
                  else
                  {
                      // File doesn't exist
                  }
                  

                  【讨论】:

                  • 虽然不是“UWP 方式”(特别是,它同步执行 I/O 操作 - 尽管速度非常快),但在 UWP (Win10) 应用程序上这是一个可行的选项。请注意,该应用程序不会对文件进行任何锁定;如果另一个线程或进程在检查和使用之间删除或创建文件,您可能会遇到意外(并且可能有害)的行为。
                  【解决方案12】:

                  在这种情况下,您可以使用 FileInfo 类。它有一个名为 FileInfo.Exists() 的方法,它返回一个布尔结果

                  https://msdn.microsoft.com/en-us/library/system.io.fileinfo.exists(v=vs.110).aspx

                  编辑:

                  如果您想检查文件是否存在,您需要创建一个 StorageFile 对象并调用 GetFile.... 方法之一。如:

                  StorageFile file = new StorageFile();
                  file.GetFileFromPathAsync("Insert path")
                  
                  if(file == null)
                  {
                     /// File doesn't exist
                  }
                  

                  我快速查看了下载文件夹路径,但没有任何乐趣,但 GetFile 方法应该可以为您提供所需的答案

                  【讨论】:

                  • 谢谢 Ben,你和 Absolute 都朝着正确的方向前进,但不幸的是我目前只返回 False,我在上面用 Absolute 评论过,我如何确认正在搜索哪个目录/文件夹文件信息?
                  • 我认为您可能需要使用 getfile 函数来查看它们是否返回对象或 null。答案已更新
                  【解决方案13】:

                  有两种方法

                  1) 您可以使用StorageFolder.GetFileAsync(),因为 Windows 8.1 和 WP 8.1 设备也支持此功能。

                  try
                  {
                     StorageFile file = await DownloadsFolder.GetFileAsync("01-Introduction.pdf");
                  }
                  catch
                  {
                      Debug.WriteLine("File does not exits");
                  }
                  

                  2) 或者您可以使用仅适用于 Windows 10 UWP 的FileInfo.Exists

                  FileInfo fInfo = new FileInfo("01-Introduction.pdf");
                  if (!fInfo.Exists)
                  {
                      Debug.WriteLine("File does not exits");
                  }
                  

                  【讨论】:

                  • 不幸的是 (1) 在 Windows 10 UWP 中似乎不可用,没有为 DownloadsFolder 定义 GetFileAsync。 (2)似乎正是我要找的,不幸的是我总是返回False,我如何指定要在哪个文件夹中搜索FileInfo。我只支持Win10,完全不向后兼容。
                  • 你确定 DownloadFolder 是 StorageFolder 类型吗,如果是,它应该有定义。尝试粘贴您的整个代码,我会检查出来
                  • DownloadFolder 没有 GetFileAsync() 方法
                  • 如果你打算使用System.IO,你不妨使用System.IO.File.Exists(String)。它更高效 - 无需构造对象 - 并且更易于阅读。
                  猜你喜欢
                  • 2022-11-12
                  • 1970-01-01
                  • 2021-12-25
                  • 1970-01-01
                  • 2015-12-20
                  相关资源
                  最近更新 更多