У меня есть приложение, которое принимает фотографии с SD-карт. После того, как они будут скопированы, карты будут переформатированы и помещены обратно в камеры, и на них будет сохранено больше фотографий.
В настоящее время вместо использования PHP copy()
Функция, я делаю следующее (примерно):
$card = '/Volumes/SD_Card/DCIM/EOS/';
$files = scandir($card);
$target = '/Volumes/HARD_DRIVE/photos/';
foreach($files as $k => $file) {
if( strtolower ( pathinfo($file,PATHINFO_EXTENSION) ) == 'jpg') {
$img_data = file_get_contents($file);
$orig_md5 = md5($img_data);
$success = file_put_contents($target . $file, $img_data);
unset ($img_data);
if( $success != TRUE ) {
echo "an error occurred copying $file\n"; exit;
} elseif ( $orig_md5 != md5_file($target . $file) ) {
echo "an error occurred confirming data of $file\n"; exit;
} else {
echo "$file copied successfully.\n";
unlink ($img_data);
}
}
}
В настоящее время я делаю это таким образом, чтобы я мог сравнить хэши md5, чтобы убедиться, что копия является побитовым совпадением с оригиналом.
Мои вопросы:
1) будет использовать php copy()
быть быстрее? Я предполагаю, что это произойдет, потому что целевой файл не должен быть прочитан в память, чтобы проверить хэш md5.
2) ли copy()
сделать некоторую проверку хеша как часть функции, чтобы обеспечить целостность копии, прежде чем возвращать TRUE
/FALSE
?
Функция копирования PHP не только будет быстрее, но и использует буферы, чтобы избежать чтения всех предыдущих файлов в памяти, что является проблемой для больших файлов. Возвращаемое логическое значение предназначено только для успешной записи, вы можете положиться на него, но если вы хотите проверить использование хэша md5_file
вместо передачи контента в md5
потому что он оптимизирован таким же образом оптимизирован для памяти.
Однако, если вам нужно просто переименовать файл, то rename
намного лучше, это абсолютно мгновенно и надежно.
Нет, copy()
не выполняет никаких дополнительных проверок целостности, он предполагает, что API файловой системы операционной системы является надежным.
Вы могли бы использовать md5_file()
как на источник, так и на место назначения:
if (copy($source, $dest) && md5_file($dest) == md5_file($source)) {
echo "File copied successfully";
} else {
echo "Copy failed";
}
Обратите внимание, что ваша честность че
cks на самом деле не проверяет, правильно ли файл был записан на диск. Большинство операционных систем используют унифицированный буферный кеш, поэтому при вызове md5_file()
сразу после записи файла он будет получать содержимое файла из буферов ядра, а не с диска. На самом деле, возможно, что целевой файл еще даже не был записан на диск, он все еще находится в буферах ядра, которые ожидают очистки. PHP не имеет функции для вызова sync(2)
, но даже если бы он это сделал, он все равно считывал из буфера кеша, а не перечитывал с диска.
Таким образом, вы в основном зависит от операционной системы и аппаратного обеспечения, которое, как вы должны полагать, является надежным. Приложения, которые нуждаются в большем количестве проверок надежности, должны выполнять прямой ввод-вывод устройства, а не проходить через файловую систему.