Solved

How to make sure, file is copied completely ?

Posted on 2003-11-04
13
364 Views
Last Modified: 2010-05-01
I have 2 apps: 1 is writing to a certain folder and another is reading from it and moves files to some other folders. Right now, second does not start until 1-st finishes. Would that be possible to run them concurrently ? The main concern is what if 2-nd app gets a hold of a file that is not copied completely ??

Any recommendations would be greatly appreciated

-Al
0
Comment
Question by:AlexF777
  • 3
  • 2
  • 2
  • +5
13 Comments
 
LVL 35

Expert Comment

by:David Todd
Comment Utility
Hi,

The basic problem is some form of communication between the two programs, so that 1st can let second knwo that there is another file to copy.

My first thought is why two programs? Why not simply create a function that writes to both locatiosn at the same time - eliminating the need for the copy?

I'd be more likley to combine this into one program, which controls both the original write and the copying.

Regards
  David
0
 
LVL 7

Expert Comment

by:_agj_
Comment Utility
three options.

one, have the two programs in one, as david sez.

two, have the 2nd prgram called by the first, so that only after copying is it called.

three, have some status file, say "Status.txt" deleted at teh beginning of copying byt the first program and created when the copying is done.
Hence, 2nd program wud look for existence of this file before copying.
0
 
LVL 5

Expert Comment

by:jayeshshah
Comment Utility
in your app2 check if the files which are being copied are existing or not.

If they are existing then the files are copied or else they are either not copied or the copy process for the file is going on.

to check if the file is existing or not you can use the below condition

