Jump to content

Can two processes (not same domain) read/write to a file without causing any data los

- - - - -

  • Please log in to reply
6 replies to this topic

#1
topgun_879

topgun_879

    Newbie

  • Members
  • PipPip
  • 10 posts
Hi all,

I have a question. Can two processes (not same domain) read/write to a file without causing any data lost. Wont be able to implement lock resouce because it's separate processes. And also assume mutex wasnt used at both processes.

1. Another OS specific que, when we mention file handle, does OS assign only one handle for each file - reflecting at abovementioned scenario.

Pls advice Gurus out thr. TQ in advance.

topgun

#2
Momerath

Momerath

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 242 posts
When I try to open a file in ReadWrite mode with two processes I get this:

Unhandled Exception: System.IO.IOException: The process cannot access the file 'D:\Visual Studio 2010\Projects\TestApp\TestApp\bin\Release\myfile.txt' because it is being used by another process.

#3
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
Both processes can write to the file at the same time if both of them have opened the file with FileShare.ReadWrite or FileShare.Write flag. But then data loss may occur if processes have not been synchronized, but rather tried to write data simultaneously. If both processes try to do append operation, data may be interlaced. Data may also be written over if processes use Seek operation without negotiating the offset, in which case they both can use the same seek offset and write over each other's data.

It is not advised to open file for writing and allow other processes to do the same. This means that normal operation is either to open file with FileShare.None (exclusive access) or FileShare.Read (allowing others to read what process is writing, but not to write at the same time).

#4
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts

Momerath said:

When I try to open a file in ReadWrite mode with two processes I get this:

Unhandled Exception: System.IO.IOException: The process cannot access the file 'D:\Visual Studio 2010\Projects\TestApp\TestApp\bin\Release\myfile.txt' because it is being used by another process.
You must use File.Open method which receives both FileAccess and FileShare flags, the latter one specifying what kind of lock is requested when opening the file. FileAccess flag says what you're planning to do with the file, and FileShare flag says what you're allowing others to do with the file while you're holding the lock.

#5
topgun_879

topgun_879

    Newbie

  • Members
  • PipPip
  • 10 posts
Thank you very much for your technical insight, Zohanh. This really makes sense now.

How about the OS file handle. Let 's assume two different processes have opened a single file. Does this means, OS allocated two different handles for the same file or just one used by both processes? Thank you in advance.

Rgds,
topgun

#6
topgun_879

topgun_879

    Newbie

  • Members
  • PipPip
  • 10 posts
Hi,

Looks like, no matter how, if one process is writing to a file, another process cannot access the file. Tried all FileMode and FileShare at both app (writter& reader), it is still failing with exception on the second process.

Can anyone suggest somehting for this problem. Thank you.

Rgds,
topgun

#7
zoranh

zoranh

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 207 posts
Here is the code which reads and writes to a file:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace Test
{

    class Program
    {

        static void Read(string path)
        {

            FileInfo fi = new FileInfo(path);
            FileSystemWatcher fsw = new FileSystemWatcher(fi.DirectoryName, fi.Name);
            _readingStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            _readingStream.Seek(0, SeekOrigin.End);

            fsw.Changed += new FileSystemEventHandler(FileChanged);
            fsw.NotifyFilter = NotifyFilters.LastWrite;
            fsw.EnableRaisingEvents = true;

            Thread.Sleep(60000);

        }

        static void FileChanged(object sender, FileSystemEventArgs e)
        {
            
            List<byte> rawData = new List<byte>();
            byte[] buffer = new byte[1024];

            int len = 0;

            do
            {
                
                len = _readingStream.Read(buffer, 0, buffer.Length);

                for (int i = 0; i < len; i++)
                    rawData.Add(buffer[i]);

            }
            while (len > 0);

            byte[] data = rawData.ToArray();
            char[] chars = UTF8Encoding.UTF8.GetChars(data);
            string text = new string(chars);

            Console.Write(text);

        }

        static void Write(string path)
        {


            while (true)
            {

                FileStream fs = File.Open(path, FileMode.Append, FileAccess.Write, FileShare.Read);

                int l = RNG.Next(70) + 1;
                StringBuilder sb = new StringBuilder();

                for (int i = 0; i < l; i++)
                    sb.AppendFormat("{0}", i % 10);

                sb.Append(Environment.NewLine);

                string line = sb.ToString();
                char[] chars = line.ToCharArray();
                byte[] bytes = UTF8Encoding.UTF8.GetBytes(chars);

                fs.Write(bytes, 0, bytes.Length);

                fs.Dispose();

                int pause = RNG.Next(1001);
                Thread.Sleep(pause);

            }


        }

        static void Main(string[] args)
        {

            string path = "file.txt";

            if (File.Exists(path))
                Read(path);
            else
                Write(path);

        }

        private static Random RNG = new Random();

        static FileStream _readingStream;

    }

}
Run multiple instances of this process. First instance will create the file named file.txt. Other instances will read from the same file. You'll see that all readers will print content of the file as it is written by the first instance.

See how the file has been opened by reader and how by the writer.

Before every run, delete file.txt.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users