Writes to read / write files

I have an application where I open a log file for writing. At some point in time (while the application is running) I opened the file with Excel 2003, which says the file should be read-only. It's okay with me.

But then my application threw this exception:

System.IO.IOException: The process cannot access the file because another process has locked part of the file.

I don't understand how Excel can lock the file (which my application has write access to) and force my application to not write to it!

Why did this happen?

(Note: I have not observed this behavior in Excel 2007.)

+1


source to share


4 answers


Here is the logger that will handle the synchronization. (You can change it according to your requirements)



using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Owf.Logger
{
    public class Logger
    {
        private static object syncContoller = string.Empty;
        private static Logger _logger;
        public static Logger Default
        {
            get
            {
                if (_logger == null)
                    _logger = new Logger();

                return _logger;
            }
        }

        private Dictionary<Guid, DateTime> _starts = new Dictionary<Guid, DateTime>();

        private string _fileName = "Log.txt";

        public string FileName
        {
            get { return _fileName; }
            set { _fileName = value; }
        }

        public Guid LogStart(string mesaage)
        {
            lock (syncContoller)
            {
                Guid id = Guid.NewGuid();

                _starts.Add(id, DateTime.Now);

                LogMessage(string.Format("0.00\tStart: {0}", mesaage));

                return id;
            }
        }

        public void LogEnd(Guid id, string mesaage)
        {
            lock (syncContoller)
            {
                if (_starts.ContainsKey(id))
                {
                    TimeSpan time = (TimeSpan)(DateTime.Now - _starts[id]);

                    LogMessage(string.Format("{1}\tEnd: {0}", mesaage, time.TotalMilliseconds.ToString()));
                }
                else
                    throw new ApplicationException("Logger.LogEnd: Key doesn't exisits.");
            }
        }

        public void LogMessage(string message)
        {
            lock (syncContoller)
            {
                string filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

                if (!filePath.EndsWith("\\"))
                    filePath += "\\owf";
                else
                    filePath += "owf";

                if (!Directory.Exists(filePath))
                    Directory.CreateDirectory(filePath);

                filePath += "\\Log.txt";

                lock (syncContoller)
                {
                    using (StreamWriter sw = new StreamWriter(filePath, true))
                    {
                        sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.sss") + "\t" + message);
                    }
                }
            }
        }
    }
}

      

+1


source


How do you write the journal? Do you have your own open / closed or use about thirty party product?



I believe the log is only opened and blocked when it writes something. Once the data is written, the code closes the file and, of course, releases the lock.

0


source


I believe I have a problem with the same type of blocking, reproduced like this:

  • User 1 opens an Excel2007 file from the network (read-write) (WindowsServer, version unkn).
  • User 2 opens the same Excel file (opens as ReadOnly, of course).
  • User 1 successfully saves the file many times

At some point user 1 UNABLE saves the file due to a "file locked" message. Close user User 2 ReadOnly version ... is locked and user 1 can now save again.

How can I open a file in ReadOnly mode by placing a lock on that file?

So it is an Excel2007 issue or a server issue.

0


source


This looks like a .NET issue. (Well, a mistake if you ask me).

I basically replicated the problem using the following multi-threaded code:

  Dim FS As System.IO.FileStream
  Dim BR As System.IO.BinaryReader

  Dim FileBuffer(-1) As Byte

  If System.IO.File.Exists(FileName) Then
   Try
    FS = New System.IO.FileStream(FileName, System.IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
    BR = New System.IO.BinaryReader(FS)

    Do While FS.Position < FS.Length
     FileBuffer = BR.ReadBytes(&H10000)

     If FileBuffer.Length > 0 Then
      ... do something with the file here... 
     End If
    Loop

    BR.Close()
    FS.Close()

   Catch
    ErrorMessage = "Error(" & Err.Number & ") while reading file:" & Err.Description
   End Try

      


Basically, the error is that trying to READ a file with all the different sharing modes (READ, WRITE, READ_WRITE) has absolutely no effect on file locking, no matter what you try; you will always end up with the same result: LOCKED and unavailable to any other user.

Microsoft doesn't even acknowledge this problem.

The solution is to use the internal Kernel32 CreateFile APIs to provide proper access, as this would ensure that the OS WILL RECEIVE your request when requested to read files with locked or denied access.

0


source







All Articles