简体   繁体   中英

C#: opening a text file stored within the same project as the app

I managed to open a text file using an absolute path (in Visual Studio 2017) although if I change the location of my Solution folder the whole code would not work anymore as the actual physical path has changed and the code can not reference an existing location anymore.

I tried to create a text file within the same project and I would now like to open this file in my code, so if the location of the whole Solution changes the program can still work, would anyone be so kind to help me fix this issue? I have also looked online for some different solution using code that references the current directory but I can't get my head around it as the current directory seems to be bin/debug and if I try to insert the file there the code doesn't recognize the location (also it doesn't look like a clean solution to me).

This is the code I am using so far in a WPF app, the whole purpose is to open the content of the text file containing countries listed line by line and to add them to a list box which will be displayed when a checkbox will be ticked.

private void listCountry_Initialized(object sender, EventArgs e)
        {
            listCountry.Visibility = Visibility.Hidden;
            string path = "C:\\Users\\david\\source\\repos\\StudentRecord\\StudentRecordSystemMod\\StudentRecord\\country.txt";
            if (File.Exists(path))
            {
                string[] myCountryFile = File.ReadAllLines(path);

                foreach (var v in myCountryFile)
                {
                    listCountry.Items.Add(v);
                }
            }
        }

This is a great use case for OpenFileDialog Class .

Represents a common dialog box that allows a user to specify a filename for one or more files to open.

Here is the example of use, from the documentation .

 // Configure open file dialog box Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); dlg.FileName = "Document"; // Default file name dlg.DefaultExt = ".txt"; // Default file extension dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension // Show open file dialog box Nullable<bool> result = dlg.ShowDialog(); // Process open file dialog box results if (result == true) { // Open document string filename = dlg.FileName; }

Clean and simple, place the file you want to open next to where the executable is generated, remember the executable path changes depending to if your project is in Debug or Release build mode. Now set:

string path = "country.txt";

By only providing a filename, the file is looked for in the same folder as the executable. Just remember that when you move the executable you must also move the file to the same place, but if you move the entire project folder then you're already set.

However, if you want to keep your file in a fixed location regardless of where you have your executable and/or VS project files, then the simplest path for it is:

string path = "C:\\country.txt";

This is an absolute path, but it's quite simple and very robust to changes, you would have to change the drive letter to break it and if C: is where your operating system files are then you probably won't do that.

If you don't like to have your files around in your root, you can always have a path like this:

string path = "C:\\ProjectNameFiles\\country.txt";

Or if you prefer to maintain a hierarchy of projects then you can use:

string path = "C:\\MyProjectsFiles\\ProjectName\\country.txt";

With this, every project can have a directory for the files it needs to open. These are all absolute paths, but are notably simpler than the one you posted, and they have a more fixed and organized structure.

Assuming C:\\Users\\david\\source\\repos\\StudentRecord\\StudentRecordSystemMod\\ is your project, and StudentRecord\\country.txt is a project folder and file in your project - you need change "Copy to Output Directory" to be "Always Copy" or "Copy If Newer" and "Build Action" to "Content" for the file in your project.

显示调试输出的项目和属性的屏幕截图

As you can see from the screenshot above, the folder structure for this content is created as well.

Then change your path assignment to be something like the following:

string path = string.Join(@"\", Application.ExecutablePath, @"StudentRecord\country.txt");

You can try using this path that is in fact the project folder:

static public readonly string AppRootFolderPath
  = Directory.GetParent
    (
      Path.GetDirectoryName(Application.ExecutablePath
                            .Replace("\\Bin\\Debug\\", "\\Bin\\")
                            .Replace("\\Bin\\Release\\", "\\Bin\\"))
    ).FullName
  + Path.DirectorySeparatorChar;

In this folder you have the default Bin and Obj for example if you haven't changed them in the project properties build tab.

So you can use:

static public readonly string CountryFile = AppRootFolderPath + "country.txt";

But you can add to the path any subfolder you want like Data :

static public readonly string AppDataFolderPath
  = AppRootFolderPath + "Data" + Path.DirectorySeparatorChar;

Hence for example you can use:

static public readonly string CountryFile = AppDataFolderPath + "country.txt";

Here I used static because I generally put such vars in the Program class to be like globals and you can put them where you want.

You can also use user local data or documents path if the file may be edited:

How to initialize user app data and document path

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM