2012-04-18 4 views
10

클라이언트 컴퓨터에서 서버로 청크 파일을 업로드하기위한 모듈을 구현 중입니다. 서버 측에서는 WCF Soap 서비스를 사용하고 있습니다.FileStream 잠금을 해제하려면 어떻게해야합니까?

파일을 청크로 업로드하기 위해 Microsoft http://msdn.microsoft.com/en-us/library/aa717050.aspx에서이 샘플을 구현했습니다. 간단한 시나리오에서 작업 할 수있게되어 파일을 청크로 업로드합니다. 이 청킹 모듈은 WSDualHttpBinding을 사용하고 있습니다.

특정 파일을 업로드하는 동안 어떤 이유 (사용자 선택, 기기 사용 중지 등)로 업로드 프로세스가 중지되는 경우 파일을 다시 업로드하는 기능을 구현해야합니다. 제 WCF 서비스에서

I 서버 측에서 파일 기록 처리 방법에있다 :

public void UploadFile(RemoteFileInfo request) 
{ 
FileInfo fi = new FileInfo(Path.Combine(Utils.StorePath(), request.FileName)); 

if (!fi.Directory.Exists) 
{ 
    fi.Directory.Create(); 
} 

FileStream file = new FileStream(fi.FullName, FileMode.Create, FileAccess.Write); 
int count; 
byte[] buffer = new byte[4096]; 
while ((count = request.FileByteStream.Read(buffer, 0, buffer.Length)) > 0) 
{ 
    file.Write(buffer, 0, count); 
    file.Flush(); 
} 
request.FileByteStream.Close(); 
file.Position = 0; 
file.Close(); 

if (request.FileByteStream != null) 
{ 
    request.FileByteStream.Close(); 
    request.FileByteStream.Dispose(); 
} 
} 

청킹 모듈 보내는 청크 함수 request.FileByteStream.Read (버퍼, 0, 버퍼있다. 길이)가 소모됩니다.

파일 스트림이 초기화 된 후 파일이 잠기지 만 (쓰기 용으로 파일 스트림을 초기화 할 때 정상적인 동작 임), 문제는 보내기/받기 프로세스가 수행되는 동안 업로드 프로세스를 중지한다는 것입니다 청크 모듈에서 사용하는 채널은 취소되지 않으므로 WCF 서비스는 전송 시간 초과가 만료 될 때까지 파일 전송을 계속 대기하므로 파일이 잠긴 상태로 유지됩니다 (시간 초과는 파일을 업로드해야하기 때문에 +2.5 GB). 다음 업로드에서 같은 파일을 업로드하려고하면 동일한 파일에 대해 파일 스트림을 다시 초기화 할 수 없으므로 WCF 서비스에서 예외가 발생합니다.

파일 잠금을 피하거나 제거하는 방법이 있는지 알고 싶습니다. 다음 번에 이전 파일 스트림이 이미 파일을 잠근 경우에도 동일한 파일을 다시 업로드 할 수 있습니다.

도움을 주시면 감사하겠습니다.

+0

여기에 어떤 용도로든 ['FileStream.Unlock'] (http://msdn.microsoft.com/en-us/library/system.io.filestream.unlock.aspx)이 있습니까? – Xenon

+0

SharingMode 매개 변수를 System.IO.FileShare.ReadWrite로 설정하여 FileStream 생성자를 사용할 수 있습니다. –

+0

이미 FileStream을 사용해 보았습니다.잠금을 해제하지만 이전 WCF 호출에서 이전 프로세스에 의해 파일이 잠겨서 문제가 해결되지 않습니다. – Fer

답변

1

저는 개인적으로 이런 종류의 해결책을 좋아하지 않습니다. 연결 유지는 이상적이지 않습니다.

예제를 사용하면 2.5GB 파일의 중간에 위치 할 수 있으며 프로세스가 중단 될 수 있습니다. 당신은 당신이 위에있는 상황에 처하게됩니다. 설상가상으로 이미 제출 된 모든 데이터를 다시 제출해야합니다.

블록을 직접 처리하고 동일한 파일 서버쪽에 추가하는 경로를 가겠습니다. 파일이 시작 중임을 나타내는 WCF 메서드를 호출하고 블록으로 데이터를 업로드 한 다음 업로드가 완료되면 다른 메서드를 호출합니다. 파일 이름이 고유하다고 확신하는 경우 단일 메소드 호출로이를 수행 할 수도 있습니다.

ulong StartFile(string filename) // This returns the data already uploaded 
void UploadFile(string filename, ulong start, byte[] data) 
void EndFile(string filename) // Just as a safety net 

당신은 (그것을 직접 귀하의 질문에 대답하지 않습니다) 제가 위에서 설명 된 경로를 이동하지 않으려면 위의 문제에 대한 간단한 해결책은 임시 파일을 사용하는 것입니다

뭔가처럼 이름을 입력하고 업로드가 완료되면 이름을 바꿉니다. 업로드가 완료되기 전에 서버의 응용 프로그램이 파일을 선택하지 못하게하려면이 방법을 실제로 채택해야합니다.

관련 문제