我有一些代码,简化,看起来像:
$fout = fsockopen($host, 80); stream_set_timeout($fout, 10*3600); // 10 hours $fin = fopen($file, 'rb'); // not really a file stream, but good enough proxy here $readbytes = stream_copy_to_stream($fin, $fout); if(!$readbytes) die('copy failed');
但是,我有时会遇到以下类型的错误:
Notice: stream_copy_to_stream(): send of 952 bytes failed with errno=104 Connection reset by peer in ... Notice: stream_copy_to_stream(): send of 952 bytes failed with errno=32 Broken pipe in ...
检查$ readbytes不会发现错误。 我知道可以用复制的字节数来检查文件的总长度,但这只有在可以提前确定流的总长度时才有效。
由于这是随机发生的,我认为连接只是因为一些奇怪的原因被丢弃(但如果有人有任何建议来减少这种情况发生的可能性,我会全神贯注)。但能够知道转移是否完全成功是很好的。 无论如何没有检测到问题:
...或者可能使用缓冲的fread / fwrite循环,检查写入的字节长度,这里是最好的解决方案吗?
感谢。
答案 0 :(得分:3)
好的,所以这是我的流复制功能,尝试检测错误,但它似乎仍然失败(我认为fwrite意味着返回正确的字节数)
function stream_copy($in, $out, $limit=null, $offset=null) { $bufsize = 32*1024; if(isset($offset)) fseek($in, $offset, SEEK_CUR); while(!feof($in)) { if(isset($limit)) { if(!$limit) break; $data = fread($in, min($limit,$bufsize)); } else $data = fread($in, $bufsize); $datalen = strlen($data); $written = fwrite($out, $data); if($written != $datalen) { return false; // write failed } if(isset($limit)) $limit -= $datalen; } return true; }
在上面的函数中,即使显示错误,我仍然会返回'true'。
所以我只是想尝试挂钩PHP的错误处理程序。没有测试过以下内容,但我的猜测是应该工作
function stream_copy_to_stream_testerr($source, $dest) { $args = func_get_args(); global $__stream_copy_to_stream_fine; $__stream_copy_to_stream_fine = true; set_error_handler('__stream_copy_to_stream_testerr'); call_user_func_array('stream_copy_to_stream', $args); restore_error_handler(); return $__stream_copy_to_stream_fine; } function __stream_copy_to_stream_testerr() { $GLOBALS['__stream_copy_to_stream_fine'] = false; return true; }
丑陋,但我能看到的唯一解决方案。