I've got a problem that has apparently been encountered before, though the solutions then don't help with what I'm seeing.
I'm trying to write data to a file, based on a base 64 encoding of the contents of a Dictionary<string, object>
. It's supposed to go like this: if the file doesn't exist,
Dictionary
Dictionary
is turned into base 64 dataSteps 1 through 3 are working fine. Step 4 appears to be working fine, until you I open the file - when it's revealed that there's nothing in it. It gets created but not written to, and I end up with an empty file.
The code goes like this, where the top method (CreateDefaultConfigFile
is called if the file doesn't exist):
private static void CreateDefaultConfigFile()
{
Console.WriteLine("AppConfig.CreateDefaultConfigFile");
File.Create(CONFIG_FILE_PATH);
Configuration.Clear();
Configuration.Add("ClientId", "5577");
Configuration.Add("RedirectUri", "https://stackexchange.com/oauth/login_success");
Configuration.Add("RequestKey", "2WQ5ksCzcYLeeYJ0qM4kHw((");
Save();
}
public static void Save()
{
Console.WriteLine("AppConfig.Save");
string data = "";
foreach (KeyValuePair<string, object> pair in Configuration)
{
Console.WriteLine(" {0}: {1}", pair.Key, pair.Value.ToString());
if (pair.Value.GetType() == typeof(string))
{
data += pair.Key + SC_SPLITTER + pair.Value + "\n";
}
else if (pair.Value.GetType() == typeof(Array))
{
data += pair.Key + SC_SPLITTER + "[" + string.Join(",", pair.Value) + "]\n";
}
else
{
Configuration.Remove(pair.Key);
}
}
if (data.EndsWith("\n"))
{
data.Remove(data.Length - 2);
}
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
string encoded = Convert.ToBase64String(dataBytes);
File.WriteAllText(CONFIG_FILE_PATH, encoded);
Console.WriteLine(" Written to file.");
}
Important fact to note: the "Written to file." message never gets logged to the console (though if I put a log directly before the File.WriteAllLines
call, it does log). A breakpoint at the final Console.Log
call never raises.
No exceptions are thrown, and it's not because data
or encoded
are empty - logging them just before the write reveals data in both.
CONFIG_FILE_PATH
is a constant value of C:\Users\Me\Documents\longpath\bin\Debug\config\general.cgf
.
I've also tried using a FileStream
and FileStream.Flush()
, as suggested in the question I linked at the top - this doesn't work.
The File.Create
method doesn't do what you appear to think that it does.
It does create a file, but it also leaves the file open and returns a FileStream
object to handle the open file.
If you just call Create
and ignore the returned FileStream
object, then the file will be left open until the object is disposed by the garbage collector.
Depending on when the garbage collection runs, the File.WriteAllText
call will either be able to write to the file, or you will get an IOException
. The fact that you don't see anything written to the file, and that you don't see the text that is written out after the call, suggests that you actually get an exception but catch that at some other level and ignore it.
If you want to use File.Create
to create the file, you should get the FileStream
object and dispose it to close the file:
using (FileStream stream = File.Create(CONFIG_FILE_PATH)) {
}
However, you don't have to create the file before calling File.WriteAllText
, it will create the file if it doesn't exist.