Can't get absolute path to file C# - c#

I have very simple program. Here I set the absolute path,but C# thinks that it's a relative path and try to load the file from project directory: C:\Users\Gleb Kozyukevich\source\repos\ChangeDir\ChageDir\bin\Debug\netcoreapp3.1\C:\test\test.txt
The path really exists.
What did I miss? I can't get understand

There are multiple ways you try.
Give file path like
string sourceFilePath = #"C:\test\test.txt";
Use System.IO.Path.Combine
string sourceFilePath = System.IO.Path.Combine(new []{"C:","test","test.txt"});

That is very strange. I've reproduced the code the way I think you wrote it and the result is just fine.
Here the code I wrote:
using System;
using System.IO;
namespace ReadAllLines
{
internal class Program
{
static void Main(string[] args)
{
var lines = File.ReadAllLines(#"c:\temp\test.txt");
Console.ReadKey();
}
}
}
Here's the result:

Related

Directory.CreateDirectory throws PathTooLong but Path.GetFullPath does not for same path

Given the below console application, I have a problem understanding the .net Framework behavior.
I do have an absolute path to a folder (Windows), that I want to create. To avoid a PathTooLongException during Directory.CreateDirectory() I check for that in advance by doing a Path.GetFullPath() for the path. However, this is not working for a reason I don't understand.
My questions are:
Why is this happening?
How can I (really, as in reliably) check if the path is to long before creating the directory
Notes:
- Simply catching the Exception during creation is not a solution for me, because the real world application does the PathTooLong check and the actual createion this on different places where a lot of other path related stuff is happening in between. So it would simply be to late to check that.
Edit: I checked that Path.GetFullPath() does not modify the path, but left that out in my example for brevity.
Here is my example code:
using System;
using System.IO;
namespace PathTooLongExperiments
{
class Program
{
static void Main(string[] args)
{
string pathThatFailsCreate = #"C:\Users\qs\1234567\vkT7eYDrFL0lZzEVBwx3O-8GE632bW64IvUiCqjOHv00661Kh,lVminnGrM4Y82EKD6\qozVNx8NoSDOhGoTV1f4syjtciBfv0fLCN7iSaRBuiHtIfgHNGJDbKQ28G4uqIumKa-\DtfhThPUI7J4hGxkPUem11PZBofq1uqn-7xw9YjBODLRouNCKo7T7-ODTc,Qjed01R0\8GfPtnmuUANti7sN55aq27cW";
TryCreateFolder(pathThatFailsCreate);
string pathThatWorks = #"C:\Users\qs\1234567\vkT7eYDrFL0lZzEVBwx3O-8GE632bW64IvUiCqjOHv00661Kh,lVminnGrM4Y82EKD6\qozVNx8NoSDOhGoTV1f4syjtciBfv0fLCN7iSaRBuiHtIfgHNGJDbKQ28G4uqIumKa-\DtfhThPUI7J4hGxkPUem11PZBofq1uqn-7xw9YjBODLRouNCKo7T7-ODTc,Qjed01R0\8GfPtnmuUANti7sN55aq27c";
TryCreateFolder(pathThatWorks);
Console.WriteLine("Done. Press any key");
Console.ReadKey();
}
private static void TryCreateFolder(string path)
{
Console.WriteLine($"Attempting to create folder for path: {path}");
string checkedPath;
try
{
checkedPath = Path.GetFullPath(path);
}
catch (PathTooLongException)
{
Console.WriteLine("PathToLong check failed!");
Console.WriteLine($"Path length: {path.Length}");
Console.WriteLine($"Path: {path}");
Console.ReadKey();
return;
}
try
{
Directory.CreateDirectory(checkedPath);
}
catch (PathTooLongException)
{
// Why is this possible? We've checked for path too long by Path.GetFullPath, didn't we?
Console.WriteLine("Could not create directory because the path was to long");
}
}
}
}

Changing the base path of an assembly from the bin directory to a different directory

I have a Test.cs file in C:\ This test file reads from an input file and writes the same to an output file.
Test.cs
public class Test
{
public static int Main(string[] args)
{
var reader = new StreamReader("in.txt");
string input = reader.ReadLine();
var writer = new StreamWriter("out.txt");
writer.WriteLine(input);
return 0;
}
}
Here it should be noted that the code only uses the filename and not the full file path, which means the file is expected to be in the directory where the program is running. And I have created the in.txt in C:\
Now, there is a c# code called Runner.cs in a solution in C:\Project\Runner.cs, that dynamically compiles the Test.cs code and runs it using reflection. Now, when the Test.cs runs, it expects the in.txt file to be in C:\Project\bin\Debug\in.txt , but it is actually present in C:\in.txt
So, my question is, is there a way to make the code to get the file from C:\in.txt and not from the bin directory without changing the path of the file in the Test.cs code file.
Edit: It is my bad that I forgot to mention why I am in need of this requirement.
The Test.cs file comes from over the wire. And I felt it will not be a good choice to edit this file and set the file path accordingly. I want to compile it and run it as it is.
I hope I am clear. If not, please feel free to ask for more information.
If it is as simple as you show in your code switching the CurrentDirectory works for this example:
var mainMembers = new CSharpCodeProvider()
.CreateCompiler()
.CompileAssemblyFromSource(
new CompilerParameters { GenerateInMemory = true }
, #"
using System;
using System.IO;
public class M {
public static int Main() {
Console.WriteLine(""CurDir = ""+ Environment.CurrentDirectory);
var reader = new StreamReader(""in.txt"");
string input = reader.ReadLine();
var writer = new StreamWriter(""out.txt"");
writer.WriteLine(input);
return 0;
}
}")
.CompiledAssembly
.GetType("M")
.GetMember("Main");
// inspect
Environment.CurrentDirectory.Dump("current");
// keep
var oldcd = Environment.CurrentDirectory;
// switch
Environment.CurrentDirectory = "c:\\temp";
// invoke external code
((MethodInfo) mainMembers[0]).Invoke(null,null);
// restore
Environment.CurrentDirectory = oldcd;
In a multi threaded scenario this becomes unreliable.

nunit test working directory

I have the following code (sample1.evol - file attached to my unit test project):
[Test]
public void LexicalTest1()
{
var codePath = Path.GetFullPath(#"\EvolutionSamples\sample1.evol");
//.....
}
I found that the working directory of test execution is not the assembly directory: (in my case codepath variable assigned to d:\EvolutionSamples\sample1.evol).
So, how can I change the execution working directory (without hardcode)? What will be the best practice to load any files attached to test case?
You can use following to get the directory of assembly running the code something like
var AssemblyDirectory = TestContext.CurrentContext.TestDirectory
I use this for integration tests that need to access data files.
On any machine the test needs to run create a system environment variable named TestDataDirectory that points to the root of where your test data is.
Then have a static method that gets the file path for you..
public static class TestHelper
{
const string EnvironmentVariable = "TestDataDirectory";
static string testDataDir = Environment.GetEnvironmentVariable(EnvironmentVariable);
public static string GetTestFile(string partialPath)
{
return Path.Combine(testDataDir, partialPath);
}
}
...
[Test]
public void LexicalTest1()
{
var codePath = TestHelper.GetTestFile(#"\EvolutionSamples\sample1.evol");
//.....
}
I am using this code:
var str = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
if (str.StartsWith(#"file:\")){
str = str.Substring(6);
}
Getting in str variable the assembly directory.
We were having a problem where tests run using ReSharper and NCrunch would work, but the native VS Test Runner would not be able to find the files, when given just a relative file path for the test to use. I solved it by creating a function that you pass the relative test file path into, and it will give you the absolute file path.
private static string _basePath = Path.GetDirectoryName(typeof(NameOfYourTestClassGoesHere).Assembly.Location);
private string GetAbsoluteTestFilePath(string relativePath) => Path.Combine(_basePath, relativePath);
You would then use the function like so:
var input = File.ReadAllLines(GetAbsoluteTestFilePath(#"TestData/YourTestDataFile.txt"));

Can I add date/time to outputted filename in C# file.writeallbytes

I am writing an errorlog to to file in the same directory the script exists. Id like to potentially create a new folder as it writes as well as add date/time to the filenames so they 2nd doesnt save over the first.
Here is what I have so far:
File.WriteAllBytes("ErrorLog.txt")
Thanks!
You can create a valid Windows file name with DateTime in it like this:
string filename = "ErrorLogFolder" + DateTime.Now.ToString("dd-MM-yyyy_hh-mm-ss") + ".txt";
Take a look at this sample code for naming a file
using System;
using System.IO;
class Program
{
static void Main()
{
//
// Write file containing the date with BIN extension
//
string n = string.Format("text-{0:yyyy-MM-dd_hh-mm-ss-tt}.bin",
DateTime.Now);
File.WriteAllText(n, "aaa");
}
}

how to write to a text file in C# in Linux with MONO Develop

Im using Ubunto OS with MONO Develop and Im programming with C#.
I want to write into a text file but I dont sure how to do it.
I tried this:
string[] lines = {"some text1", "some text2", "some text3"};
System.IO.File.WriteAllLines(#"/home/myuser/someText.txt", lines);
this didn't work.
I tried this:
string str = "some text";
StreamWriter a = new StreamWriter("/home/myuser/someText.txt");
a.Write(str);
this didn't work too.
what to do?
tnx.
Both should work, perhaps you forgot to provide the application code?
using System;
using System.IO;
public class Program
{
public static int Main(string[] args)
{
string[] lines = {"some text1", "some text2", "some text3"};
File.WriteAllLines(#"/home/myuser/someText.txt", lines);
return 0;
}
}
Compile with dmcs program.cs, e.g.
Make sure you close the stream (File.Close() or a.Close(), I'm not familiar with c# syntax) as only when the stream is disposed, it actually writes on the file.

Categories