如何在项目根目录中读取文本文件?

106

我想读取我添加到项目根目录中的文本文件的第一行。也就是说,我的解决方案资源管理器显示了我的项目中的.cs文件以及.txt文件。

因此,我尝试做:

TextReader tr = new StreamReader(@"myfile.txt");
string myText = tr.ReadLine();

但是这并不起作用,因为它正在引用Bin文件夹,而我的文件不在其中... 我该如何使其起作用? :/

谢谢


顺便说一句,StreamReader 的名称有点令人困惑,我认为微软应该将其命名为 TextStreamReader。 - George Birbilis
7个回答

167

从“解决方案资源管理器”中,右键点击 myfile.txt 文件并选择“属性”

接着,在那里把 Build Action 设置为 content, 并将Copy to Output Directory设置为 始终复制(Copy always) 或者 仅在较新时复制(Copy if newer)

输入图像说明


2
我宁愿不让我的用户看到这个文件... 是否有一种方法可以将其嵌入dll并从那里读取? - Shai UI
3
尝试将该字符串作为资源添加到项目中,而非使用文件。请注意,数据将不会无法获取。这个文件包含的数据有多敏感? - Dan J
5
将构建选项设置为“嵌入资源”,并阅读关于如何读取嵌入资源的文章http://blogs.msdn.com/b/nikola/archive/2008/05/14/embedded-resources.aspx - dance2die
如果我正在为一个项目创建安装程序,那么我就无法使用属性进行工作。有其他解决方案吗? - Neel Bhasin

37

您可以使用以下代码获取网站项目的根目录:

String FilePath;
FilePath = Server.MapPath("/MyWebSite");

或者你可以这样获取基本目录:

AppDomain.CurrentDomain.BaseDirectory

33

将资源文件添加到项目中(右键单击项目->属性->资源)。在“字符串”处,您可以切换到“文件”。选择“添加资源”并选择您的文件。

现在,您可以通过Properties.Resources集合引用您的文件。


当我尝试时,出现了“路径中的非法字符”。该资源似乎将您的文件内容保存为字符串,并在一定长度后截断它。 - user0474975

19
private string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);

上述方法将会给你带来像这样的东西:

"C:\Users\myuser\Documents\Visual Studio 2015\Projects\myProjectNamespace\bin\Debug"

您可以使用 System.IO.Directory.GetParent 后退导航:

_filePath = Directory.GetParent(_filePath).FullName;

一次将带您到 \bin,两次将带您到 \myProjectNamespace,因此会是这样:

_filePath = Directory.GetParent(Directory.GetParent(_filePath).FullName).FullName;

现在你有了类似"C:\Users\myuser\Documents\Visual Studio 2015\Projects\myProjectNamespace"的路径,所以只需将最终路径附加到你的文件名上即可,例如:

_filePath += @"\myfile.txt";
TextReader tr = new StreamReader(_filePath);

希望这有所帮助。


谢谢,但可以这样写: _filePath = Path.Combine(_filePath, "myfile.txt"); // 优雅的写法 :) - FreeClimb

15

您也可以将它嵌入(构建操作设置为 Resource),这是从中检索它的方法:

private static UnmanagedMemoryStream GetResourceStream(string resName)
{
    var assembly = Assembly.GetExecutingAssembly();
    var strResources = assembly.GetName().Name + ".g.resources";
    var rStream = assembly.GetManifestResourceStream(strResources);
    var resourceReader = new ResourceReader(rStream);
    var items = resourceReader.OfType<DictionaryEntry>();
    var stream = items.First(x => (x.Key as string) == resName.ToLower()).Value;
    return (UnmanagedMemoryStream)stream;
}

private void Button1_Click(object sender, RoutedEventArgs e)
{
    string resName = "Test.txt";
    var file = GetResourceStream(resName);
    using (var reader = new StreamReader(file))
    {
        var line = reader.ReadLine();
        MessageBox.Show(line);
    }
}

(参考此答案,作者Charles)


4

在这种情况下,您必须使用绝对路径。但是,如果您设置了CopyToOutputDirectory = CopyAlways,它将像您正在执行的那样工作。


2

在这段代码中,您可以访问root项目目录:

 string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);

那么:

StreamReader r = new StreamReader(_filePath + "/cities2.json"))

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