2013-06-17 4 views
0

나는 파일 업데이트를 수행하는이 코드를 사용하고 있습니다 : 어떻게하면 gridfs-stream으로 대체 할 수 있습니까?

app.post("/UploadFile", function(request, response) 
{ 
    var file = request.files.UploadedFile; 

    var name = request.param("Name"); 
    var componentId = request.param("ComponentId"); 

    console.log("Uploading: " + name); 

    var parameters = 
    { 
     filename: name, 
     metadata: 
     { 
      Type: "Screenshot", 
      ComponentId: componentId 
     } 
    }; 

    grid.files.findOne({ "metadata.ComponentId" : componentId }, function(error, existing) 
    { 
     console.log("done finding"); 
     if (error) 
     { 
      common.HandleError(error); 
     } 
     else 
     { 
      if (existing) 
      { 
       console.log("Exists: " + existing._id); 
       grid.remove({ _id: existing._id }, function(removeError) 
       { 
        if (removeError) 
        { 
         common.HandleError(removeError, response); 
        } 
        else 
        { 
         SaveFile(file, parameters, response); 
        } 
       }); 
      } 
      else 
      { 
       console.log("new"); 
       SaveFile(file, parameters, response); 
      } 
     } 
    }); 
}); 

function SaveFile(file, parameters, response) 
{ 
    console.log("Saving"); 
    var stream = grid.createWriteStream(parameters); 

    fs.createReadStream(file.path).pipe(stream); 
} 

은 기본적으로 내가 메타 데이터에 저장된 ID가있는 파일을 확인하고 있습니다. 존재하는 경우 저장하기 전에 삭제하고, 저장하지 않으면 저장합니다. 그것은 단지 산발적으로 작동하는 것 같습니다. 때때로 두 가지 오류가있는 동작을 보게됩니다.

파일은 삭제되지만 다시 생성되지는 않습니다.

파일이 업데이트 된 것처럼 보이지만 코드를 다시 호출하기 전에는 파일이 실제로 대체되지 않습니다. 그래서 기본적으로 대체 파일을 등록하기 위해 두 개의 파일 업로드를 수행해야합니다.

매우 스케치되어있어 작동 여부에 대한 패턴을 실제로 결정할 수 없습니다.

그래서 내가 잘못하고 있다고 가정합니다. gridfs-stream을 사용하여 파일을 대체하는 올바른 방법은 무엇입니까?

답변

0

그것은 당신이 제공 한 단지 코드에서 확실히 말할 어렵다 (즉, 당신은 app.postresponse이 궁극적으로 처리하는 방법을 표시하지 않습니다),하지만 난 확인하기 위해 여러 붉은 깃발을 참조하십시오

귀하 SaveFile 위의 함수는 파일과 gridFS 저장소 사이에 pipe을 설정 한 직후에 반환됩니다. 즉, 위의 코드를 호출 한 사람은 대용량 파일을 이동하거나 MongoDB 스토어가 상대적으로 느린 경우 파일이 MongoDB 인스턴스로 완전히 복사되기 전에 제어권을 회복 할 가능성이 높습니다 링크 (예 : 인터넷).

이러한 경우에는 pipe이 아직 실행 중이고 gridFS 저장소에 올바른 파일 복사본이 포함되기 전에 발신자가 직접 확인하는 것이 좋습니다.

다른 문제는 생성 한 스트림에서 생성 된 이벤트를 오류 검사 또는 처리하지 않는다는 것입니다.

수정 아마의 라인을 따라, 당신의 파이프에 적절한 이벤트 처리기를 만드는 작업이 포함됩니다 :

function SaveFile(file, parameters, response) 
{ 
    console.log("Saving"); 
    var stream = grid.createWriteStream(parameters); 

    pipe = fs.createReadStream(file.path).pipe(stream); 

    pipe.on('error', function (err) { 
     console.error('The write of " + file.path + " to gridFS FAILED: ' + err); 
     // Handle the response to the caller, notifying of the failure 
    }); 

    pipe.on('finish', function() { 
     console.log('The write of " + file.path + " to gridFS is complete.'); 
     // Handle the response to the caller, notifying of success 
    }); 
} 

전송이 완료 될 때까지 그 적절한 장소 있도록 'finish' 이벤트를 처리하는 함수는 호출되지 않습니다 app.post 요청에 응답합니다. 그 밖의 것이 없다면 오류 이벤트에서 유용한 정보를 얻어이를 더 진단하는 데 도움이됩니다.