Reputation: 24067
I'm creating a StreamWriter
using a relative path. But the file doesn't appear. To troubleshoot, I want to check that the full path is what I'm expecting. So having a StreamWriter
instance, how can I get the full path of the file it's going to write to?
string fileName = "relative/path.txt"
StreamWriter sw= new StreamWriter(fileName);
// What is the full path of 'sw'?
Upvotes: 22
Views: 35398
Reputation: 2700
Using nullable types and safe casting (as
doesn't throw exceptions):
_logger.LogInformation("Wrote file at {0}", (streamWriter.BaseStream as FileStream)?.Name);
?
only accesses the property if the result of the expression on the left is not null
, otherwise it returns (evaluates to) null
(it's like it's equivalent to E is T ? (T)(E) : (T)null
).
If you wanted, you could check the cast result for null
like this:
var fs = streamWriter.BaseStream as FileStream;
if (fs != null)
{
_logger.LogInformation("Wrote file at {0}", fs.Name);
}
But that's more code than you need. The more modern way to write the above example with C# 7+ is to use the is
operator:
if (streamWriter.BaseStream is FileStream fs)
{
_logger.LogInformation("Wrote report file at {0}", fs.Name);
}
This has the added benefit that the log call doesn't happen at all, if the cast could not be performed, because actually fs
is never null
when using is
. The entire is
expression evaluates to either true or false, but never null
.
Upvotes: 1
Reputation: 21
This would be better as a comment to @Jeppe Stiehl Nielsen's reply, but I can't add comments: In VB.Net, this becomes:
Dim fullPath As String = CType(streamWriter.BaseStream, FileStream).Name
I'm not sure why the CType
is needed, and only for this property while all other properties do not, but it's needed.
Upvotes: 0
Reputation: 62012
In my version of the framework, this seems to work:
string fullPath = ((FileStream)(streamWriter.BaseStream)).Name;
(Found by debugging.)
Upvotes: 65
Reputation: 568
Dim fs As FileStream = CType(sw.BaseStream, FileStream)
Dim fi As New FileInfo(fs.Name)
Console.WriteLine(fi.FullName)
Upvotes: 0
Reputation: 216363
To get the full path from a relative path, use the Path.GetFullPath method.
For example:
string fileName = "relative/path.txt";
string fullPath = Path.GetFullPath(fileName);
Upvotes: 11
Reputation: 16981
var fstream = sw.BaseStream as System.IO.FileStream;
if (fstream != null)
Console.WriteLine(GetAbsolutePathByHandle(fstream.SafeFileHandle));
[DllImport("ntdll.dll", CharSet = CharSet.Auto)]
private static extern int NtQueryObject(SafeFileHandle handle, int objectInformationClass, IntPtr buffer, int StructSize, out int returnLength);
static string GetAbsolutePathByHandle(SafeFileHandle handle)
{
var size = 1024;
var buffer = Marshal.AllocCoTaskMem(size);
try
{
int retSize;
var res = NtQueryObject(handle, 1, buffer, size, out retSize);
if (res == -1073741820)
{
Marshal.FreeCoTaskMem(buffer);
size = retSize;
Marshal.AllocCoTaskMem(size);
res = NtQueryObject(handle, 1, buffer, size, out retSize);
}
if (res != 0)
throw new Exception(res.ToString());
var builder = new StringBuilder();
for (int i = 4 + (Environment.Is64BitProcess ? 12 : 4); i < retSize - 2; i += 2)
{
builder.Append((char)Marshal.ReadInt16(buffer, i));
}
return builder.ToString();
}
finally
{
Marshal.FreeCoTaskMem(buffer);
}
}
Output:
\Device\HarddiskVolume2\bla-bla\relative\path.txt
Upvotes: -2
Reputation: 6326
Might be the directory 'relative' not exists. Either create it manually. Or create it programmatically as below
string fileName = @"relative\path.txt";
fileName = Path.GetFullPath(fileName);
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
StreamWriter sw= new StreamWriter(fileName, true);
Upvotes: 1