Oleg Vazhnev
Oleg Vazhnev

Reputation: 24067

How to get full path of StreamWriter

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

Answers (7)

Paul-Sebastian Manole
Paul-Sebastian Manole

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

CeSinge
CeSinge

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

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 62012

In my version of the framework, this seems to work:

string fullPath = ((FileStream)(streamWriter.BaseStream)).Name;

(Found by debugging.)

Upvotes: 65

Aave
Aave

Reputation: 568

Dim fs As FileStream = CType(sw.BaseStream, FileStream)
Dim fi As New FileInfo(fs.Name)
Console.WriteLine(fi.FullName)

Upvotes: 0

Steve
Steve

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

Serj-Tm
Serj-Tm

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

Cinchoo
Cinchoo

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

Related Questions