Announcement

Collapse
No announcement yet.

Filecopy

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Filecopy


    I am having a problem with filecopy. It works most of the time.

    Code:
          If Len(Dir$(yigFile)) > 0 Then   
             printout "Delete: " & yigfile
             Kill yigFile
             If len(dir$(yigFile)) <> 0 Then
                printout "Error!! Kill FAILED!"
                printout "Err = " & Str$(Err)
             End If   
             Sleep 500
             If Len(Dir$(gameFile)) > 0 Then   
                printout "Rename " & gameFile & " As " & yigFile
                FileCopy gameFile, yigFile
                Sleep 500
                Kill gameFile
                Sleep 500
                If len(dir$(yigFile)) = 0 Then
                   printout "Error!! Rename FAILED!"
                   printout "Err = " & Str$(Err)
                End If
    *** Printout just prints a line to a log file
    The file names (gameFile and yigFile) are always the same.
    There is over 2 gigs of free disk space on the drive with the files and the files themselves are 50K to 1000K in size.

    The program works most of the time, but once in a while the message:

    Error!! Rename FAILED!
    Err = 0

    . . . shows up in the log file. The fails have happened on machines running Windows 95, Windows 98 and Windows NT.

    I was told that it is a timing problem, As in windows can sometimes delay the new file coming into "existance" so that Dir$() does not see it if called to quickly. That is why I added the sleeps.

    If I stop the program when the error hits and wait for the file to show up, it never does. Any guesses?

    Tim Wisseman


  • #2
    Tim,

    It may well be a timing problem, although my own personal experience (on NT) is the opposite: The file will exist before it is completely copied (only an issue with large files, and only if you're acessing the file from a process different from the one performing the copying, writing or whatever creates the file).

    Anyway, I'd suggest you use the NAME statement rather than copy the file. Why they called it NAME and not RENAME is beyond me, but that's not a PB issue (all BASICs I know call it NAME; PB is just following suit).

    Anyway, it has the format

    Code:
    NAME filespec1 AS filespec2
    and renames filespec1 to filespec2. Apart from beeing a lot faster and cleaner than copying the file, I also assume it will eliminate your problem. You still have to KILL filespec2 first!

    Ketil


    ------------------

    Comment


    • #3
      Tim,

      I think when a file is being moved or copied, Windows will show it as existing in the destination folder, even though it is actually still being assembled there. Not only does it get displayed in Explorer, but file system calls will show it as being there. The problem is of course, it isn't necessarily available for use.

      You don't say where gameFile is coming from. I suspect that in this line :

      If Len(Dir$(gameFile)) > 0 Then

      gameFile is still being assembled, so that the next line :

      FileCopy gameFile, yigFile

      will fail, and this is what you are seeing.

      Some while back I had a similar problem with a server system I built that posted small message files around. It worked beautifully ... until those files started coming across a WAN, whereupon I hit this same problem. My solution was to have the receiving code inspect the archive bit of the delivered file ; if it was set (as it will be automatically when a file is transferred), it doesn't touch the file. Once a file is delivered, delivering code then clears the file's archive bit. Receiving code sees this, and knows that the file is fully assembled and available for use. There's never been a problem with it since.

      'Hope this is useful -

      Regards,

      Paul
      Zippety Software, Home of the Lynx Project Explorer
      http://www.zippety.net
      My e-mail

      Comment


      • #4
        I prefer API CopyFile (very useful flag bFailIfExists)

        ------------------

        Comment


        • #5
          The problem most likely stems from how the O/S deals with "lazy commits" and is more prevalent when dealing with 'file server' - files that are physically stored on another PC.

          Briefly - the O/S allocates one thread to handle the data transfer and another thread to handle the DIR$ request - because Windows uses the "lazy commit" technique it is possible for the second thread to query the file system before the first thread does it's thing - for a spilt second there appears to be a missing file.

          This is a documented Windows behavior - try searching http://msdn.microsoft.com for "lazy commit".

          The workaround would be to retry the DIR$ after a short delay if it initially fails.


          ------------------
          Lance
          PowerBASIC Support
          mailto:[email protected][email protected]</A>
          Lance
          mailto:[email protected]

          Comment


          • #6
            I can not use NAME, because NAME can not work accross volumes and there will be cases that this code will need to reach across volumes (hard drives).

            I am trying your suggestion of the CopyFile API. I have removed the sleeps and switched from using FileCopy to using CopyFile API.

            It looks like it is working fine. Around 10000 test runs and no fails yet. The old code would never have done that. I will
            let the code run for a few days just to be sure.

            I thought that FileCopy used the CopyFile API. I guess they are very different after all.

            Looks like a great answer, thanks!

            Tim



            ------------------

            Comment


            • #7
              On OS newer than Win95 you can NAME across partitions.
              I had to implement "IsSameRoot" function to prevent
              Win98,NT4,NT5 to copy the file instead of renaming it.
              Obviously there are minor error in the description of
              the key-word NAME in the help/documentation files.

              ------------------
              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se



              [This message has been edited by Fred Oxenby (edited March 24, 2000).]
              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Comment


              • #8
                NAME can also be used to 'move' files across partitions and drives, but it cannot move directories between drives. Internally, NAME uses the MoveFile() API, so it is limited by what that API can provide.


                ------------------
                Lance
                PowerBASIC Support
                mailto:[email protected][email protected]</A>
                Lance
                mailto:[email protected]

                Comment


                • #9

                  I had a simular problem, but the answer was more
                  simple than proposed here!

                  You attempted to copy a file that is open or in use!

                  I'd start there!, which also goes hand in hand with
                  what Lance was talking about "lazy commit"

                  my $.02
                  Mike



                  ------------------
                  mwm
                  mwm

                  Comment


                  • #10
                    I had a problem a couple of years ago with a recurring file write
                    problem that did not show up on my own box but used to crash on
                    boxes with less memory. The utility wrote many files one after
                    the other to the same directory on a local machine.

                    I think Lance hit it on the head with the "lazy commits" as it
                    requires the use of buffering to make it work in the OS. My
                    problem was that the data sequence filled the cache and then
                    crashed. The solution I found was to flush the file to disk after
                    each write and the crashes never happened again.

                    It does slightly slow up the short term file transfers but it will
                    keep writing files over very large volumes of data. I don't know
                    if this is directly what your problem was but it is worth flushing
                    each file to disk to see if it does the job.

                    Regards,

                    [email protected]

                    ------------------
                    hutch at movsd dot com
                    The MASM Forum

                    www.masm32.com

                    Comment

                    Working...
                    X