1

我的应用程序在执行它的目录的子目录中打开文件,调用子目录sample并包含文件:

  • example.raf(示例扩展,不重要)
  • background.gif

example.raf包含到的相对路径background.gif(在这种情况下,只有文件名,因为文件与 raf 位于同一目录中)并且打开 RAF 会导致应用程序读取和显示background.gif.

当我使用OpenFileDialog加载 RAF 文件时,一切正常,图像加载正确。我知道打开文件对话框以某种方式更改了当前工作目录,但我无法在不调用打开文件对话框的情况下重新创建它

不幸的是,如果我直接从代码中调用raf 读取OpenFileDialog方法,而不像这样提供文件形式的路径

LoadRAF("sample\\example.raf");

在这种情况下,我遇到了问题,应用程序尝试从 ExecutablePath加载图像,而不是从包含RAF文件和图像的子目录加载。当然,这是正常行为,但在这种情况下,这是非常不受欢迎的。需要在我的应用程序中处理相对和绝对类型的路径,所以我应该怎么做才能解决这个问题,如何更改 ExecutablePath 或者我可以做些什么来使这项工作至少在以下情况下工作OpenFileDialog

4

3 回答 3

3

我的项目 ZipSolution ( http://zipsolution.codeplex.com/ ) 中的下一个代码显示了如何在 .net 中解析和创建相对路径

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ZipSolution
{
    internal static class RelativePathDiscovery
    {
        /// <summary>
        /// Produces relative path when possible to go from baseLocation to targetLocation
        /// </summary>
        /// <param name="baseLocation">The root folder</param>
        /// <param name="targetLocation">The target folder</param>
        /// <returns>The relative path relative to baseLocation</returns>
        /// <exception cref="ArgumentNullException">base or target locations are null or empty</exception>
        public static string ProduceRelativePath(string baseLocation, string targetLocation)
        {
            if (string.IsNullOrEmpty(baseLocation))
            {
                throw new ArgumentNullException("baseLocation");
            }

            if (string.IsNullOrEmpty(targetLocation))
            {
                throw new ArgumentNullException("targetLocation");
            }

            if (!Path.IsPathRooted(baseLocation))
            {
                return baseLocation;
            }

            if (!Path.IsPathRooted(targetLocation))
            {
                return targetLocation;
            }

            if (string.Compare(Path.GetPathRoot(baseLocation), Path.GetPathRoot(targetLocation), true) != 0)
            {
                return targetLocation;
            }

            if (string.Compare(baseLocation, targetLocation, true) == 0)
            {
                return ".";
            }

            string resultPath = ".";

            if (!targetLocation.EndsWith(@"\"))
            {
                targetLocation = targetLocation + @"\";
            }

            if (baseLocation.EndsWith(@"\"))
            {
                baseLocation = baseLocation.Substring(0, baseLocation.Length - 1);
            }

            while (!targetLocation.StartsWith(baseLocation + @"\", StringComparison.OrdinalIgnoreCase))
            {
                resultPath = resultPath + @"\..";
                baseLocation = Path.GetDirectoryName(baseLocation);

                if (baseLocation.EndsWith(@"\"))
                {
                    baseLocation = baseLocation.Substring(0, baseLocation.Length - 1);
                }
            }

            resultPath = resultPath + targetLocation.Substring(baseLocation.Length);

            // preprocess .\ case
            return resultPath.Substring(2, resultPath.Length - 3);
        }

        /// <summary>
        /// Resolves the relative pathes
        /// </summary>
        /// <param name="relativePath">Relative path</param>
        /// <param name="basePath">base path for discovering</param>
        /// <returns>Resolved path</returns>
        public static string ResolveRelativePath(string relativePath, string basePath)
        {
            if (string.IsNullOrEmpty(basePath))
            {
                throw new ArgumentNullException("basePath");
            }

            if (string.IsNullOrEmpty(relativePath))
            {
                throw new ArgumentNullException("relativePath");
            }

            var result = basePath;

            if (Path.IsPathRooted(relativePath))
            {
                return relativePath;
            }

            if (relativePath.EndsWith(@"\"))
            {
                relativePath = relativePath.Substring(0, relativePath.Length - 1);
            }

            if (relativePath == ".")
            {
                return basePath;
            }

            if (relativePath.StartsWith(@".\"))
            {
                relativePath = relativePath.Substring(2);
            }

            relativePath = relativePath.Replace(@"\.\", @"\");
            if (!relativePath.EndsWith(@"\"))
            {
                relativePath = relativePath + @"\";
            }

            while (!string.IsNullOrEmpty(relativePath))
            {
                int lengthOfOperation = relativePath.IndexOf(@"\") + 1;
                var operation = relativePath.Substring(0, lengthOfOperation - 1);
                relativePath = relativePath.Remove(0, lengthOfOperation);

                if (operation == @"..")
                {
                    result = Path.GetDirectoryName(result);
                }
                else
                {
                    result = Path.Combine(result, operation);
                }
            }

            return result;
        }
    }
}
于 2009-11-17T09:54:33.820 回答
1

OpenFileDialog 在幕后吐出一条绝对路径。

如果您知道 raf 文件的位置,您可以执行以下操作:

string parentPath = Directory.GetParent(rafFilePath);
string imagePath = Path.Combine(parentPath, imageFileNameFromRaf);

imagePath 现在将包含从 raf 文件中包含的图像名称派生的图像的绝对路径,以及 raf 文件所在的目录。

于 2008-10-02T21:19:57.730 回答
0

在从相对路径读取之前,您可以尝试使用 Environment.CurrentDirectory 将当前目录更改为包含可执行文件的目录。或者相反,如果您有相对路径 (Path.IsPathRooted),您可以将 (Path.Combine) 您的根目录与相对路径结合起来,以获得绝对路径。

于 2009-11-17T10:03:43.407 回答