1

It is my first time with C# (I wrote in Java before). I tried to get the path to the json file "movies-filtered.json" located in directory "Resources" by this way:

enter image description here

string fileName = "movies-filtered.json";
string path = Path.Combine(Environment.CurrentDirectory, "..\\..\\Resources\\", fileName);
Console.WriteLine(path);

Console.WriteLine("Hold the application: ");
string Number2 = Console.ReadLine();

But the output of this Console.WriteLine(path) is: C:\Users\xxxxxx\Movie_Library_C#\MovieLibrary\MovieLibrary\bin\Debug....\Resources\movies-filtered.json

The "xxxxxx" hide some part of the path.

I tried to get out of the "bin/Debug" directories and then from "MovieLibrary" go to "Resources" directory and there is "movies-filtered.json" file which I want to get. But it doesn't work like that.

Could anyone help me to solve this issue? I will be gratefull for help.

EDITED

My goal is to be able to load json file from directory "Resources". I want to do this in Dao.cs class by the method "LoadObjectsFromJsonFile":

public class Dao
{
    private const char delimiter = ',';
    private IList<Movie> Movies;

    public IList<Movie> GetMovies { get => Movies; set => Movies = value; }

    public Dao()
    {
        this.Movies = null;
    }

    public void LoadObjectsFromJsonFile()
    {
        string Filepath = "../MovieLibrary/Resources/movies-filtered.json";
        using (StreamReader Sr = new StreamReader(Filepath))
        {
            var Json = Sr.ReadToEnd();
            Movies = JsonConvert.DeserializeObject<List<Movie>>(Json);
        }
    }
JeyKey
  • 413
  • 1
  • 9
  • 22
  • *it doesn't work like that* That doesn't help us. In what way does it not work? Do you have an error? – DavidG May 10 '18 at 10:46
  • Are you telling us that after Path.Combine the backslashes before Resources are missing? – Steve May 10 '18 at 10:49
  • 1
    Ideally you'd mark `movies-filtered.json` to be copied to the output directory. Now you don't need to do upward directory traversal. Right-click the file in the solution explorer, choose properties then "copy always"/"copy if newer". (It's been a few months since I last opened VS, so the wording might be a little different). – spender May 10 '18 at 10:49
  • In any case your compiled program will not run in a bin\debug folder so you should rethink your approach (as @spender suggested) – Steve May 10 '18 at 10:51
  • Or read the absolute path to the file from a config value if it might change in future. – DavidG May 10 '18 at 10:54
  • You can look into Server.MapPath Method , for reference https://msdn.microsoft.com/en-us/library/ms524632%28v=vs.90%29.aspx?f=255&MSPPError=-2147217396 – Frankenstine Joe May 10 '18 at 11:00
  • @FrankenstineJoe This is a console app, not a web app – DavidG May 10 '18 at 11:01
  • I updated my question. The goal is to be able to be able to load json file from "Resources" directory. I want to load it in "DAO" directory inside Dao.cs class" What approach should I consider then? – JeyKey May 10 '18 at 12:01

3 Answers3

1

First, let's solve the immediate problem: one reason to use Path.Combine is to avoid backslashes altogether. You should be able to achieve the desired result by passing ".." literals separately:

string path = Path.Combine(Environment.CurrentDirectory, "..", "..", "Resources", fileName);

Now let's consider what you are trying to achieve: if you are looking to make the file available to your code at runtime, this approach is not going to work, because the location of the file is going to change. You can have the file copied by the compiler into the output directory, or embed it as a resource.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Not sure why you got a dv, but maybe because your proper use of `Path.Combine` gives the same output as OP so doesn't fix the problem? The question is kind of unanswerable if you ask me, but this is good advice. – DavidG May 10 '18 at 10:59
  • if you see file structure do you think, OP needs .. in Path.Combine function?, btw I am not downvoter – Prasad Telkikar May 10 '18 at 11:37
  • I updated my question. The goal is to be able to be able to load json file from "Resources" directory. I want to load it in "DAO" directory inside Dao.cs class" What approach should I consider then? – JeyKey May 10 '18 at 12:02
  • I didn't downvote, but I wouldn't use relative directories to source file locations. You can't count on the build location like that (it is by default, but easily changed). The other issue I see is `Environment.CurrentDirectory` may or may not point to the EXE location, it is easily changed by factors outside the program's control. – Ron Beyer May 10 '18 at 12:21
  • @RonBeyer Well, this question started as an X\Y problem, so the answer has two parts - the immediate fix, and suggestions for the actual fix. – Sergey Kalinichenko May 10 '18 at 12:24
  • @JeyKey Do you need an ability for end-users to modify the content of `movies-filtered.json` file after you have compiled your program, or should it remain fixed to what you put in there at the time when you compiled your code? – Sergey Kalinichenko May 10 '18 at 12:27
  • @dasblinkenlight It can be fixed. But I would also like to know how to approach this problem if I would like to keep this file secure from end-user to modify it after I compile the program. – JeyKey May 10 '18 at 12:46
  • @JeyKey The only way to keep the file secure from end-users' modifications is to make it unavailable to end users by embedding it. That is what I would do in my project with your requirements. Follow the steps outlined in Microsoft tutorial at the "embed as resource" link from the answer, it is relatively straightforward. This approach is very similar to `classLoader.getResourceAsStream` in Java. – Sergey Kalinichenko May 10 '18 at 12:52
  • @dasblinkenlight Thank you for your help. I appreciate it. – JeyKey May 10 '18 at 12:53
0

In order to load files like that, you need to do two things...

First, click on the file and make sure that the Build Action (in the Property Panel) is set to Copy Always or Copy if Newer. This will make sure to copy your .json files to the build directory with the specified folder structure.

Next, is to build the path, you should (need to) use Path.Combine, but I would recommend not using Environment.CurrentDirectory. The problem is that it returns the current working directory, which may or may not be the path to your executable.

To get the folder of your executable, you can do this:

var exeFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

And then combine it with your resource location to get the full path:

var jsonFile = Path.Combine(exeFolder, "Resources", "Filename.json");
Ron Beyer
  • 11,003
  • 1
  • 19
  • 37
0

I also found the answer to my problem, but it makes the program search for the path to the Solution Directory and then I manipulate the path to get to the right directory and the right file:

public void LoadObjectsFromJsonFile()
    {
        string SolutionPath = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
        string Filepath = SolutionPath + "\\Resources\\movies-filtered.json";
        using (StreamReader Sr = new StreamReader(Filepath))
        {
            var Json = Sr.ReadToEnd();
            Movies = JsonConvert.DeserializeObject<List<Movie>>(Json);
        }
        LoadActors();
    }

The right path is the "FilePath"

JeyKey
  • 413
  • 1
  • 9
  • 22