Checking if file being accessed

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • tshad

    Checking if file being accessed

    I am trying to get access to a file that may still being written because the
    file is so large (7-10MB).


    I get an error:

    The process cannot access the file 'c:\TestDocs\XM LFiles\492172.X ML' because
    it is being used by another process


    This is when doing:

    CheckFileBeingU sed(xmlFile); // below - should give me up to 15
    seconds to finish writing the file
    fs = new FileStream(xmlF ile, FileMode.Open, System.IO.FileA ccess.Read);

    I tried the following routine which should get an error if still in use. It
    should run for 15 seconds (5 * 3), but even though the file is being
    accessed (which I know because the FileStream error happens after the call),
    it jumps out after the first call and never does go to the catch.

    Why is this?
    *************** *************** *************** *
    public bool CheckFileBeingU sed(string fileName)
    {
    // Check to see if file is in use. If very large it may be.

    bool inUse = false;
    for (int i = 0; i < 5; i++)
    {
    try
    {
    System.IO.File. Open(fileName, FileMode.Open,
    System.IO.FileA ccess.Read, FileShare.None) ;
    inUse = false;
    break;
    }
    catch (System.IO.IOEx ception exp)
    {
    inUse = true;
    System.Threadin g.Thread.Sleep( 3000); // Wait 3
    seconds and try again
    }

    }
    return inUse;
    }
    *************** *************** *************** *

    Thanks,

    Tom


  • Peter Duniho

    #2
    Re: Checking if file being accessed

    On Tue, 10 Jun 2008 17:48:27 -0700, tshad <tshad@dslextre me.comwrote:
    I am trying to get access to a file that may still being written because
    the
    file is so large (7-10MB).
    >
    >
    I get an error:
    >
    The process cannot access the file 'c:\TestDocs\XM LFiles\492172.X ML'
    because
    it is being used by another process
    >
    >
    This is when doing:
    >
    CheckFileBeingU sed(xmlFile); // below - should give me up to 15
    seconds to finish writing the file
    I don't understand this comment. The method you posted will not return
    until it's given up or has opened the file itself. Either way, how does
    that "give me up to 15 seconds to finish writing the file"?

    But, really...that doesn't matter. The important part is the rest of the
    discussion:
    fs = new FileStream(xmlF ile, FileMode.Open,
    System.IO.FileA ccess.Read);
    >
    I tried the following routine which should get an error if still in
    use. It
    should run for 15 seconds (5 * 3), but even though the file is being
    accessed (which I know because the FileStream error happens after the
    call),
    it jumps out after the first call and never does go to the catch.
    The file is being accessed because you just opened it.

    Hopefully, this helps illustrate the fallacy behind your approach. Don't
    open a file just to check to see if you can open. Just try to open it to
    _use_ it! In addition to the specific problem, the code you posted also
    won't work because between the time you think you've determined whether
    the file can be opened or not, the status of the file could change. Most
    unhelpfully, you could find the file available, but then it could become
    unavailable by the time you get to try to open it.

    If you want to include some sort of retry logic, so that you can
    gracefully deal with situations where something else might also be using
    the file, then do so. But once you've successfully opened the file, just
    use the opened file. Anything less is just pointless file-twiddling.

    Pete

    Comment

    • tshad

      #3
      Re: Checking if file being accessed

      Peter Duniho wrote:
      On Tue, 10 Jun 2008 17:48:27 -0700, tshad <tshad@dslextre me.com>
      wrote:
      >I am trying to get access to a file that may still being written
      >because the
      >file is so large (7-10MB).
      >>
      >>
      >I get an error:
      >>
      >The process cannot access the file 'c:\TestDocs\XM LFiles\492172.X ML'
      >because
      >it is being used by another process
      >>
      >>
      >This is when doing:
      >>
      > CheckFileBeingU sed(xmlFile); // below - should give me up to
      >15 seconds to finish writing the file
      >
      I don't understand this comment. The method you posted will not
      return until it's given up or has opened the file itself. Either
      way, how does that "give me up to 15 seconds to finish writing the
      file"?
      What is happening here is I am going to process this xml file that has lots
      of images in it and is very large.

      I am getting it too quick and I need to make the file has been completely
      written and closed (so I don't get the file being accessed message) before I
      start processing it.

      The 15 seconds (probably not enough in some cases) is the 3 second delay for
      5 loops. If I can access it right away, there would be no delay.

      The problem is that the file is being written to and I am trying to open it
      exclusively (FileShare.none ). If someone already has it open (only when
      being put in the folder), the this should give me an error and go to the
      catch area. I assume that is how this is supposed to work (got the code
      elsewhere).

      But as you say later, I should just put the loop and try/catch around the
      FileStream call, then when it becomes available I will already have it.
      >
      But, really...that doesn't matter. The important part is the rest of
      the discussion:
      >
      > fs = new FileStream(xmlF ile, FileMode.Open,
      >System.IO.File Access.Read);
      >>
      >I tried the following routine which should get an error if still in
      >use. It
      >should run for 15 seconds (5 * 3), but even though the file is being
      >accessed (which I know because the FileStream error happens after the
      >call),
      >it jumps out after the first call and never does go to the catch.
      >
      The file is being accessed because you just opened it.
      >
      Hopefully, this helps illustrate the fallacy behind your approach. Don't
      open a file just to check to see if you can open. Just try to
      open it to _use_ it! In addition to the specific problem, the code
      you posted also won't work because between the time you think you've
      determined whether the file can be opened or not, the status of the
      file could change. Most unhelpfully, you could find the file
      available, but then it could become unavailable by the time you get
      to try to open it.
      In my case, this wouldn't happen. I am watching the folder with a
      filewatcher Service and the only access would be the person dropping the
      file in my folder and my accessing it.
      >
      If you want to include some sort of retry logic, so that you can
      gracefully deal with situations where something else might also be
      using the file, then do so. But once you've successfully opened the
      file, just use the opened file. Anything less is just pointless
      file-twiddling.
      Probably right.

      I am still curious as to why the FileShare.none wouldn't create an error, if
      the file were still being written to.

      Thanks,

      Tom
      >
      Pete

      Comment

      • Peter Duniho

        #4
        Re: Checking if file being accessed

        On Tue, 10 Jun 2008 18:38:46 -0700, tshad <tshad@dslextre me.comwrote:
        >[...]
        >Most unhelpfully, you could find the file
        >available, but then it could become unavailable by the time you get
        >to try to open it.
        >
        In my case, this wouldn't happen.
        Says you.

        Unless you have somehow set the file permissions so that only your process
        has access to the file, you cannot assume in your code that the file will
        remain unavailable just because at some point in time it was.
        I am watching the folder with a
        filewatcher Service and the only access would be the person dropping the
        file in my folder and my accessing it.
        That may be the typical case, even by far. But you can't assume it.
        >If you want to include some sort of retry logic, so that you can
        >gracefully deal with situations where something else might also be
        >using the file, then do so. But once you've successfully opened the
        >file, just use the opened file. Anything less is just pointless
        >file-twiddling.
        >
        Probably right.
        >
        I am still curious as to why the FileShare.none wouldn't create an
        error, if
        the file were still being written to.
        It probably doesn't. The most likely reason that the file is inaccessible
        is because _your_ process has it open, due to the successful call to
        File.Open(). That's what I said before, and I still believe it. :)

        Pete

        Comment

        • =?ISO-8859-1?Q?Bj=F8rn_Brox?=

          #5
          Re: Checking if file being accessed

          tshad wrote:
          ....
          >
          I am getting it too quick and I need to make the file has been completely
          written and closed (so I don't get the file being accessed message) before I
          start processing it.
          >
          The simple solution to ensure that the file is complete before it is
          used is to store it with a temporary name and rename it to the final
          filename when finished.


          String tmp_filename = filename + ".tmp";
          ....
          if (File.Exists(fi lename))
          File.Delete(fil ename);
          File.Move(tmp_f ilename, filename);


          --
          Bjørn Brox

          Comment

          • Peter  Bromberg [C# MVP]

            #6
            Re: Checking if file being accessed

            I've seen this come up so many times. Congratulations on the first
            common-sense, simple and logical solution I believe I've seen.
            --Peter
            "Bjørn Brox" <bpbrox@gmail.c omwrote in message
            news:484f6dfd$1 @news.broadpark .no...
            tshad wrote:
            ...
            >>
            >I am getting it too quick and I need to make the file has been completely
            >written and closed (so I don't get the file being accessed message)
            >before I start processing it.
            >>
            The simple solution to ensure that the file is complete before it is used
            is to store it with a temporary name and rename it to the final filename
            when finished.
            >
            >
            String tmp_filename = filename + ".tmp";
            ...
            if (File.Exists(fi lename))
            File.Delete(fil ename);
            File.Move(tmp_f ilename, filename);
            >
            >
            --
            Bjørn Brox

            Comment

            • Peter Duniho

              #7
              Re: Checking if file being accessed

              On Thu, 12 Jun 2008 17:13:23 -0700, Peter Bromberg [C# MVP]
              <pbromberg@nosp amDood.yahoo.co mwrote:
              I've seen this come up so many times. Congratulations on the first
              common-sense, simple and logical solution I believe I've seen.
              Huh. Actually, Bjørn's proposal is reasonably common. But I had the
              impression from the OP that he doesn't have the luxury of picking the
              filename for whatever output's the file.

              That said, yes...I agree. If he _does_, the Bjørn's suggestion works the
              best. :)

              Pete

              Comment

              • tshad

                #8
                Re: Checking if file being accessed


                "Bjørn Brox" <bpbrox@gmail.c omwrote in message
                news:484f6dfd$1 @news.broadpark .no...
                tshad wrote:
                ...
                >>
                >I am getting it too quick and I need to make the file has been completely
                >written and closed (so I don't get the file being accessed message)
                >before I start processing it.
                >>
                The simple solution to ensure that the file is complete before it is used
                is to store it with a temporary name and rename it to the final filename
                when finished.
                >
                >
                String tmp_filename = filename + ".tmp";
                ...
                if (File.Exists(fi lename))
                File.Delete(fil ename);
                File.Move(tmp_f ilename, filename);
                >
                Not sure how this would work.

                Does it stop at the File.Exists until it is finished copying?

                Thanks,

                Tom
                >
                --
                Bjørn Brox

                Comment

                • tshad

                  #9
                  Re: Checking if file being accessed


                  "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
                  news:op.ucnusgi z8jd0ej@petes-computer.local. ..
                  On Thu, 12 Jun 2008 17:13:23 -0700, Peter Bromberg [C# MVP]
                  <pbromberg@nosp amDood.yahoo.co mwrote:
                  >
                  >I've seen this come up so many times. Congratulations on the first
                  >common-sense, simple and logical solution I believe I've seen.
                  >
                  Huh. Actually, Bjørn's proposal is reasonably common. But I had the
                  impression from the OP that he doesn't have the luxury of picking the
                  filename for whatever output's the file.
                  >
                  Correct.

                  I am not picking the file name.

                  The user is putting a file into a folder I am watching with my Windows
                  Service program. It can be anything.

                  As soon as my FileWatcher program sees the file, it starts to process it.

                  Thanks,

                  Tom
                  That said, yes...I agree. If he _does_, the Bjørn's suggestion works the
                  best. :)
                  >
                  Pete

                  Comment

                  • Peter Duniho

                    #10
                    Re: Checking if file being accessed

                    On Sat, 14 Jun 2008 22:51:01 -0700, tshad <tfs@dslextreme .comwrote:
                    I am not picking the file name.
                    >
                    The user is putting a file into a folder I am watching with my Windows
                    Service program. It can be anything.
                    >
                    As soon as my FileWatcher program sees the file, it starts to process it.
                    Well, I might not have been direct enough in previous posts. I can't tell
                    from your follow-up posts whether your question has been answered
                    satisfactorily or not.

                    The only right way to do this is to repeatedly attempt to open the file
                    with exclusive access unless you succeed. But don't do this the way
                    you've posted. Just open the file as you want to use it, and then if and
                    when you succeed, use it.

                    Depending on what latency is acceptable to you, you should probably put a
                    delay in between each attempt. Half a second to a second might be
                    reasonable. How you delay is up to you; I would use a timer, but if you
                    just want to let a thread sit and try over and over, with a call to
                    Thread.Sleep() in between, that'd be fine too.

                    Is there any other information you need?

                    Pete

                    Comment

                    Working...