Блокировка чтения / записи файла - PullRequest
1 голос
/ 02 декабря 2008

У меня есть приложение, в котором я открываю файл журнала для записи. В какой-то момент времени (пока приложение работает) я открыл файл в Excel 2003, в котором говорилось, что файл должен быть открыт только для чтения. Со мной все в порядке.

Но тогда моя заявка вызвала это исключение:

System.IO.IOException: процесс не может получить доступ к файлу, поскольку другой процесс заблокировал часть файла.

Я не понимаю, как Excel мог заблокировать файл (к которому мое приложение имеет доступ на запись) и заставить мое приложение не записывать в него!

Почему это произошло?

(Примечание. Я не наблюдал такого поведения в Excel 2007).

Ответы [ 4 ]

1 голос
/ 02 декабря 2008

Вот регистратор, который позаботится о синхронизации синхронизаций. (Вы можете изменить его в соответствии с вашими требованиями)

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);
                    }
                }
            }
        }
    }
}
0 голосов
/ 12 декабря 2009

Это похоже на проблему .NET. (Ну, ошибка, если вы спросите меня).

По сути, я повторил проблему, используя следующий многопоточный код:

  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

По сути, ошибка в том, что попытка ЧИТАТЬ файл со всеми различными режимами общего доступа (READ, WRITE, READ_WRITE) абсолютно не влияет на блокировку файла, независимо от того, что вы пытаетесь; вы всегда получите один и тот же результат: он заблокирован и недоступен для любого другого пользователя.

Microsoft даже не признает эту проблему.

Решение состоит в том, чтобы использовать внутренние API-интерфейсы CreateFile Kernel32 для обеспечения правильного доступа, поскольку это гарантирует, что ОС СЛУШАЕТ ваш запрос при запросе на чтение файлов с доступом к заблокированным или заблокированным общим доступом.

0 голосов
/ 06 ноября 2009

Я полагаю, у меня проблема с блокировками того же типа, воспроизводимая следующим образом:

  • Пользователь 1 открывает файл Excel2007 из сети (чтение и запись) (WindowsServer, версия unkn).
  • Пользователь 2 открывает тот же файл Excel (конечно, открывается как ReadOnly).
  • Пользователь 1 успешно сохраняет файл много раз

В какой-то момент Пользователь 1 не в состоянии сохранить файл из-за сообщения «файл заблокирован». Закройте версию ReadOnly для пользователя 2. Блокировка снята, и пользователь 1 теперь может сохранить ее снова.

Как открытие файла в режиме ReadOnly может заблокировать этот файл?

Итак, похоже, это проблема Excel2007 или проблема с сервером.

0 голосов
/ 02 декабря 2008

Как вы пишете журнал? У вас есть свой открытый / закрытый или какой-нибудь продукт тридцати вечеринок?

Мне кажется, что журнал открывается и блокируется только тогда, когда он что-то пишет. Как только запись данных завершена, код закрывает файл и, конечно, снимает блокировку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...