none
Backing up a file transparently to another program in .net RRS feed

  • Question

  • Howdy folks,

                  I'd like to read/backup a single file transparently to another program. Using fileshare.ReadWrite |fileshare.Delete I can handle every case  other than the other program trying to delete the file and recreate it while I'm reading it. (I'm ok with the file being crash consistent).

    I've had no real luck getting this to work until I heard of the Volume Shadow Service

    It looks like this thing would ask for applications to freeze for up to a minute and then store difs of the whole volume and in that way I could just access my log file.

    Theoretically that should work, but it feels like hitting a fly with a sledgehammer.

    I don't need a shadow of a whole volume, just a single file (or folder) and waiting 1 minute for a freeze is a bit slow (not to mention stopping the server from doing stuff)

    Is there a way to tell VSS to not shadow the whole volume, OR is there another way to transparently access a file without interrupting the other program?

    Thanks


    -Andrew



    Thursday, November 7, 2019 3:20 PM

All replies

  • Hi _Andrew_B,

     I'd like to read/backup a single file transparently to another program. Using fileshare.ReadWrite |fileshare.Delete I can handle every case  other than the other program trying to delete the file and recreate it while I'm reading it. (I'm ok with the file being crash consistent).

    Please provide more details:

    • What programming language is your project using? (C#?)
    • What is the purpose of your fileshare.ReadWrite | fileshare.Delete, you can use 0 instead, so you can monopolize the file and avoid other users to access and delete.
    • Or you can use LockFileLocks the specified file for exclusive access by the calling process.

    OR is there another way to transparently access a file without interrupting the other program?

    Do you mean that when you access a file, you don't want to influence other programs to use this file?

    Best regards,

    Strive


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, November 8, 2019 9:31 AM
  • Both programs are c#.

    There is a pre-existing program that writes logs to a file and deletes/recreates the file when the log gets too full.

    I'd like to be able to read in all the lines or copy this file without causing any interruption to the other program. Since as far as the other program is concerned this is just a simple logfile it doesn't do any locking, it just uses File.Delete, File.Writelines etc. I'd prefer not to modify this program.

    Monopolizing the file is the exact opposite of what I want it to do because that will cause an exception in the other program.

    Here is my exact scenario:

    Program A decides that it wants to trim the file:

    1. It reads all lines

    2. Deletes the file (File.Delete)

    3. Writes all current lines (File.Writelines)

    If it gets an exception it aborts the operation and does not retry.

    Program B which I am writing merely needs to grab that file without causing an exception in program A.

    If I open with fileshare.readwrite|fileshare.delete before Program A kicks off it's process:

    step 1 is fine

    step 2 is fine but the file is not deleted until program b's reader closes.

    step 3 throws exception in program a because it cannot create a file that already exists and it waiting to be deleted.

    ______________________

    Is there a way to setup my filestream in project B so that if anyone else tries to delete the file program B aborts the stream so the delete can instantly continue?

    Or is there a way to just use the Volume Shadow Service to backup just a single file? Stopping a bunch of server IO for a minute to get at a simple file is a bad idea.


    -Andrew

    Friday, November 8, 2019 5:21 PM
  • Hi _Andrew_B

    Since this issue is related to C#, this thread will be moved to C# forum for better support.

    Best regards,

    Strive


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 12, 2019 2:36 AM
  • Hi _Andrew_B, 

    According to your question, I make a test on my side, and Program A will check if a file is in use and make sure the file will be deleted.

    Here’s the code.

    Program A:

            static void Main(string[] args)
            {
                string path = @"file path";
                string[] text = File.ReadAllLines(path);
                FileInfo fileInfo = new FileInfo(path);
                while (IsFileLocked(fileInfo))
                {
                    Thread.Sleep(100);
                    Console.WriteLine("waiting...");
                }
                File.Delete(path);
                Console.WriteLine("deleted");
                string path2 = @"new file path"; 
                File.WriteAllLines(path2,text);
                Console.ReadLine();
            }
    
            protected static bool IsFileLocked(FileInfo file)
            {
                try
                {
                    using (FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
                    {
                        stream.Close();
                    }
                }
                catch (IOException)
                {
                    return true;
                }
                return false;
            }
    

    Progarm B:

            static void Main(string[] args)
            {
                string path = @"file path ";
                StreamReader sr = new StreamReader(path);
                string content = sr.ReadLine();
                Thread.Sleep(5000);
                sr.Close();
                Console.ReadLine();
            }

    Result of my test:

    Hope it can help you.

    Best Regards,

    Xingyu Zhao



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 12, 2019 7:40 AM
    Moderator
  • Xingyu,

           The whole point is that program A exists already and if at all possible I want to avoid modifying it.

    I want to read in the whole file to program B but at the same time I wish to cause no interruption to program A whether it is reading, writing or backing up the fine.

    Also even if I were to modify program A to use your suggested code, there would be a race condition if another process opened the file between closing it in

    IsFileLocked

    and deleting it in main.

           


    -Andrew

    Friday, November 15, 2019 8:18 PM
  • Hi _Andrew_B, 

    Thanks for your feedback.

    >> if anyone else tries to delete the file program B aborts the stream so the delete can instantly continue.

    It is hard to achieve this in C# without knowing how program B handle the file.

    I suggest you backup a file and make program B handle the backup file when the log gets too full, then program A delete the file.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 21, 2019 1:53 AM
    Moderator