if (Dir(Str_Filename, vbNormal Or vbReadOnly Or vbHidden Or vbSystem Or vbArchive) <> "") = true then
   ''' file is existing
else
   '' file is not existing
end if

K'Regards

Jayesh
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 250 total points
Comment Utility
You can't simply check to see if the file exists because the sytem creates a 0k file and then writes to it.  

I came across this type of problem when I wrote a complex piece of software that delivered and received files via another ftp app I had written.  The solution I came up with was to embed the file size in the file name itself.  Then if an app wants to know if the file is done being sent/received/copied etc, it can compare the expected file size from the file name, to the actual file size on the system.  If the two don't match then the file is still being worked on.  Once you are sure no more operations are being performed on the file (because the file name size matches the acutal size), you can remove the file size from the file name and do with it what you want.

Idle_Mind
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
You could also simply rename files to be copied with a temporary extension and then copy/move the file and rename it back afterward.  Your second app just needs to ignore any file with your temporary extension because it knows it is being worked on.

Idle_Mind
0
 
LVL 17

Expert Comment

by:inthedark
Comment Utility
There is a simple solution here.  When you create a new file you create it on the same drive but in a temp folder.  When the generation of the file is complete you move the file to the pickup folder.  The file is not recopied, the folder is just udated.  In this way the 2nd app can't see the file until it is ready for collection.

Name TempFile As DestinationFile

Furthermore, there are some bugs in VB's Dir command which can manifest when you delete files withing a Dir loop.  You must have on error active whenever you use Dir().  To avoid the problem pickup all files before you start to process them.  If you don't do this your app may work for a few months but it will keep screwing up.

How to cause the problem:

sFile = Dir(sFolder + "*.*")
Do While Len(SFile)>0
       ProcessFile sFolder, sFile ' do whaterver you need
       sFile = Dir() ' Get next file ** warning this can fail but only once in a blue moon
Loop

How to avoide the problem:

Dim Attempts as Long
dim colFiles As Collection
Dim vFile as Variant

Restart:

If Attempts>5 Then
      msgbox "You have a problem"
      Exit Sub
End If

Attempts = Attempts +1
On Error GoTo Restart

Set colFiles = New Collection

sFile = Dir(sFolder + "*.*")
Do While Len(SFile)>0
    colFiles.Add sFile
    sFile = Dir()
Loop

On Error Goto xxxxx
' now files can be moved/deleted
For Each vFile in colFiles
       ProcessFile sFolder, vFile ' do whaterver you need
Next



0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 17

Expert Comment

by:inthedark
Comment Utility
Furthermore,  there is a registry setting which causes an exefile to be run whenever a new file is loaded into a folder.  This is used by the Windows 2000 SMTP maildrop folder.  If you have SMTP loaded onto your server your can find the details of the setting be searching registry for your maildrop folder.
0
 

Author Comment

by:AlexF777
Comment Utility
Idle_Mind,

                    As surprising as it may seem, it takes so long to rename the file when sending stuff across the pipe, that I would rather parse out the file's name to get the size than do the renaming thing.

 Thank You Everyone.
 -Al
0
 
LVL 1

Expert Comment

by:lmckenzie
Comment Utility
Perhaps I'm missing something with how you need this to work but here's another suggestion.  If you're using built in file routines (as opposed to the File System Object) to write the file, you can set the access level:

Dim intOutFileNo as integer

intOutFileNo = FreeFile()

Open "C:\MyFolder\MyFile.txt" For Output Lock Read As #intOutFileNo
'Write your data
Close #intOutFileNo
----------------------------------
In you file reading code, simply try to open the file.  If it's still being written to, you'll get an error 55 - File Already Open because of the read lock.  Just have your read code trap the error and try again later.  I don't have a network to test this on but it works locally.  Unfortunately the FSO doesn't include the lock syntax but I wouldn't be surprised if you still get an error if the file hasn't been closed by the writing application.  
0
 

Author Comment

by:AlexF777
Comment Utility
Very interesting!

          I really do not need to read any of the files processed ( just move them around depending on their
names ), however, I guess, I could try to use your technique just to make sure, file is available.

         Thank You,
         -Al
 
0
 
LVL 1

Expert Comment

by:lmckenzie
Comment Utility
Exactly.  The open attempt is just to check the status, even though you don't really need to read the contents. It does have the advantage of not requiring a second copy operation or messing with the file names.   I don't know of another way to do this.  Even the api function OF_EXIST
"Opens the file and then closes it. Used to test for a file’s existence."   You could also set up a message queu between the two applications and have the first send a message notifying the second as each file was written and available for moving.  In any case, I'd try to keep the two as independent as possible so that changing one doesn't necesaarily break the other.
0
 
LVL 17

Expert Comment

by:inthedark
Comment Utility
>  As surprising as it may seem, it takes so long to rename the file when sending stuff across the pipe, that I
 >  would rather parse out the file's name to get the size than do the renaming thing.

If the temporary file is saved on the save hard drive a file rename is instant.

0
 

Expert Comment

by:vb-signer
Comment Utility
In the my 'buttonpucher" VB-code for automatic printing postscript files from QuarkXPress I made comparsion between the present and past file sizes.

How it works. I need separately to print (write) QuarkXpress pages in the separate files. I cannot control inside the Quark becouse my app is just "buttonpusher" (use SendKeys statement). Therefore I should control for file existing and its size becouse it is not allowed to start print next page 2 (3, 4, 5, etc) until previous page is not done. I make this:

    For cw = 1 To 30 ' timeout
        fex = False ' fex - indicator
        myTimer 1  ' timeout 1 second
            If fso.FileExists(sf) Then
                Set fil = fso.GetFile(sf) ' if file created then object activated
                fex = True
                Exit For
            End If
    Next cw
    If fex = False Then MsgBox "Page " & sf & " was not printed to file!", vbCritical, "Error": Exit Sub

    pfs = 0 ' pfs - previous file size, long
    For cw = 1 To 60
        fex = False
        myTimer 2
        If fil.Size = pfs Then
            fex = True ' if in during 2 seconds file size not changed this means that write process is done
            Exit For
        End If
        pfs = fil.Size
    Next cw
    If fex = False Then MsgBox "Page " & sf & " was not printed to file!", vbCritical, "Error": Exit Sub

Private Function myTimer(myPause As Double) ' floating variable
Dim Start As Double
   Start = Timer
   Do While Timer < Start + myPause
        If endStop Then Exit Function
        DoEvents
   Loop
End Function

End of

Everything is works fine.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Vb.net Listview 9 76
Access 2016 VB code 9 86
VB6 Compile Compatibility Issue 4 26
MS Date Picker 64 bit 32 bit issue 12 42
There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now