Framework Tips General IO
FAQ Home
1. How do you
persist any object in the registry?
2. How can I listen to changes in a file/directory in the windows file
system?
3. How can I convert a long path to a short path?
4. I want to iterate through both files and folders in a given folder. Is
this possible?
5. My application requires a simple ini file. Is there a easy way to
implement this without using any parsing?
6. How can I access a webpage from a windows form?
7. I just want to read a text file into a string. Is there some simple code
for this?
8. I just want to write a simple text file. Is there some simple code for
this?
9. While deserializing how do I check whether a name is available in the
deserialized info?
10. How come some of the objects are not initialized during deserialization?
1 How do you persist any object in the registry?
To store an object in the registry, the object should be serializable
(either has a Serializable attribute attached to it or derives from
ISerializable; same holds to all contained objects).
ArrayList names; // Source
object; Can contain any object that is serializable
... // Fill up this arraylist
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream1 = new MemoryStream();
formatter.Serialize(stream1, names);
RegistryKey regKey;
... // Open the key where you want to store it, with write permissions
regKey.SetValue("ValueName", stream1.ToArray());
To Read from registry:
ArrayList names; // Destination object
RegKey regKey;
... // Open the corresponding key
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream1 = new MemoryStream();
byte[] barray1 = null;
barray1 = (byte[])regKey.GetValue("ValueName");
if(barray1 != null)
{
stream1.Write(barray1, 0, barray1.Length);
MemoryStream stream1 = new MemoryStream();
byte[] barray1 = null;
barray1 = (byte[])regKey.GetValue("ValueName");
if(barray1 != null)
{
stream1.Write(barray1, 0, barray1.Length);
stream1.Position = 0;
names = formatter.Deserialize(stream1) as ArrayList;
}
2 How can I listen to changes in a file/directory in the windows file
system?
Use FileSystemWatcher to watch for changes in a specified
directory. You can watch for changes in files and subdirectories of the
specified directory. The component can watch files on a local computer, a
network drive, or a remote computer.
3 How can I convert a long path to a short path?
There is no direct support in the framework to do this. You have to use the
GetShortPathName function using PInvoke.
This is how the signature for this function looks like:
[DllImport("kernel32.dll",
SetLastError=true, CharSet=CharSet.Auto)]
public static extern int GetShortPathName(string longPath, [MarshalAs(UnmanagedType.LPTStr)]StringBuilder
ShortPath, [MarshalAs(UnmanagedType.U4)]int bufferSize);
4 I want to iterate through both files and folders in a given folder. Is
this possible?
Yes
string[] contents =
Directory.GetFileSystemEntries("folderName");
foreach(string s in contents)
Console.WriteLine(s);
5 My application requires a simple ini file. Is there a easy way to
implement this without using any parsing?
Yes. This may not be the most efficient way to read from a ini file but it
is a pretty good solution that is easy to maintain.
You can use a XML file to store your settings. Use a DataSet to read from
it. Consider a simple sample file, config.ini. It has three parameters
base_path, update_path and output_file. These will map to columns in the
settings datatable.
view config.ini
// add error handling
DataSet ds = new DataSet();
ds.ReadXml("config.ini", XmlReadMode.Auto);
DataTable table = ds.Tables["settings"];
DataRow row = table.Rows[0];
string baseFolder = (string)row["base_path"];
string updateFolder = (string)row["update_path"];
string outputFileName = (string)row["output_file"];
You can of course use XmlReader, XmlDocument etc to create and maintain more
complex ini files. But this is a quick way to maintain a simple property
set.
6 How can I access a webpage from a windows form?
Use the WebRequest class found in the System.Net namespace.
//create the request object
WebRequest req = WebRequest.Create(@"http://www.syncfusion.com");
//get the response and use the reponse
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string s = sr.ReadToEnd();
textBox1.Text = s;
7 I just want to read a text file into a string. Is there some simple
code for this?
The following code reads a text file into a string object. It doesn't get
any simpler than this. In production code always make sure that you handle
exceptions.
using System.IO;
....
// filePath should contain the complete path to a file.
StreamReader stream = new StreamReader(filePath);
fileText = stream.ReadToEnd();
stream.Close();
8 I just want to write a simple text file. Is there some simple code for
this?
It doesn't get any simpler than this. In production code always make sure
that you handle exceptions.
using System.IO;
....
// filePath has the complete path to the file
StreamWriter writer = new StreamWriter(filePath);
writer.Write(fileNewText);
writer.Close();
9 While deserializing how do I check whether a name is available in the
deserialized info?
This is usualy an issue when a newer version introduces newer names, then
the older version will not serialize property due to the absence of certain
names. For example, this code will fail, sometimes:
protected
MyClassConstructor(SerializationInfo info, StreamingContext context)
{
...
// This might fail if MyProp was added in a newer version and you are
serializing an older version.
this.MyProp = info.GetBoolean("MyProp");
}
To avoid such conflicts, you could insert version nos. into the serialized
info. and during deserialization check for a name only when a particular
version is being deserialized. Or you could insetad parse through the
available info in the SerializationInfo list as follows:
[C#]
protected MyClassConstructor(SerializationInfo info, StreamingContext
context)
{
foreach(SerializationEntry entry in info)
{
switch(entry.Name)
{
case "MyProp":
// This will make sure that older versions without the MyProp
name will also deserialize without any problems
this.MyProp = (bool)entry.Value;
break;
...
}
}
}
[VB.Net]
Protected MyClassConstructor(ByVal info As SerializationInfo, ByVal context
As StreamingContext) As Protected
Dim entry As SerializationEntry
For Each entry In info
Select Case entry.Name
Case "MyProp"
' This will make sure that older versions without the MyProp
name will also deserialize without any problems
Me.MyProp = (Boolean)entry.Value
Exit For
End Select
Next
End Function
10 How come some of the objects are not initialized during
deserialization?
This is possible in this case: Say your object graph contains an object A,
which has a reference to the object B. Then while deserializing A, the
reference B might not be initialized yet. This is because while
deserializing, references are deserialized one at a time and when A is
deserialized, B might not have been deserialized, yet. You should follow the
workaround as follows:
[C#]
protected MyCustomConstrucotr(SerializationInfo info, StreamingContext
context)
{
this.cachedRefToB = (B)info.GetValue("B", typeof(B));
// At this point cachedRefToB might not be initialized.
}
// But when this method gets called, after complete serialization, the
cachedRefToB will be initialized
void IDeserializationCallback.OnDeserialization(object sender)
{
// At this point cachedRefToB will be initialized.
}
[VB.Net]
protected MyCustomConstrucotr(ByVal info As SerializationInfo, ByVal context
As StreamingContext) As Protected
Me.cachedRefToB = CType(info.GetValue("B", Type.GetType(B)), B)
' At this point cachedRefToB might not be initialized.
End Function
' But when this method gets called, after complete serialization, the
cachedRefToB will be initialized
' Your class should implement IDeserializationCallback
Sub OnDeserialization(ByVal sender As Object) as
IDeserializationCallback.OnDeserialization
' At this point cachedRefToB will be initialized.
End Sub
|