Qn: Обход свойства блокировки файлов Windows - использование FileHandling в Java или C # - PullRequest
0 голосов
/ 24 февраля 2012

У меня возникла проблема при разработке программного обеспечения для моего бизнеса. Задача, которую я пытаюсь решить, заключается в том, что мне нужно обновить файл (.txt), пока к этому файлу постоянно обращается другая программа.

Конечная настройка такова: у меня будет запущено программное обеспечение, постоянно читающее содержимое файла канала (назовите его info.txt). У меня запущен другой скрипт, который постоянно обновляет файл фида (info.txt).

Я осознал серьезный конфликт при использовании файла после того, как реализовал вышеуказанные настройки. С работающим программным обеспечением (назовите его AAA) я не могу редактировать файл info.txt даже вручную. Я открываю файл info.txt, вносю изменения и нажимаю «Сохранить». Windows возвращает сообщение об ошибке: «Процесс не может получить доступ к файлу, поскольку он используется другим процессом». Если я пытаюсь удалить файл info.txt, появляется сообщение об ошибке: «действие не может быть завершено, поскольку файл открыт в AAA.exe». Когда я запускаю свой (java) скрипт, который постоянно обновляет info.txt, исключение ввода-вывода файла: java.io.FileNotFoundException: info.txt (процесс не может получить доступ к файлу, потому что он используется другим процессом)

Программное обеспечение AAA не так хорошо разработано. (Это чужое программное обеспечение для моего предприятия, поэтому я не могу изменить его поведение / исходный код.) То, как он обращается к файлам, полностью блокирует файл. Я подумал о том, чтобы временно указать ссылку на файл info.txt в файлах профиля программного обеспечения, чтобы разрешить временное редактирование, но этот подход не удался, потому что при работающем AAA (и мне это нужно) я не могу внести никаких изменений в любой файл. он использует.

Я консультировался с одним из основных разработчиков программного обеспечения AAA. Он признает, что это проблема сейчас, он исправит ее в следующем выпуске. Но пока что я хотел бы, чтобы все заработало. Он сказал мне, что программирует на .NET, и предоставил строку, которая может помочь мне обойти мою проблему:

FileStream fs = new FileStream (@ "info.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);

Предположительно, предоставляя эти аргументы, этот файловый поток разрешается совместно использовать как при записи, так и при чтении.

Я программист на Java, и у меня не было опыта работы с .NET. Тем не менее, я провел некоторое исследование и изучение, я понял, что его код - это синтаксис C #, который работает в среде CLR .NET. Я установил C # на своем компьютере и изучил какое-то учебное пособие для начинающих на C # и придумал следующий скрипт, надеясь решить мою проблему.

Если действительно так, что C # позволяет изменять свойство доступа к файлу на фундаментальном уровне, я бы открыл поток файлов info.txt, позволяя делиться им как с чтением, так и с записью. Как только я это сделаю, я могу запустить свой скрипт обновления info.txt, а затем запустить программное обеспечение AAA, которое продолжает обновлять info.txt.

Пытаясь добиться вышеописанной реализации, я придумываю скрипт на C #:

=============================================== = * * тысяча двадцать-один

using System;
using System.IO;

class CopyFeed
{
    static void Main()
    {
        string fileName1 = "info.txt";  
        string fileName2 = "info2.txt";


        FileStream fs = new FileStream(@fileName1, FileMode.OpenOrCreate,             FileAccess.Write, FileShare.ReadWrite);
        StreamWriter sw = null;

        // attempting to unlock part of the file, didn't work
        /*
        string contents = File.ReadAllText(@fileName2);
        fs.Unlock(0, contents.Length * 2);
        */

        while (true)
        {
            Console.WriteLine("Copying Feed...");

            string contents = File.ReadAllText(@fileName2);

            try
            {
                sw = new StreamWriter(fs);
                sw.Write(contents);
            }
            catch (Exception e)
            {
                Console.WriteLine("CopyFeed :: " + e.Message);
            }
            finally
            {
                if (sw != null)
                {

                    sw.Flush();
                    //sw.Close();

                }
            }

            Console.WriteLine("Pausing For 2 sec...");
            System.Threading.Thread.Sleep(2000);

        }



    }
}

=============================================== =

Возможно, у меня будет Java-скрипт, постоянно обновляющий info2.txt. Тогда у меня будет этот C # скрипт, постоянно копирующий весь контент info2.txt в info.txt. Я хочу обратиться за помощью к этому сообщению в двух аспектах:

  1. Вышеуказанный скрипт все еще глючит, потому что все, что он делает, это продолжает добавлять файл info.txt. Я хочу найти способ очистить содержимое файла в начале каждой итерации и просто скопировать содержимое файла2. Прямо сейчас, если я выполню скрипт, он со временем создаст бесконечно большой файл.

  2. Будет ли мое решение работать на основе приведенного выше описания? У меня есть лучший вариант? (при неизменном поведении программного обеспечения AAA) Есть ли способ обойти это?

  3. Могу ли я найти решение с использованием Java? есть ли в Java возможность обработки файлов, которая взаимодействует с системой Windows на более фундаментальном уровне и разблокирует файл?

Я работал над этой проблемой последние несколько дней и действительно застрял.Я искренне благодарю любого, кто предлагает какие-либо идеи!

Ответы [ 2 ]

0 голосов
/ 24 мая 2013

Несмотря на то, что ваш метод предотвратит возникновение исключения FileNotFoundException в вашей программе, вы должны учитывать возможность возникновения такого же исключения для других программ, которые пытаются получить доступ к файлу, который вы редактируете.использовать случай, и мы напрямую взаимодействуем с контролем версий вместо файла.Таким образом, мы можем объединить изменения, если выполняются одновременные правки.

Если вам неудобен такой подход, вам следует как минимум изменить свой код, чтобы он перехватывал System.IO.FileNotFoundExceptions вместо System.Exception.

0 голосов
/ 25 февраля 2012

Я не могу сказать вам, работает ли описанный вами метод для доступа к заблокированному файлу, поскольку у меня нет такого сценария, доступного для тестирования.

Что касается вашего вопроса 1.):

Вы можете очистить содержимое файла статическим методом File.WriteAllText (пространство имен System.IO ).Это эквивалент

string contents = File.ReadAllText(@fileName2);

в опубликованном вами коде C #.

Пример:

System.IO.File.WriteAllText(@"C:\Test\test.txt", "");

или лучше

System.IO.File.WriteAllText(@"C:\Test\test.txt", string.Empty);

В качестве альтернативы вы можете использовать метод setLength вашего FileStream со значением 0:

fs.SetLength(0);
...