5

我知道这个标题有点奇怪,但我会到达那里。

我有一台连接在笔记本电脑上的相机。使用远程拍摄,当摄影师拍摄照片时,它会保存到笔记本电脑硬盘上的文件夹中。在文件夹上设置了一个 Automator (Mac OS X) 操作,每当出现新文件时,它都会调整其大小并使用 Transmit 将其推送到 FTP。

这就是代码的来源。

我有一个网页显示最近拍摄的照片。它使用 ajax 反复检查是否上传了新文件,如果有,则加载新照片并与旧照片交叉淡入淡出。这是页面上运行的 Javascript。

(function() {
  var delay, refreshLoop;

  // Alias to setTimeout that reverses the parameters, making it much cleaner in code (for CoffeeScript)
  delay = function(time, callback) {
    return setTimeout(callback, time);
  };

  // Function that drives the loop of refreshing photos
  refreshLoop = function(currentFolderState, refreshRate) {
    // Get the new folder state
    $.get("ajax/getFolderState.php", function(newFolderState) {
      // If the new folder state is different
      if (newFolderState !== currentFolderState) {
        // Get the newest photo 
        $.get("ajax/getNewestPhoto.php", function(photoFilename) {
          var img;
          // Create the new image element
          img = $('<img class="new-photo"/>')
            // Append the src attribute to it after so it can BG load
            .attr('src', "/events/mindsmack/booth/cinco-de-mindsmack-2012/" + photoFilename)
            // When the image is loaded
            .load(function() {
              // Append the image to the photos container
              $('#photos').append(img);
              // Crossfade it with the old photo
              $('#photos .current-photo').fadeOut();
              $('#photos .new-photo').fadeIn().removeClass("new-photo").addClass("current-photo");
            });
        });
      }
      // Wait for the refresh rate and then repeat
      delay(refreshRate, function() {
        refreshLoop(newFolderState, refreshRate);
      });
    });
  };

  // Document Ready
  $(function() {
    var refreshRate;

    // Load the first photo 
    $.get("ajax/getNewestPhoto.php", function(photoFilename) {
      $('#photos').append("<img src='/events/mindsmack/booth/cinco-de-mindsmack-2012/" + photoFilename + "' class='current-photo' />");
    });
    refreshRate = 2000;
    // After the timeout
    delay(refreshRate, function() {
      // Get the initial folder state and kick off the loop
      $.get("ajax/getFolderState.php", function(initialFolderState) {
        refreshLoop(initialFolderState, refreshRate);
      });
    });
  });

}).call(this);

这是在该 Javascript 中调用的两个 PHP 文件

获取文件夹状态.php

<?php

    $path = $_SERVER['DOCUMENT_ROOT'] . "/events/mindsmack/booth/cinco-de-mindsmack-2012/";

    // Get a directory listing of the path where the photos are stored
    $dirListing = scandir( $path );

    // Echo an md5 hash of the directory listing
    echo md5(serialize($dirListing));

获取最新照片.php

<?php

    $path = $_SERVER['DOCUMENT_ROOT'] . "/events/mindsmack/booth/cinco-de-mindsmack-2012/";

    // Get a directory listing of the path where the photos are stored
    $listing = scandir($path);

    $modTime = 0;
    $mostRecent = "";

    // Find the most recent file
    foreach ( $listing as $file ) {
        if ( is_file($path.$file) && $file !== ".DS_Store" && filectime($path.$file) > $modTime) {
            $modTime = filectime($path.$file);
            $mostRecent = $file;
        }
    }

    // Echo the most recent filename
    echo $mostRecent;

所有这些工作大多完美无缺。我相信,问题在于当文件正在上传时触发循环。偶尔会拍一张照片,它只会在页面中途显示。根本没有抛出错误,脚本继续运行得很好,并且图像文件实际上以该状态缓存,让我相信我的代码正在捕获正在进行的文件上传并且只显示文件的一部分那一刻已经上传。

如果我需要为了克服这个问题而改变我的解决方案,我不介意改变我的解决方案,我只是不确定该怎么做。

编辑

根据以下建议之一,我在 getNewestPhoto.php 中添加了代码,用于检查照片的文件大小,稍等片刻,然后再次检查。如果它们不同,它会返回并再次检查,直到文件大小相同。我希望这会捕获正在上传的文件,因为文件大小会在循环之间发生变化,但即使照片出现部分渲染,文件大小检查也没有捕获它。

这是我添加的代码

$currFilesize = filesize($path . $mostRecent);
$newFilesize;

while ( true ) {
    sleep(.5);
    $newFilesize = filesize($path . $mostRecent);

    if ( $newFilesize == $currFilesize) {
        break;
    }
    else {
        $currFilesize = $newFilesize;
    }
}

我在想(通过另一个建议)我需要在上传时添加某种锁定文件,以阻止代码刷新照片并在上传完成后被删除,但看到我没有运行任何类型的网络计算机上的服务器连接到相机,我不知道如何做到这一点。我很乐意提出建议。

4

2 回答 2

3

有很多方法可以解决这个问题,最比我要建议的要好。然而,我认为最简单和最快的解决方案是将 FTP 传输到 tmp 目录,并在传输完成后触发文件移动到生产目录。您当地的自动化工作在处理传输时是否有这样的机制?

于 2012-04-26T19:17:47.687 回答
1

我会让 PHP 脚本以(小)延迟循环检查文件大小,如果匹配则输出文件。否则,循环直到它完成。

于 2012-04-26T19:17:38.863 回答