2012-01-17 15 views
8

के साथ टीस्ट्रीम के माध्यम से फ़ाइल डाउनलोड करें मैंने एक डेटास्नाप सर्वर विधि लिखा है जो एक फ़ाइल को स्थानांतरित करने के लिए एक TStream ऑब्जेक्ट देता है। क्लाइंट एप्लिकेशन विधि को कॉल करता है और स्ट्रीम ठीक पढ़ता है। मेरी समस्या यह है कि विधि कॉल को पढ़ने के लिए TStream ऑब्जेक्ट उपलब्ध होने से पहले कुछ समय लगता है, लेकिन सर्वर पक्ष पर मैं देख सकता हूं कि विधि कॉल को ऑब्जेक्ट को वापस करने के लिए केवल एक सेकंड लगता है। मैं उम्मीद कर रहा था कि स्ट्रीम ऑब्जेक्ट तुरंत लौटा दिया जाएगा ताकि मैं स्ट्रीम पढ़ सकूं और डाउनलोड प्रगति के लिए प्रगति पट्टी प्रदर्शित कर सकूं। क्या मैं ऐसा कर सकता हूं?डेल्फी XE2 डेटा स्नैप - प्रगति बार

सर्वर विधि बहुत सरल है:

function TServerMethods.DespatchDocument(sCompanyID, sDocOurRef: string): TStream; 
var 
    sSourceFilePath: string; 
    strFileStream: TFileStream; 
begin 
    sSourceFilePath := GetDocumentPDFFilePath(sCompanyID, sDocOurRef); 

    strFileStream := TFileStream.Create(sSourceFilePath, fmOpenRead); 
    Result := strFileStream; 
end; 
+0

संभव डुप्लिकेट: // stackoverflow। कॉम/प्रश्न/6081841/प्रोग्रेसबार-फॉर ट्रेसोरस्ट्रीम-डेल्फी) – NGLN

उत्तर

2

यह वह जगह है मैं इसे कैसे एक समय पहले किया था। मैंने एक्सई का इस्तेमाल किया और इसे साफ करने का मौका नहीं मिला।

// सर्वर साइड:

function TServerMethods1.DownloadFile(out Size: Int64): TStream; 
begin 
    Result := TFileStream.Create('upload.fil', fmOpenRead or fmShareDenyNone); 
    Size := Result.Size; 

    Result.Position := 0; 
end; 

// क्लाइंट साइड:

procedure TfMain.DownloadFile(Sender: TObject); 
var 
    RetStream: TStream; 
    Buffer: PByte; 
    Mem: TMemoryStream; 
    BytesRead: Integer; 
    DocumentId: Int64; 
    Size: Int64; 
    filename: WideString; 
    BufSize: Integer; 
begin 
    BufSize := 1024; 

    try 
     Mem := TMemoryStream.Create; 
     GetMem(Buffer, BufSize); 

     try 
     RetStream := FDownloadDS.DownloadFile(Size); 
     RetStream.Position := 0; 

     if (Size <> 0) then 
     begin 
      filename := 'download.fil'; 

      repeat 
      BytesRead := RetStream.Read(Pointer(Buffer)^, BufSize); 

      if (BytesRead > 0) then 
      begin 
       Mem.WriteBuffer(Pointer(Buffer)^, BytesRead); 
      end; 

      lStatus.Caption := IntToStr(Mem.Size) + '/' + IntToStr(Size); 
      Application.ProcessMessages; 

      until (BytesRead < BufSize); 

      if (Size <> Mem.Size) then 
      begin 
      raise Exception.Create('Error downloading file...'); 
      end; 
     end 
     else 
     begin 
      lStatus.Caption := ''; 
     end; 
     finally 
     FreeMem(Buffer, BufSize); 
     FreeAndNIl(Mem); 
     end; 
    except 
     on E: Exception do 
     begin 
     lErrorMessage.Caption := PChar(E.ClassName + ': ' + E.Message); 
     end; 
    end; 
end; 

