2016-06-25 12 views
-3

問題があります。サーバーからファイルを取得しても、ファイルがダウンロードされても、「このファイルは別のアプリケーションで使用されています」というエラーメッセージが表示されます。デルファイによるソケットファイル転送ファイルロックの問題

編集:申し訳ありませんがコードが見つかりませんでした。これはサーバー部分です。私は起動後にこのメソッドを実行しています。クライアントからのコマンドを待ちます。 gotoはラベルです。ジョブ(「ファイル開始」など)が完了したら、クリーンでフリーな接続を行います。これはマルチスレッドソケットアプリケーションです。ファイルの一部をダウンロードするまで繰り返します。私は説明することを願っています。

私のコード

procedure ConnectionWorker(P: Pointer); 
label cleanup; 
Var 
    sData1: TStringDYNArray; 
    cSock: TClientSocket; 
    scHost, scSendData, scFirstData, scFullData:String; 
    sBuff, sString:String; 
    bPackInfos:TPacketInformation; 
    scByte, sComm:Byte; 
    sBitMap:TBitmap; 
    sJPEG:TJPEGImage; 
    fFile:TFileStream; 
    scPort,lRecvLen, cRead, x,y:Integer; 
    arrBuffer:array[0..1000] of Byte; 
    bBuff:array[0..4095] of Byte; 
    eRatio:Extended; 
    sFirstCap, sDifCap, sSecondCap, sCompStream:TMemoryStream; 
    pCompStream:TCompressionStream; 
    cThread, cKillThread:Cardinal; 
Begin 
    scHost := PInfo(P)^.scHost; 
    scSendData := PInfo(P)^.scData; 
    scPort := PInfo(P)^.scPort; 
    scByte := PInfo(P)^.scPackHead; 
    sFirstCap := TMemoryStream.Create; 
    sSecondCap := TMemoryStream.Create; 
    cSock := TClientSOcket.Create; 
    cSock.Connect(scHost,scPort); 
    if cSock.Connected then begin 
    scFirstData := scSendData; 
    If SendPacket(cSock,scByte, scFirstData) then begin 
     repeat 
     scFullData := ''; 
     ZeroMemory(@arrBuffer[0], 1001); 
     lRecvLen := cSock.ReceiveBuffer(arrBuffer[0],1001); 
     if cSock.Connected = false then break; 
     SetLength(sBuff,lRecvLen); 
     MoveMemory(@sBuff[1],@arrBuffer[0],lRecvLen); 
     scFullData := scFullData + sBuff; 
     repeat 
      bPackInfos := VerifyPacket(scFullData); 
      scFullData := bPackInfos.PacketLeft; 
      sString := bPackInfos.PacketCommand; 
      sComm := bPackInfos.PacketByte; 
      if bPackInfos.PacketFinished = False then 
      break; 
      case sComm of 

      PACK_QUERYCOMPRESSEDFILE: 
       begin 
       if FileExists(sString) then begin 
        try 
        sFirstCap.LoadFromFile(sString); 
        sFirstCap.Position := 0; 
        sCompStream := TMemoryStream.Create; 
        pCompStream := TCompressionStream.Create(clMax,sCompStream); 
        pCompStream.CopyFrom(sFirstCap, sFirstCap.Size); 
        pCompStream.Free; 
        sString := ''; 
        SetLength(sString,sCompStream.Size); 
        SendPacket(cSock,PACK_COMPRESSEDTRANSFERFILE,IntToStr(sCompStream.Size)); 
        sCompStream.Position := 0; 
        sCompStream.Read(sString[1],sCompStream.Size); 
        SendPacket(cSock,PACK_COMPRESSEDDOWNLOADFILE,sString); 
        except 
        SendPacket(cSock,PACK_COMPRESSEDTRANSFERFILE,IntToStr(0)); 
        end; 
        goto cleanup; 
       end; 
       end; 
      PACK_QUERYFILE: 
       begin 
       if FileExists(sString) then begin 
        try 
        sFirstCap.LoadFromFile(sString); 
        sFirstCap.Position := 0; 
        sString := ''; 
        SetLength(sString,sFirstCap.Size); 
        SendPacket(cSock,PACK_DOWNLOADFILE,IntToStr(sFirstCap.Size)); 
        sFirstCap.Read(sString[1],sFirstCap.Size); 
        SendPacket(cSock,PACK_TRANSFERFILE,sString); 
        except 
        SendPacket(cSock,PACK_DOWNLOADFILE,IntToStr(0)); 
        end; 
        goto cleanup; 
       end; 
       if FileExists(sString) then begin 
        try 
        fFile := TFileStream.Create(sString, fmOpenRead); 
        Repeat 
         ZeroMemory(@bBuff[0],4096); 
         cRead := fFile.Read(bBuff[0],Length(bBuff)); 
         If (cRead <= 0) Then Break; 
         If cSock.SendBuffer(bBuff[0],cRead) <= 0 then break; 
        Until 1 = 3; 
        fFile.Free; 
        except 
        end;                 
       end;             
       goto cleanup; 
       end;              
      PACK_FILESTART: // problem is here                      
       begin                 
       try 
        fFile := TFileStream.Create(sString, fmCreate); 
        Repeat 
        ZeroMemory(@bBuff[0],4096); 
        cRead := cSock.ReceiveBuffer(bBuff[0],4096); --> stopped on debug. no execute next line. 
        if cRead <= 0 then break; 
        fFile.Write(bBuff,cRead); 
        Until 1 = 3; 

       Finally 
       fFile.Free; 
       end; 
       goto cleanup; 
       end;            



      end;          
     until scFullData = ''; 
     until 1 = 3; 
    end; 
    end; 
    cleanup: 
    try 
     sFirstCap.Free; 
     sSecondCap.Free; 
    except 
    end; 
    FreeMem(p); 
    cSock.Disconnect; 
End; 
+0

'goto'役立ちます

希望デルファイへのより多くのネイティブなものを書いてお勧めしますか?あなたは間違いなくそれを書き直す必要があります。 'fmCreate'は最も制限的な共有モードに対応しています。あなたはこのファイルを閉じていますか? –

+0

'1 = 3'まで? 'goto CleanMySock'。あなたは私たちを運んでいますか?デバッグを試してみてください。どのファイルがロックされていますか?あなたは[mcve]を見せますか? **アクセスする前にリソースを取得**しようとするか、アクセス違反が予想されます。 –

+0

こんにちは、私は再び説明しました。 –

答えて

0

いくつかの考え...

1)バイトが読み取り可能である場合に、コードはチェックしません。参照してください: "cRead:= cSock.ReceiveBuffer(bBuff [0]、4096); - >デバッグ時に停止し、次の行を実行しません。 これがリピートループにどのようにあるのか注意してください。読み込むデータがなくなったらどうなりますか?それは再入コードを持っているようにこれが見えます(例えば、早期断線)

2)...私は)同じファイル

3にfmCreateを獲得しようとしているから、2つの異なるスレッドを停止するために、任意のチェックが表示されませんgotoに関するコメントに関しては、これはVBA(ON Error Gosub)から変換されたように見えます。私は非常にこれは

関連する問題