3

I have a directory on a remote machine in which my clients are uploading (via different tools and protocols, from WebDav to FTP) files. I also have a PHP script that returns the directory structure. Now, the problem is, if a client uploads a large file, and I make a request during the uploading time, the PHP script will return the file even if it's not completely uploaded. Is there a way to check whether a file is completely uploaded using PHP?

Rad'Val
  • 8,895
  • 9
  • 62
  • 92

3 Answers3

6

Setup your remote server to move uploaded files to another directory, and only query the directory files are moved to for files.

AFAIK, there is no way (at least cross-machine) to tell if a file is still being uploaded, without doing something like:

  1. Query the file's length
  2. Wait a few seconds
  3. Query the file's length
  4. If it's the same, its possibly completed
Nahydrin
  • 13,197
  • 12
  • 59
  • 101
  • +1 for logic, but even that makes sense, what is optimal time period for checking file-size. If uploader has connection problems that may cause significant delays during file upload, which means that file may have same size for a period of 5,6,10 seconds or more. In case of large files and slow upload speed this cant be good solution because you cant wait for hours to see if it's finished or not. **There is no way** is probably the best answer. – Wh1T3h4Ck5 Mar 29 '12 at 16:10
  • True, that's why I offered a workable solution as opposed to checking file size. At least this way the OP can make a decision based on what he wants to do. – Nahydrin Mar 29 '12 at 16:12
  • I would not rely on a file size check, since that meta data could be cached in the operating system, and a temporary network stall would fool your check. Network connections can stall for many seconds, in some situations even minutes. – Alfred Godoy Mar 29 '12 at 23:41
1

Most UNIX/Linux/BSD-like operating systems has a command called lsof (lsof stands for "list open files") which outputs a list of all currently open files in the system. You can run that command to see if any process is still working with the file. If not, your upload has finished. In this example, awk is used to filter so only files will show that are open with write or read/write file handlers:

if (shell_exec("lsof | awk '\$4 ~ /.*[uw]/' | grep " . $uploaded_file_name) == '') {
    /* No file handles open for this file, so upload is finished. */
}

I'm not very familiar with Windows servers, but this thread might help you to do the same on a Windows machine (if that is what you have): How can I determine whether a specific file is open in Windows?

Community
  • 1
  • 1
Alfred Godoy
  • 1,045
  • 9
  • 19
  • Sorry, forgot to mention, I'm on Linux, and will always be (not a problem of portability). This sounds great! Thanks! Will try it tomorrow. – Rad'Val Mar 29 '12 at 23:44
  • The problem with this is that it counts any access to the file, upload, download etc. I guess it could be updated to look only for upload, but it depends on how the file is accessed (webdav, ftp, ssh etc) – Rad'Val Apr 03 '12 at 11:46
  • Well, yes. However, you could use awk to only show those files that are open with write or read/write file handlers. This way, reads will not disturb you. Editing the answer... – Alfred Godoy Apr 08 '12 at 21:06
0

I would think that some operating systems include a ".part" file when downloading a file, so there may be a way to check for the existence of such a file. Otherwise, I agree with Brian's answer. If you were using the script on the same system it is simple enough to tell using move_uploaded_file()'s return if it was being uploaded by a PHP script, but it does become a challenge pulling from a remote directory that can be added to with different protocols.

Demonslay335
  • 776
  • 7
  • 17