Is it possible to read File from same folder where Azure function exists
Asked Answered
E

5

32

In my Azure C# function I need to read a .txt file. I make the .txt file in Visual studio and set it to "copy Always".

Now I am using this code to read the file

var dir = System.IO.Path.GetDirectoryName(
    System.Reflection.Assembly.GetEntryAssembly().Location);

var path = System.IO.Path.Combine(dir, "twinkle.txt");

this code doesn't work. When I open the folder which is the value of dir. It lead me to this directory ""C:\Users{username}\AppData\Local\Azure.Functions.Cli\1.0.9""

How I can store a simple txt file in Azure function. Or I need Azure Storage for this.

Anything else I can do to get this done.

Update for showing file copied

enter image description here

Everyday answered 1/4, 2018 at 11:50 Comment(3)
Embed that file as a resource into assembly.Gouge
@Gouge I am checking that way, thanks for idea.Everyday
@Gouge yes, it's working. thanksEveryday
G
70

Here is how to get to the correct folder:

public static HttpResponseMessage Run(HttpRequestMessage req, ExecutionContext context)
{
    var path = System.IO.Path.Combine(context.FunctionDirectory, "twinkle.txt");
    // ...
}

This gets you to the folder with function.json file. If you need to get to bin folder, you probably need to go 1 level up, and then append bin:

// One level up
Path.GetFullPath(Path.Combine(context.FunctionDirectory, $"..{Path.DirectorySeparatorChar}twinkle.txt"))

// Bin folder
Path.GetFullPath(Path.Combine(context.FunctionDirectory, $"..{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}twinkle.txt"))
Garnish answered 1/4, 2018 at 12:3 Comment(6)
I don't believe I have access to ExecutionContext at startup. Any other way to do that?Ursine
I had the same problem @BillNoel, I've posted an answer below that address the issue.Maple
You can just add ExecutionContext context as a parameter to the Run method of your function.Brunet
context.FunctionAppDirectory gives you access to anything in the applications root folder context.FunctionDirectory only gives you access to the function specific directoryNormy
This will only work on Windows (if it works)Chaldea
context.FunctionAppDirectory is the right answer now. Adding this in the event somebody else lands here and gets confused.Mab
M
37

For those like me who doesn't have access to ExecutionContext since we have to read a file in Startup.

var binDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var rootDirectory = Path.GetFullPath(Path.Combine(binDirectory, ".."));

///then you can read the file as you would expect yew!
File.ReadAllText(rootDirectory + "/path/to/file.ext");

Also worth noting that Environment.CurrentDirectory might work on a local environment, but will not work when deployed to Azure.

Works inside functions too.

Reference

Maple answered 19/2, 2020 at 14:35 Comment(7)
Super useful for including Google.json files that are necessary for FirebaseAdmin functions! Thanks, louie!Ursine
Wondering how this has worked for everyone. The executing assembly directory that I see is a temporary ASP.NET location and the config file of course does not exists there. "D:\local\Temporary ASP.NET Files\root\80e1a0b8\1c033853\assembly\dl3\dc0956b6\".Partner
Hmmm, that is strange indeed, it's maybe worth checking out the reference I included in the answer @PrasadKorhaleMaple
If I have the file in folder it doesn't work, it had to be directly places under root folderSpermatophore
@PrasadKorhale, because I think you are deploying the source code (as opposed to a built assembly) and your project is being compiled on the hosting of Functions App.Borneo
@Spermatophore then you have to navigate to the folder after getting the root directory similar to what I have in the answer rootDirectory + "/your/sub/folders/file.ext"Maple
Needed to add "wwwroot" to the end for working. var rootDirectory = Path.Combine(Path.GetFullPath(Path.Combine(binDirectory, ".."),"wwwroot"));Parang
V
0

To use a file called pub_key.pem in an Azure Function. I'd rather do this in the .csproj file:

<ItemGroup>
    <EmbeddedResource Include="pub_key.pem">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </EmbeddedResource>
</ItemGroup>
 

and then read the file using a Stream

var assy = Assembly.GetAssembly(typeof(AnyClassInFunction)); 
Stream fileStream = assy.GetManifestResourceStream(typeof(AnyClassInFunction),"pub_key.pem");

Vitale answered 30/1, 2023 at 3:35 Comment(0)
R
0

I tried most of the above but still had issues. I found an article on another site where MS suggested a way to do this.

I ended up with an Environment Variable in local.settings.json that held the path to the dir containing my files.

Locally it was: "LiquidTemplatesPath": "C:_WorkingFolder_Code_Integrations_Partner"

In the AzFn Env it was: C:_home_site_wwwroot

This reflects the folder it sits in on the server. In code I then just access it as follows:

string? azure_root = Environment.GetEnvironmentVariable("LiquidTemplatesPath");
azure_root = azure_root.Replace("_", "/");
string liquidTemplate = File.ReadAllText($"{azure_root}{templateTxtPathWithLeadingSlash}");

The reason for _ in the variable is because I also hit issues trying to pass it in the YAML pipeline so this was the easiest workaround e.g.

          appSettings: 
            -LiquidTemplatesPath C:_home_site_wwwroot

Hopefully this might help someone.

Reunion answered 27/6 at 10:57 Comment(0)
P
-1

Here is a useful link: https://github.com/Azure/azure-functions-host/wiki/Retrieving-information-about-the-currently-running-function

There is the possibility of a hard coded way:

File.ReadAllText("d:\home\site\wwwroot\NameOfYourFunction" + "/path/to/file.ext");
Piperonal answered 20/2, 2020 at 13:49 Comment(1)
This sound cool but hard coded code are bad. What if Azure suddenly storing Function somewhere else ?Everyday

© 2022 - 2024 — McMap. All rights reserved.