我想知道是否有办法知道文件是否已完全下载。 即,一旦下载文件,是否有可能触发某些操作(如向服务器发送消息或警告用户等)。
可能在java,php。
谢谢。
答案 0 :(得分:3)
尽管有相反的评论,但可能,但它不适合胆小者,因为它需要一些HTTP协议知识以及对文件流的理解。
假设PHP ...
ignore_user_abort()
- 这将允许php脚本在用户关闭连接后继续运行Connection: close
标题 AND 一个Content-Length: 1234
标题,其中1234是所投放文件的大小。 fwrite
将文件流式传输到客户端,跟踪您输出的字节数。一旦输出字节数达到文件大小,就知道你已经完成了。客户端将关闭连接,但您的脚本将继续运行。但要小心,因为在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();
}
}