将绝对路径转换为相对路径 C#

10

可能重复问题:
如何获取相对于当前工作目录的路径?

我有一些C#代码,其中包含了从绝对路径到相对路径的一些图片,这样无论应用程序文件夹位于哪里都可以找到这些图像。

例如,我的代码中(以及我的笔记本电脑中的图像)的路径为

C:/something/res/images/image1.jpeg

我希望在我的代码中使用这个路径

..../images/image1.jpeg 

因此,它可以在放置文件夹的任何位置运行,无论C:分区的名称是什么等等。

我希望在我的代码中有一个路径,它不受应用程序文件夹位置的影响,也不受其是否在另一个分区中的影响,只要它与解决方案的其余部分位于同一文件夹中。

我有这段代码:

 try 
 { 
     File.Delete("C:/JPD/SCRAT/Desktop/Project/Resources/images/image1.jpeg");
 } 
 catch (Exception) 
 { 
      MessageBox.Show("File not found:C:/Users/JPD/Desktop/Project/images/image1.jpeg");
  } 

只有在特定路径中同时存在文件和文件夹时,此代码才能运行(该路径也是代码的位置)。我希望该路径是相对的,因此无论我将整个文件夹(代码、文件等)放在哪里,只要代码(位于项目文件夹下)与图像文件夹位于同一位置,程序仍将正常工作……我该怎么办?


@user1766548 如果你都不理解那段代码,那么你怎么能理解我们在这里发布的其他任何代码呢? - Kiril
1
这个项目被一个回答被踩的家伙标记为重复......不错。 - John Demetriou
重复的答案很好。去那里看看。 - CAD bloke
2
@CADbloke,我需要的答案已经被接受为答案了。这个问题被标记为重复,因为一个人的回答被投票下降,因为它不符合我的需求。将某些东西标记为重复的人并没有检查它是什么。他们只是接受它并继续他们的生活而不检查它。 - John Demetriou
通常情况下,当一个问题被标记为重复时,会有一个指向重复问题的链接,但我在这里看不到。那么重复的问题在哪里? - markshep
@markshep 看看我最后发的评论:D 无论如何,这里的一个答案就是重复问题的答案。 - John Demetriou
3个回答

12

相对路径是基于你的应用程序运行的二进制文件。默认情况下,你的二进制文件会被输出到[.csproj所在目录]/bin/debug。例如,假设你想在与.csproj相同级别的位置创建一个名为images的文件夹。那么你可以使用相对路径"../../images/someImage.jpg"访问你的图像。

为了更好地了解这一点,请尝试以下测试:

1)创建一个新的Visual Studio示例项目;

2)在与.csproj相同的级别上创建一个images文件夹;

3)将一些文件放入images文件夹中;

4)将以下示例代码放入你的主方法中 -

    static void Main(string[] args)
    {
        Console.WriteLine(Directory.GetCurrentDirectory());
        foreach (string s in Directory.EnumerateFiles("../../images/"))
        {
            Console.WriteLine(s); 
        }
        Console.ReadLine(); // Just to keep the console from disappearing.
    }

你应该看到在第三步中放置的所有文件的相对路径。


明天我会尝试这个并告诉你结果,现在我要去睡觉了,因为之前的尝试失败了,太累了 :D - John Demetriou
你的意思是想要更改可执行文件部署的目录吗?另外,你想要避免哪种字符串操作? - Blake
没关系,我用了你的代码,真的很有帮助,我自己回答了后续问题。 - John Demetriou
太好了!很高兴它对你有用。如果这个答案帮到了你,请给它点赞(点击问题上方的数字前面的箭头)。非常感谢 - 谢谢 :) - Blake
我之前由于声誉太低而无法做到,但现在我做到了。 - John Demetriou
1
@user2781812 这就是正确的做法。这个问题被标记为另一个问题的重复,但另一个问题的答案不如这个好。强烈推荐使用这个版本。 - John Demetriou

9

1
没有为 Uri uri2 = new Uri(@"c:\foo\bar\bazz"); 给出正确的路径。 - L.B
@viggity 这不是完全重复的问题,我想要的答案是Blake的答案。你认为我需要的答案并不起作用。 - John Demetriou
1
如果bazz是一个目录,请使用Uri uri2 = new Uri(@"c:\foo\bar\bazz\"); 如果bazz是一个文件,则正确。 - Tom Blodget
对我来说起作用了,只需要在 ToString() 后切换斜杠为反斜杠即可。 - dba

0
根据你的程序设置,可能可以通过跳过完整路径字符串的一部分来使用相对路径。这不是什么值得炫耀的东西,所以 J. Skit 可能会因此而批评我,但我意识到你只是想让它正常工作。美观性可以之后再考虑。
String absolutePath = @"c:\beep\boop\HereWeStart\hopp.gif";
String relativePath = absolutePath.Substring(13);

如果需要/希望,您可以交换数字13(这是一种丑陋和不理想的方法,但仍然有效)为动态计算的数字。例如(假设目录“HereWeStart”是相对路径开始的位置,在absolutePath中第一次出现该字符串),您可以按照以下步骤进行。

String absolutePath = @"c:\beep\boop\HereWeStart\hopp.gif";
int relativePathStartIndex = absolutePath.IndexOf("HereWeStart");
String relativePath = absolutePath.Substring(relativePathStartIndex);

另外,你的问题引出了另一个问题。我想知道你是如何获取绝对路径的。也许有一种更聪明的方法可以完全避免这个麻烦?

编辑

你也可以尝试以下方法。忘记Directory类给你一个绝对路径。直接使用相对路径。我假设你要删除的所有文件都在同一个目录中。如果不是,你需要添加一些额外的代码,但我们会在那时解决这个问题。

别忘了将答案标记为绿色勾选(或者解释还缺少什么或者需要改进的地方)。

String
  deletableTarget = @"\images\image1.jpeg", 
  hereWeAre = Environment.CurrentDirectory;
MessageBox.Show("The taget path is:\n" + hereWeAre + deletableTarget);

try
{ File.Delete(hereWeAre + deletableTarget); }
catch (Exception exception)
{ MessageBox.Show(exception.Message); }

此外,请注意我已经擅自更改了你的异常处理。虽然你的处理方式起作用了,但更好的做法是依赖于内置的消息系统。这样你就可以得到更专业的错误信息。不过我们在运行时也不会有任何错误,对吧?;)

是的,我只想让它工作。我在上面的解决方案中发布了这条评论C:/Users/JPD/Desktop/project/Resources/images/image1.jpeg,但如果我将文件夹移动到其他地方,例如我的文档文件夹中的一个名为projects的文件夹中,我希望我的代码仍然能找到该图像,你给我的解决方案能解决这个问题吗? 你的解决方案会有效吗? - John Demetriou
你的解决方案没有起作用...... - John Demetriou
哦,好的,我知道转义字符和反斜杠(这就是我使用双反斜杠的原因),我不知道可以使用@来实现,谢谢伙计。 - John Demetriou
我必须获得15个声望才能投票 :D - John Demetriou
@macrian 现在你是的! ;) - Konrad Viltersten
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接