08-09-22, 11:54 AM
(آخر تعديل لهذه المشاركة : 08-09-22, 11:55 AM {2} بواسطة saif2023.
تعديل السبب: System.Net.WebException: تم إجهاض الطلب: تعذر إنشاء قناة SSL/TLS آمنة.
)
(14-04-20, 02:38 AM)ابو ليلى كتب : الان سنقوم بمعالجة عملية الرفع وفق التالي.
سنحدد الملفات التي نريد رفعها عبر CheckBox و من ثم نقوم بالمرور على كل صفوف الجدول فاذا وفق ان الصف محدد
سنقوم عندها برفع الملف .
الدالة المسؤولة عن الرفع هي دالة من النوع Asyncronis تحتاج الى عدة وسائط (كائن DropboxClient , مسار الرفع و اسم الملف و مساره) و كلها تتوفر لدينا في الجدول و لكل ملف.PHP كود :
Private Async Sub Btn_Upload_Click(sender As Object, e As EventArgs) Handles Btn_Upload.Click
If DGV1.RowCount > 0 Then
For Each Row As DataRow In Dt_FileUpdate.Rows
If Row IsNot Nothing Then
If Row("Status").ToString = "True" Then
Lb_FileToUpload.Text = Row("FilePath")
Btn_Upload.Enabled = False
Await Uploader(client, Path, Row("FileName"), Row("FilePath"))
Btn_Upload.Enabled = True
End If
End If
Next
End If
End Sub
End Class
الدالة Uploader :
PHP كود :
''' <summary>
''' رفع ملفات
''' </summary>
''' <param name="dbx"></param>
''' <param name="folder"></param>
''' <param name="_file"></param>
''' <param name="fileToUpload"></param>
''' <returns></returns>
Private Async Function Uploader(ByVal dbx As DropboxClient, ByVal folder As String, ByVal _file As String, ByVal fileToUpload As String) As Task
Const ChunkSize As Integer = 2 * 1024
Using fileStream = File.Open(fileToUpload, FileMode.Open)
If fileStream.Length <= ChunkSize Then
Await dbx.Files.UploadAsync(folder & "/" & _file, WriteMode.Overwrite.Instance, body:=fileStream)
Else
Await UploadWthProgress(dbx, folder & "/" & _file, fileStream, CInt(ChunkSize))
End If
End Using
End Function
''' <summary>
''' الرفع مع بروجرس
''' </summary>
''' <param name="dbx"></param>
''' <param name="path"></param>
''' <param name="stream"></param>
''' <param name="chunkSize"></param>
''' <returns></returns>
Private Async Function UploadWthProgress(ByVal dbx As DropboxClient, ByVal path As String, ByVal stream As FileStream, ByVal chunkSize As Integer) As Task
Dim numChunks As ULong = CULng(Math.Ceiling(CDbl(stream.Length) / chunkSize))
Dim buffer As Byte() = New Byte(chunkSize - 1) {}
Dim sessionId As String = Nothing
Dim idx As ULong = 0
PG2.Invoke(New Action(Sub()
idx = 0
Me.PG2.Value = 0
PG2.Maximum = numChunks - 1
End Sub))
For idx = 0 To numChunks - 1
Dim byteRead = stream.Read(buffer, 0, chunkSize)
Using memStream = New MemoryStream(buffer, 0, byteRead)
If idx = 0 Then
Dim result = Await dbx.Files.UploadSessionStartAsync(False, memStream)
sessionId = result.SessionId
Else
Dim cursor = New UploadSessionCursor(sessionId, CULng(chunkSize) * idx)
If idx = numChunks - 1 Then
Lb_FileToUpload.Invoke(New Action(Sub()
Lb_FileToUpload.Text = "اكتمل الرفع"
Lb_FileToUpload.Update()
End Sub))
Dim fileMetadata As FileMetadata = Await dbx.Files.UploadSessionFinishAsync(cursor, New CommitInfo(path), memStream)
Else
Await dbx.Files.UploadSessionAppendV2Async(cursor, False, memStream)
Lb_FileToUpload.Invoke(New Action(Sub()
Lb_FileToUpload.Text = "Uploading..." & " " & path & " " & numChunks - 1 & " / " & idx
Lb_FileToUpload.Update()
Me.PG2.Value = idx + 1
End Sub))
End If
End If
End Using
Next
End Function
الدالة تم تقسيمها الى جزئين و السبب هو وجود ملفات ذات حجم كبير يمكن ان يتم رفعها الى المساحة و بالتالي لا بد من طريقة لاشعار المستخدم ان هناك تقدم في عملية الرفع بدل الانتظار لوقت ظويل دون معرفة ما يجري في الخلفة.
اما الملفات الصغيرة فيتم تحميلها مباشرة دون الشعور بتقدم المؤشر و يمكن التحكم باقل حجم بعده ينطلق الجزء الثاني من الدالة عبر تغير قيمة المتغير ChunkSize .
صراحة تم العمل كثيراً على هذا الجزء الخاص بربط ProgressBar مع عملية التحميل حيث ان العملية غير مدعومة داخل المكتبة .
و كون عملية الرفع تجري في الخلفية في Task منفصل فكان من الصعب جداً الوصول الى طريقة فعالة , و لكن و الحمد لله تم حل المشكلة و هي تعمل بكفاءة.
-------------------------------------------------------------
الشق الثاني المتعلق بتحميل الملفات : يجري بنفس السيناريو حيث نقوم بتحميل اسماء الملفات ضمن المسار المحدد الى ListBox و من ثم نقوم بالمرور على الملفات داخل المسار و نحملها تباعاً الى مسار محدد ستراه داخل الكود.
اجراء التحميل:
الدالة ListFolder داخل الكود مهمتها مزدوجة تقوم بالمرور على شقين داخل المسار المحدد.PHP كود :
Private Async Sub Btn_Download_Click(sender As Object, e As EventArgs) Handles Btn_Download.Click
Dim list = Await ListFolder(client, Path)
GroupBox4.Text = "Files To Download in Folder : " & Path
Try
For Each Itm In list.Entries
If Itm.IsFile Then
Btn_Download.Enabled = False
Await Downloader(client, Path, Itm.AsFile)
Btn_Download.Enabled = True
End If
Next
Label1.Text = "اكتمل التحميل..."
Catch ex As Exception
End Try
End Sub
الشق الاول تقوم بجلب كل المجلدات الفرعية داخل المسار , اهذا انا انشأت مجلدات فرعية في بداية الشرح..
الشق الثاني تقوم بجلب كل الملفات داخل المسار المحدد (داخل المجلد المحدد في المسار).
شكل الدالة :
اما دالة التحميل Downloader فهي تقوم بتحميل الملف بدلالة مساره و اسمه القادم من الموقع الى مكان محدد داخل جهازيPHP كود :
''' <summary>
''' جلب الملفات من مسار محدد ضمن الموقع
'''DropBox المسار هو مجلد داخل
''' </summary>
''' <param name="client"></param>
''' <param name="path"></param>
''' <returns></returns>
Private Async Function ListFolder(ByVal client As DropboxClient, ByVal path As String) As Task(Of ListFolderResult)
Dim list = Await client.Files.ListFolderAsync(path)
'هذا لجلب مجلدات ضمن المسار
'For Each item In list.Entries.Where(Function(i) i.IsFolder)
' ListBox_Folders.Items.Add(item.Name)
'Next
ListBox_Files.Items.Clear()
'جلب املفات ضمن المسار
For Each item In list.Entries.Where(Function(i) i.IsFile)
Dim file = item.AsFile
ListBox_Files.Items.Add(file.Size & " / " & item.Name)
Next
Return list
End Function
وهو هنا (D:\Test Folder\) يمكنك جعل الامر اكثر تفاعلا بجعل المستخدم يحدد المكان.
شكل الدالة :
الى هنا نكون قد وصلنا الى الهدف من برنامجنا.PHP كود :
''' <summary>
''' تحميل ملفات تم الدمج وفق طريقتين
''' </summary>
''' <param name="client"></param>
''' <param name="folder"></param>
''' <param name="file"></param>
''' <returns></returns>
Private Async Function Downloader(ByVal client As DropboxClient, ByVal folder As String, ByVal file As FileMetadata) As Task
Using response = Await client.Files.DownloadAsync(folder & "/" & file.Name)
Dim fileSize As ULong = response.Response.Size
Const bufferSize As Integer = 1024 * 1024
Dim buffer = New Byte(bufferSize) {}
Using stream = Await response.GetContentAsStreamAsync()
Using file2 = New FileStream("D:\Test Folder\" & file.Name, FileMode.OpenOrCreate)
Dim length = stream.Read(buffer, 0, bufferSize)
While (length > 0)
file2.Write(buffer, 0, length)
Dim percentage = 100 * CType(file2.Length, ULong) / fileSize
Label1.Invoke(New Action(Sub()
Label1.Text = "Download" & " " & file.Name & " " & fileSize & " / " & CInt(percentage)
Label1.Update()
Me.PG.Value = percentage
End Sub))
length = stream.Read(buffer, 0, bufferSize)
End While
End Using
End Using
End Using
End Function
المكتبة تمكنك من عمل الكثير من انشاء مجلدات و ملفات و التعديل عليها و الحذف و غيرها من الامور الاعتيادية التي تستطيع التعامل معها , ان كان على مستوى خاص او على مستوى فريق .... الخ
نحن اكتفينا ببعض الامور التي تفيدنا .
الملف المرفق يحتوي على المثال كامل .
ان كنت ستعتمد عليه , فعليك بتغير Access Token الى الخاص بك في اعدادات البرنامج.
صور للاستخدام.
![]()
![]()
![]()
![]()
![]()
دمتم بخير و الله الموفق.