आप BufSize समायोजित कर सकते हैं जैसे आप चाहें। जब तक मैंने इसे इस तरह से नहीं किया तब तक मुझे स्ट्रीम का आकार प्राप्त करने में परेशानी हो रही थी। मैंने XE2 के साथ प्रयोग किया और मुझे एक ही समस्या प्रतीत नहीं हुई लेकिन मैं अपलोड कर रहा था। स्ट्रीम के आकार को पुनः प्राप्त करने का शायद एक बेहतर तरीका है। अगर मुझे जल्द ही जवाब मिल जाएगा तो मैं आपको बता दूंगा ....

एक और नोट पर - मुझे पता नहीं चला है कि सर्वर पक्ष पर प्रगति पट्टी कैसे प्रदर्शित करें। मैं अभी भी इसे समझने की कोशिश कर रहा हूं।

मुझे आशा है कि इस मदद करता है! अगर आपका कोई प्रश्न हैं, तो मुझे से पूछें!

+0

नहीं, मुझे कोई देरी नहीं हुई है। मैं सभी आकारों की फाइलें डाउनलोड कर रहा हूं (5 मेगापिक्स तक)। प्रगति सूचक बस ठीक काम करता है। मुझे पता है कि यह अजीब लगता है लेकिन कभी-कभी मुझे कुछ बंदरगाहों पर डेटास्नाप व्यवहार करने के तरीके में परेशानी होती है। मैं एक अलग बंदरगाह में बदल गया और सब कुछ ठीक काम किया। दुर्भाग्यवश, मुझे यह जानने का मौका कभी नहीं मिला कि मैं आपको क्यों बताऊंगा। आपकी फाइलों का आकार क्या है? और आपने BufSize के लिए कितनी उच्च और निम्न श्रेणियों की कोशिश की है? – Tadpole

+0

जिस फ़ाइल के साथ मैं परीक्षण कर रहा हूं वह केवल 5 मेगापिक्सल है। मैंने आपके पास समान डेटा स्नैप विधि बनाई है, और ग्राहक कॉल प्रगति पट्टी के साथ स्ट्रीम को पढ़ने से पहले पूरा करने के लिए लगभग 40 सेकंड ले रहा है। मैं वर्तमान में डेटास्नाप विधि को कॉल करने के लिए TDSRESTConnection का उपयोग कर HTTP पर पोर्ट 8080 का उपयोग कर रहा हूं। आप DataSnap सेवा से कैसे जुड़ रहे हैं? –

+0

मुझे अभी तक डेटास्नाप की आरईएसटी क्षमताओं को देखने का मौका नहीं मिला है। मैं डिफ़ॉल्ट 211 पोर्ट और क्लाइंट TSQLConnection का उपयोग कर टीसीपी से कनेक्ट कर रहा हूं।जिस ऐप में मुझे परेशानी हो रही थी, मैंने पोर्ट 99 99 (और एक और ऐप 99 99 तक) पर सेट किया और समस्याएं चली गईं। मुझे लगता है कि यह मेरा आईएसपी फ़िल्टर तंत्र था। एक और बात - मैं XE2 अपडेट 3 का उपयोग कर रहा हूं। क्या आपको यह मिला है? आप JSON के साथ कुछ भी कर रहे हैं? मुझे इसके साथ कुछ चीजों को ठीक करना पड़ा है, लेकिन मैं इसे आपके डाउनलोड को प्रभावित करने वाली छवि नहीं कर सकता। यदि आपके पास एक छोटा नमूना है तो मैं इसे बनाउंगा और देख सकता हूं कि मुझे एक ही समस्या है या नहीं। – Tadpole

0

खुशी है कि आपके पास कुछ भाग्य है! यह वही फिक्स है जो मुझे करना था। आप कोड मैं "Data.DBXJSONReflect.pas" में पाया में इस लिंक https://forums.embarcadero.com/thread.jspa?threadID=66490&tstart=0

का उल्लेख कर सकते डाइविंग के बाद

प्रक्रिया TJSONPopulationCustomizer.PrePopulate (डेटा: TObject; rttiContext: TRttiContext); ...

3473: rttiField.GetValue(Data).AsObject.Free; 
3474: rttiField.SetValue(Data, TValue.Empty); 

...

मुझे लगता है कि यह इस तरह से होना चाहिए: (http [TResourceStream (डेल्फी) के लिए ProgressBar] की

3473: rttiField.SetValue(Data, TValue.Empty); 
3474: rttiField.GetValue(Data).AsObject.Free; 
संबंधित मुद्दे