用于了解文件是否已下载的代码

时间:2012-08-09 16:42:12

标签: java php file triggers download

我想知道是否有办法知道文件是否已完全下载。 即,一旦下载文件,是否有可能触发某些操作(如向服务器发送消息或警告用户等)。

可能在java,php。

谢谢。

3 个答案:

答案 0 :(得分:3)

尽管有相反的评论,但可能,但它不适合胆小者,因为它需要一些HTTP协议知识以及对文件流的理解。

假设PHP ...

  1. 通过PHP脚本运行文件下载 - 即不要让Web服务器直接从磁盘提供文件,让php脚本返回它。
  2. 告诉PHP脚本ignore_user_abort() - 这将允许php脚本在用户关闭连接后继续运行
  3. 发送Connection: close标题 AND 一个Content-Length: 1234标题,其中1234是所投放文件的大小。
  4. 使用fwrite将文件流式传输到客户端,跟踪您输出的字节数。一旦输出字节数达到文件大小,就知道你已经完成了。客户端将关闭连接,但您的脚本将继续运行。
  5. 执行您想要通知自己的任何内容,或者下载成功完成的数据库或文本日志文件。
  6. 但要小心,因为在Web SAPI中,您可以轻松地在PHP的最大时间限制内运行。


    更新:

    值得一提的是,如果你做这样的事情,你还应该在输出循环中添加一个检查connection_aborted,这样如果客户端在完成传输之前中止连接,则不会继续流输出。这应该是常识,但不要说我没有警告你。

答案 1 :(得分:0)

只需通过phpscript发送文件.. 例如http://exmaple.com/download.php?filename=some_filename.txt

$file=$_GET['filename'];
if (file_exist($file)){
 send_message_to_somebody(); //DO what ever you want here and then

 $mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $file);
 header("Content-Type: " . $mime);
 header("Content-Transfer-Encoding: binary");
 header('Accept-Ranges: bytes');
 header('Content-Disposition: attachment; filename="' .  basename($file).'"');
 header('Content-Length: ' . filesize($file));
 readfile($file);
}

答案 2 :(得分:0)

在数据库中写入信息,如果下载被取消/中止,像“is_downloaded”这样的列将为0,而不是1 ...描述不佳,没有时间。

这里重要的是 _destruct(),这是下载完成的触发器。

<?php

class Download
{
  protected $file;
  private $session;
  private $_last_insert_id;

  public function __construct($file, $session) 
  {
        $this->file = $file;
        $this->session = $session;
  }

  public function send()
  {

        $info = pathinfo($this->file);

        $query = DB::insert('downloads', array('user_id', 'file', 'path', 'start'))
        ->values(array($this->session->get('id'), $info['basename'], $this->file, DB::expr('NOW()')))
        ->execute();

        $this->_last_insert_id = $query[0];

        $this->session->set('downloading', 1);

        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.$info['basename'].'"');
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($this->file));

        readfile($this->file);
  }

  public function __destruct()
  {
    $aborted = connection_aborted();
    $this->session->set('downloading', 0);
    $query = DB::update('downloads')->set(array('stop' => DB::expr('NOW()')))->where('id', '=', $this->_last_insert_id)->execute();
  }

}