Wednesday 25 November 2015

Locking and unlocking specific bytes of a file in C#

The following code shows a program that can lock and unlock specific bytes of file in C# using FileStream::Lock and FileStream::Unlock in System.IO. To test out that locking can protect designated bytes of a file, start up multiple instances of the program and try writing to the file after it has been locked. This will protect the file to be modified by other processes, which is handy if you want to ensure data integrity of files your system or application uses and expect to have a given contents and format. FileStream class allows us to work on files on a byte level and do detailed I/O operations on files in .NET.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestOutFileLocking
{

    class FStreamLock
    {

        static void Main(string[] args)
        {
            var uniEncoding = new UnicodeEncoding();
            string lastRecordText = "The last processed record number was: ";
            int textLength = uniEncoding.GetByteCount(lastRecordText);
            int recordNumber = 13;
            int byteCount = uniEncoding.GetByteCount(recordNumber.ToString());
            string tempString;

            using (var fileStream = new FileStream("Test#@@#.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //Write the original file data. 
                if (fileStream.Length == 0)
                {
                    tempString = lastRecordText + recordNumber.ToString(); 
                    fileStream.Write(uniEncoding.GetBytes(tempString), 0, uniEncoding.GetByteCount(tempString));
                }

                //Allow the user to choose the operation. 
                char consoleInput = 'R'; 
                byte[] readText = new byte[fileStream.Length];
                while (consoleInput != 'X')
                {
                    Console.Write("\nEnter 'R' to read, 'W' to write, 'L' to " + "lock, 'U' to unlock, anything else to exit: ");

                    if ((tempString = Console.ReadLine()).Length == 0)
                    {
                        break;
                    }
                    consoleInput = char.ToUpper(tempString[0]);

                    switch (consoleInput)
                    {
                        //Read data from the file and 
                        //write it to the console 
                        case 'R':
                            try
                            {
                                fileStream.Seek(0, SeekOrigin.Begin);
                                fileStream.Read(readText, 0, (int) fileStream.Length);
                                tempString = new string(uniEncoding.GetChars(readText, 0, readText.Length));
                                Console.WriteLine(tempString);
                                recordNumber = int.Parse(tempString.Substring(tempString.IndexOf(':') + 2)); 

                            }
                            //Catch the IOException generated if the 
                            //specified part of the file is locked. 
                            catch (IOException e)
                            {
                                Console.WriteLine("{0}: The read " +
                                 "operation could not be performed " +
                                 "because the specified part of the " +
                                 "file is locked.",
                                 e.GetType().Name);
                                
                            }

                            break;

                            //Update the file. 
                        case 'W':

                            try
                            {
                                fileStream.Seek(textLength, SeekOrigin.Begin);
                                fileStream.Read(readText, textLength - 1, byteCount);
                                tempString = new string(uniEncoding.GetChars(readText, textLength - 1, byteCount));
                                recordNumber = int.Parse(tempString) + 1;
                                fileStream.Seek(textLength, SeekOrigin.Begin);
                                fileStream.Write(uniEncoding.GetBytes(recordNumber.ToString()), 0, byteCount);
                                fileStream.Flush(); 
                                Console.WriteLine("Record has een updated.");
                            }
                            catch (IOException e)
                            {
                                Console.WriteLine(
                                    "{0}: The write operation could not " +
                                    "be performed because the specified " +
                                    "part of the file is locked.",
                                    e.GetType().Name);
                            } //try-catch 
                            break;

                            //Lock the specified part of the file. 
                        case 'L':

                            try
                            {
                                fileStream.Lock(textLength - 1, byteCount);
                                Console.WriteLine("The specified part " + "of file has been locked.");
                            }
                            catch (IOException err)
                            {
                                Console.WriteLine("{0}: The specified part of file is" + " already locked.", err.GetType().Name);
                            } //try-catch 
                            break; 

                        case 'U':
                            try
                            {
                                fileStream.Unlock(textLength - 1, byteCount);
                                Console.WriteLine("The specified part of file has been unlocked.");

                            }
                            catch (IOException err)
                            {
                                Console.WriteLine("{0}: The specified part of file is " + "not locked by the current prcess.", err.GetType().Name);
                            }
                            break; 

                        default:
                            consoleInput = 'X';
                            break; 

                    } //switch 

                }

            } //using 



        }

    }

}


Thursday 12 November 2015

Reading a text file in VB6 and putting the contents into an array

VB6 or Visual Basic 6.0 is not used in many new projects, as it is replaced by .NET. But sometimes you are assigned at work to read and further develop or migrate Legacy code. Let's look at some simple VB6 code. We first read the contents of a file and put each line into a string array. Then we add the items to a listbox control.

Private Sub Command3_Click()

 Dim someFileHandle As Integer
 Dim fileName As String
 Dim someStrings() As String
 
 someFileHandle = FreeFile

 fileName = App.Path + "\fox.txt"
 
 ReDim someStrings(1000) As String

 Open fileName For Input As #someFileHandle
 
 Dim lineNo As Integer
 
 Do Until EOF(someFileHandle)
  Input #someFileHandle, someStrings(lineNo)
  lineNo = lineNo + 1
 Loop
 
 ReDim Preserve someStrings(lineNo - 1) As String
  
 List1.Clear
  
 For x = 0 To lineNo - 1
  List1.AddItem someStrings(x)
 Next x

End Sub


First we get a file handle to the file we want to open. We declare an integer and use the FreeFile method to get a filehandle. We then use the Open function to open a file and assign the file handle. Note the use of the pound sign (#) here. We also declare a large string array, which is one dimensional. We use the ReDim Preserve Method to resize the array to save some memory space and preserve the content. We use the Input Method to put each line into an array element before this is done. Note the use of EOF here. We finally loop through the array and add each array item to a listbox control. So now you should have some basic overview how you can read a file in VB6 into an array structure and loop through its content. How neat is that!

Friday 30 October 2015

Creating a socket-based echo server and client

Sockets in C# are flexible and efficient way of creating communication between a client and server. It supports many protocols and the code below shows one of the simplest scenarios for using Sockets - an echo server and client. Note that the code below will target TCP and Ipv4 protocol. Many users today have got a Ipv6 and/or Ipv4 address assigned.

Socket-based server

Create a new Console Application in Visual Studio and insert the following code into the Program.cs file.

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SynchronousSocketServer
{

    public class SynchronousSocketServer
    {

        //Incoming data from the client. 
        private static string _data;

        public static void StartListening()
        {
            //Data buffer for incoming data. 
            // ReSharper disable once RedundantAssignment

            //Establish the local endpoint for the socket.
            //Dns.GetHostName returns the name of the host running the application
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList.First(a =< a.AddressFamily == AddressFamily.InterNetwork);
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11004);

            //Create a TCP/IP socket 
            var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //Bind the socket to the local endpoint and listen for incoming connections 
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(10);

                //Start listening for connections 
                while (true)
                {
                    Console.WriteLine("Waiting for connection ...");
                    //Program is suspended while waiting for an incoming connection. 
                    Socket handler = listener.Accept();
                    _data = null;

                    //An incoming connection needs to be processed. 
                    while (true)
                    {
                        var bytes = new byte[1024];
                        int bytesRec = handler.Receive(bytes);
                        _data += "\n" + Encoding.Unicode.GetString(bytes, 0, bytesRec);
                        if (_data.IndexOf("<EOF>", StringComparison.Ordinal) > -1)
                        {
                            break;
                        }
                        //Show the data on the console. 
                        byte[] msg = Encoding.Unicode.GetBytes(_data);
                        handler.Send(msg);
                    }

                    Console.WriteLine("Text received: {0}", _data);

                  
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(err.ToString());
            } //try-catch 

            Console.WriteLine("\nPress ENTER to continue ...");
            Console.Read();
        }

        // ReSharper disable once UnusedParameter.Local
        static int Main(string[] args)
        {
            StartListening();
            return 0;
        }

    }

}

Socket-based client

Create a new Console application in Visual Studio. Add the following code into the Program.cs file:

using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SynchronousSocketClient
{

    public class SynchronousSocketClient
    {

        public static void StartClient()
        {
            //Data buffer for incoming data. 
            byte[] bytes = new byte[1024];

            //Connect to a remote device. 
            try
            {
                //Establish the remote endpoint for the socket
                //This example uses port 11000 on the local computer 
                IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ipAddress = ipHostInfo.AddressList.First(a =< a.AddressFamily == AddressFamily.InterNetwork);
                IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, 11004);

                //Create a TCP/IP socket. 
                var sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //Connect the socket to the remote endpoint. Catch any errors. 
                try
                {
                    sender.Connect(remoteEndPoint);

                    Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint);

                    while (true)
                    {
                        Console.WriteLine("Enter text, type <EOF> to exit:");

                        //Encode the data string into a byte array 
                        string enteredText = Console.ReadLine() ?? "<EOF>"; 
                        byte[] msg = Encoding.Unicode.GetBytes(enteredText);

                        //Send the data through the socket. 
                        int bytesSent = sender.Send(msg);
                        Console.WriteLine("Sent {0} bytes over the network", bytesSent);

                        //Receive the response from the remote device. 
                        int bytesReceived = sender.Receive(bytes);
                        Console.WriteLine("Echoed test = {0}", Encoding.Unicode.GetString(bytes, 0, bytesReceived));

                        if (enteredText.IndexOf(">EOF<", StringComparison.CurrentCultureIgnoreCase) < -1)
                        {
                            break;
                        }

                    }

                    //Release the socket. 
                    sender.Shutdown(SocketShutdown.Both);
                    sender.Close();
                }
                catch (ArgumentNullException err)
                {
                    Console.WriteLine("ArgumentNullException : {0}", err.Message);
                }
                catch (SocketException err)
                {
                    Console.WriteLine("SocketException : {0}", err.Message);
                }
                catch (Exception err)
                {
                    Console.WriteLine("Exception : {0}", err.Message);
                }

            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            } //try-catch 

        }

        // ReSharper disable once UnusedParameter.Local
        static int Main(string[] args)
        {
            StartClient();
            return 0;
        }

    }

}