Sumber: Baoyu BLOG
1. Saya akan menjelaskan prinsip upload tanpa komponen sedikit demi sedikit dengan contoh HTML kliennya adalah sebagai berikut. Untuk menelusuri lampiran yang diunggah, kita meneruskan elemen <input type="file">, namun pastikan untuk menyetel atribut enctype formulir ke "multipart/form-data":
<form method="post" action="upload.asp" enctype="multipart/form-data">
<label>
<masukan tipe="file" nama="file1" />
</label>
<br />
<input type="teks" nama="nama file" value="nama file default"/>
<br />
<input type="kirim" value="Kirim"/>
<input type="reset" value="Reset"/>
</bentuk>
Di program latar belakang asp, dulu sangat mudah untuk mendapatkan data ASCII yang dikirimkan melalui formulir. Namun jika Anda perlu mendapatkan file yang diunggah, Anda harus menggunakan metode BinaryRead dari objek Permintaan untuk membacanya. Metode BinaryRead melakukan pembacaan biner sejumlah byte tertentu dari aliran input saat ini. Satu hal yang perlu diperhatikan adalah setelah metode BinaryRead digunakan, koleksi Request.Form atau Request.QueryString tidak dapat digunakan lagi. Dikombinasikan dengan properti TotalBytes dari objek Permintaan, semua data yang dikirimkan oleh formulir dapat diubah menjadi biner, namun semua data ini dikodekan. Pertama, mari kita lihat bagaimana data ini dikodekan. Apakah ada aturan yang harus diikuti? Segmentasikan kodenya, kita ubah biner yang dibaca oleh BinaryRead menjadi teks dan keluarannya di upload.asp di latar belakang (catatan). Jangan unggah file besar dalam contoh ini, jika tidak, browser mungkin mogok):
<%
Redupkan biData, PostData
Ukuran = Permintaan.TotalBytes
biData = Permintaan.BinaryRead(Ukuran)
PostData = BinaryToString(biData,Ukuran)
Response.Tulis "<pre>" & PostData & "</pre>" 'Gunakan pra dan keluaran format apa adanya
'Ubah aliran biner menjadi teks dengan bantuan RecordSet
Fungsi BinaryToString (biData, Ukuran)
Konstan adLongVarChar = 201
Setel RS = CreateObject("ADODB.Recordset")
RS.Fields.Tambahkan "mBinary", adLongVarChar, Ukuran
RS.Buka
RS.TambahBaru
RS("mBinary").AppendChunk(biData)
RS.Perbarui
BinaryToString = RS("mBinary").Nilai
RS.Tutup
Fungsi Akhir
%>
Demi kesederhanaan, unggah file teks paling sederhana (G:homepage.txt, dengan konten "Baoyu: http://www.webuc.net ") untuk mengujinya. Pertahankan nilai default "nama file default" di nama file kotak teks. Kirim dan lihat hasilnya:
--------------------------------7d429871607fe
Disposisi Konten: form-data; name="file1"; filename="G:homepage.txt"
Tipe Konten: teks/polos
Baoyu: http://www.webuc.net
--------------------------7d429871607fe
Disposisi Konten: form-data; nama = "nama file"
nama file bawaan
-----------------------------7d429871607fe--
Terlihat untuk item yang berbentuk "----- --------------------------7d429871607fe" Batas-batas tersebut digunakan untuk memisahkan bagian-bagian menjadi beberapa bagian, dan terdapat beberapa informasi deskripsi di awal setiap bagian. , misalnya: Konten- Disposisi: form-data; name="filename", pada informasi deskripsi, Anda dapat mengetahui nama item form melalui name="filename". Jika ada konten seperti filename="G:homepage.txt", berarti itu adalah file yang diunggah. Jika itu adalah file yang diunggah, maka informasi deskripsi akan memiliki satu baris lagi Content-Type: text/plain untuk dijelaskan Tipe Konten file. Informasi deskripsi dan informasi isi dipisahkan dengan jeda baris.
Pada dasarnya sudah jelas. Menurut aturan ini, kita tahu cara memisahkan data dan memproses data yang dipisahkan. Namun, kita hampir mengabaikan satu masalah, yaitu nilai batas ("-------" di atas contoh) Bagaimana -----------------------7d429871607fe") tahu? Nilai batas ini berbeda setiap kali Anda mengunggahnya. Untungnya, dapat diperoleh melalui Request.ServerVariables("HTTP_CONTENT_TYPE") di asp. Misalnya, pada contoh di atas, konten HTTP_CONTENT_TYPE adalah: "multipart/form-data; batas=-- --------------------------7d429871607fe", dengan ini, kita tidak hanya dapat menentukan apakah enctype="multipart/form- data " (jika tidak digunakan maka tidak perlu mengeksekusinya di bawah), Anda juga bisa mendapatkan nilai batas batas=---------------------- ----- 7d429871607fe. (Catatan: Nilai batas yang diperoleh di sini memiliki "--" di awal lebih sedikit daripada nilai batas di atas. Yang terbaik adalah menambahkannya.)
Adapun proses cara menganalisis data, saya tidak akan menjelaskannya secara detail tidak lebih dari menggunakan fungsi seperti InStr dan Mid untuk memisahkan data yang kita inginkan.
2. Saat mengunggah dalam potongan, kemajuan pencatatan harus mencerminkan bilah kemajuan secara real time. Intinya adalah untuk mengetahui berapa banyak data yang diperoleh server saat ini secara real time? Mengingat kembali proses pengunggahan, kami mengimplementasikannya melalui Request.BinaryRead(Request.TotalBytes). Selama proses Request, kami tidak dapat mengetahui berapa banyak data yang diperoleh server saat ini. Jadi kita hanya bisa menggunakan solusinya. Jika kita bisa membagi data yang diperoleh menjadi beberapa bagian, lalu berdasarkan jumlah blok yang sudah diunggah, kita bisa menghitung seberapa besar yang saat ini diunggah! Artinya, jika 1K adalah 1 blok, maka aliran input unggahan 1MB akan dibagi menjadi 1024 blok untuk memperolehnya. Misalnya, jika saya telah memperoleh 100 blok, berarti 100K telah diunggah. Ketika saya mengusulkan pemblokiran, banyak orang merasa luar biasa karena mereka mengabaikan bahwa metode BinaryRead tidak hanya dapat membaca ukuran yang ditentukan, tetapi juga membaca terus menerus.
Tulis contoh untuk memverifikasi integritas pembacaan blok, berdasarkan contoh tadi (perhatikan bahwa contoh ini tidak mengunggah file besar, jika tidak maka dapat menyebabkan browser mogok):
<%
Redupkan biData, PostData, TotalBytes, ChunkBytes
ChunkBytes = 1 * 1024' Ukuran potongannya adalah 1K
TotalBytes = Permintaan.TotalBytes 'Ukuran total
PostData = "" ' Data dikonversi ke tipe teks
ReadBytes = 0 'Diinisialisasi ke 0
'Bacalah sedikit demi sedikit
Lakukan Saat ReadBytes < TotalBytes
biData = Request.BinaryRead(ChunkBytes) 'Potongan saat ini
PostData = PostData & BinaryToString(biData,ChunkBytes) 'Ubah potongan saat ini menjadi teks dan sambungkan
ReadedBytes = ReadedBytes + ChunkBytes 'Rekam ukuran baca
Jika ReadBytes > TotalBytes Maka ReadedBytes = TotalBytes
Lingkaran
Response.Tulis "<pre>" & PostData & "</pre>" ' Gunakan pra dan keluaran format apa adanya
' Ubah aliran biner menjadi teks
Fungsi BinaryToString (biData, Ukuran)
Konstan adLongVarChar = 201
Setel RS = CreateObject("ADODB.Recordset")
RS.Fields.Tambahkan "mBinary", adLongVarChar, Ukuran
RS.Buka
RS.TambahBaru
RS("mBinary").AppendChunk(biData)
RS.Perbarui
BinaryToString = RS("mBinary").Nilai
RS.Tutup
Fungsi Akhir
%>
Coba unggah file teks tadi. Hasil keluaran membuktikan bahwa pembacaan konten dalam blok telah selesai, dan dalam perulangan While, kita dapat mencatat status saat ini ke dalam Aplikasi setiap kali perulangan, dan kemudian kita dapat meneruskan Access the Aplikasi untuk mendapatkan bilah kemajuan unggahan secara dinamis.
Juga: Dalam contoh di atas, penyambungan string digunakan. Jika Anda ingin menyambungkan data biner, Anda dapat menggunakan metode Write pada objek ADODB.Stream. Kode contohnya adalah sebagai berikut:
Set bSourceData = createobject("ADODB.Stream" )
bSourceData.Buka
bSourceData.Type = 1 'Biner
Lakukan Saat ReadBytes < TotalBytes
biData = Permintaan.BinaryRead(ChunkBytes)
bSourceData.Write biData ' Langsung gunakan metode tulis untuk menulis aliran file saat ini ke bSourceData
ReadBytes = ReadBytes + PotonganBytes
Jika ReadBytes > TotalBytes Maka ReadedBytes = TotalBytes
Aplikasi("ReadedBytes") = ReadBytes
Lingkaran
3. Simpan file yang diunggah. Dapatkan data yang dikirimkan melalui Request.BinaryRead Setelah memisahkan file yang diunggah, metode penyimpanannya berbeda-beda tergantung pada tipe datanya:
untuk data biner, Anda dapat menyimpan aliran biner secara langsung melalui metode SaveToFile. Objek ADODB.Stream. Menjadi file.
Untuk data teks, Anda dapat menyimpan data teks ke file melalui metode Tulis pada objek TextStream.
Data teks dan data biner dapat dengan mudah dikonversi satu sama lain. Untuk mengunggah file kecil, pada dasarnya tidak ada perbedaan antara keduanya. Namun masih terdapat beberapa perbedaan saat menyimpan antara kedua metode tersebut. Untuk objek ADODB.Stream, semua data harus dimuat sebelum dapat disimpan sebagai file. Oleh karena itu, mengunggah file berukuran besar menggunakan metode ini akan memakan banyak memori, dan untuk objek TextStream, Setelah file dibuat, Anda dapat menulis sebagian sekaligus dan menulisnya beberapa kali. Keuntungannya adalah tidak akan memakan ruang memori server blok dianalisis di atas, kita dapat menulis setiap bagian dari data yang diunggah ke tengah file. Saya pernah melakukan percobaan dan mengupload file berukuran lebih dari 200 MB ke mesin yang sama. Menggunakan cara pertama, memori terus bertambah. Ujung-ujungnya langsung ditanyakan bahwa memori virtual komputer tidak mencukupi padahal di progres barnya menandakan file sudah terupload, pada akhirnya file tersebut tetap tidak tersimpan. Dengan menggunakan metode terakhir, pada dasarnya tidak ada perubahan pada memori selama proses pengunggahan.
4. Masalah yang belum terselesaikan Saya melihat Bestcomy di blog yang menjelaskan bahwa komponen unggahan Asp.Net-nya dapat independen dari Sever.SetTimeOut, tetapi di Asp saya tidak dapat melakukannya. Untuk mengunggah file besar, saya hanya dapat menggunakan Server.SetTimeOut saja ditetapkan ke nilai yang sangat besar. Saya tidak tahu apakah ada solusi yang lebih baik.
Jika kita menggunakan metode Write pada objek TextStream saat menyimpan file, maka jika pengguna menghentikan transfer file saat mengupload, bagian file yang sudah diupload masih ada. Masalah utamanya adalah meskipun metode Request.BinaryRead dapat membaca dalam blok, metode ini tidak dapat melewati bagian pembacaan tertentu!
5. Kesimpulan Prinsipnya pada dasarnya dijelaskan dengan jelas, tetapi kode sebenarnya jauh lebih rumit dari ini. Ada banyak masalah yang perlu dipertimbangkan. Bagian yang paling merepotkan adalah analisis data menganalisis apakah itu termasuk dalam informasi deskripsi. Item formulir masih berupa file yang diunggah, dan apakah file tersebut telah diunggah...
Saya yakin bahwa berdasarkan uraian di atas, Anda juga dapat mengembangkan komponen unggahan tanpa komponen yang kuat. Saya pikir lebih banyak orang hanya peduli dengan kode dan tidak tahu cara menulisnya sendiri. Mungkin mereka tidak punya waktu, mungkin levelnya tidak cukup, dan lebih banyak lagi yang menjadi kebiasaan... Saya punya melihat terlalu banyak teknologi di CSDN Esai delapan bagian - paragraf deskripsi, dan kemudian semua kode. Mengajari seseorang memancing tidak sebaik mengajarinya memancing. Jika saya memberi Anda kode, Anda mungkin tidak memikirkan alasannya dan hanya menggunakannya. Saat Anda menghadapi masalah serupa di lain waktu, Anda masih tidak tahu alasannya. Saya harap artikel ini dapat membantu Lebih banyak orang mempelajari sesuatu, dan yang terpenting adalah "mencerahkan" sesuatu!