главная продукты downloads форум тех. поддержка

 

Главная страница

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

 

e-mail:

 

bousoft@mail.ru