কেন কেউ মিশ্রিত ডেটা এবং ফাইল স্থানান্তরের জন্য মাল্টিপার্ট / ফর্ম-ডেটা ব্যবহার করবে?


14

আমি সি # তে কাজ করছি এবং আমি লিখছি এমন 2 টি অ্যাপের মধ্যে কিছু যোগাযোগ করছি। আমি ওয়েব API এবং JSON পছন্দ করতে এসেছি। এখন আমি সেই স্থানে আছি যেখানে আমি দুটি সার্ভারের মধ্যে একটি রেকর্ড প্রেরণের জন্য একটি রুটিন লিখছি যাতে কিছু পাঠ্য ডেটা এবং একটি ফাইল অন্তর্ভুক্ত থাকে।

ইন্টারনেট অনুসারে আমি এখানে দেখানো হিসাবে একটি মাল্টিপার্ট / ফর্ম-ডেটা অনুরোধ ব্যবহার করার কথা:

এসও প্রশ্ন "সি # ক্লায়েন্টের বহুবিধ ফর্মগুলি"

মূলত আপনি ম্যানুয়ালি একটি অনুরোধ লিখুন যা এর মতো বিন্যাস অনুসরণ করে:

Content-type: multipart/form-data, boundary=AaB03x

--AaB03x
content-disposition: form-data; name="field1"

Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain

 ... contents of file1.txt ...
--AaB03x--

আরএফসি 1867 থেকে অনুলিপি করা হয়েছে - এইচটিএমএলে ফর্ম-ভিত্তিক ফাইল আপলোড

এই ফর্ম্যাটটি এমন কাউকে বেশ কষ্টদায়ক, যিনি সুন্দর জেএসওএন ডেটা ব্যবহার করতে ব্যবহৃত। সুতরাং স্পষ্টতই সমাধানটি হল একটি JSON অনুরোধ তৈরি করা এবং বেস 64 ফাইলটি এনকোড করে এবং এর অনুরোধটি শেষ করে:

{
    "field1":"Joe Blow",
    "fileImage":"JVBERi0xLjUKJe..."
}

এবং আমরা আমাদের যে কোনও জায়গায় JSON সিরিয়ালাইজেশন এবং ডিসরিয়ালাইজেশন ব্যবহার করতে পারি। তার উপরে, এই ডেটা প্রেরণের কোডটি বেশ সহজ। আপনি কেবল JSON সিরিয়ালাইজেশনের জন্য আপনার ক্লাস তৈরি করেন এবং তারপরে বৈশিষ্ট্যগুলি সেট করুন। ফাইল স্ট্রিং বৈশিষ্ট্যটি কয়েকটি তুচ্ছ লাইনে সেট করা আছে:

using (FileStream fs = File.Open(file_path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    byte[] file_bytes = new byte[fs.Length];
    fs.Read(file_bytes, 0, file_bytes.Length);
    MyJsonObj.fileImage = Convert.ToBase64String(file_bytes);
}

প্রতিটি আইটেমের জন্য আর মূর্খ সীমানা এবং শিরোনাম নেই। এখন বাকি প্রশ্ন পারফরম্যান্স। সুতরাং আমি যে প্রোফাইল। আমার কাছে 50 টি স্যাম্পল ফাইলের একটি সেট রয়েছে যা আমার 50KB থেকে 1.5MB বা তার বেশি পর্যন্ত তারের জুড়ে পাঠাতে হবে। প্রথমে আমি কিছু লাইন কেবল ফাইলটিতে প্রবাহিত করতে একটি বাইট অ্যারেতে প্রবাহিত করতে যুক্ত করেছিলাম যা ফাইলটিতে প্রবাহিত হয় এবং তারপরে এটি একটি বেস 64 স্ট্রিমে রূপান্তরিত করে। নীচে 2 টি কোডের কোড যা আমি প্রকাশ করেছি:

প্রোফাইল মাল্টিপার্ট / ফর্ম-ডেটাতে সরাসরি স্ট্রিম

var timer = new Stopwatch();
timer.Start();
using (FileStream fs = File.Open(file_path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    byte[] test_data = new byte[fs.Length];
    fs.Read(test_data, 0, test_data.Length);
}
timer.Stop();
long test = timer.ElapsedMilliseconds;
//Write time elapsed and file size to CSV file

JSON অনুরোধ তৈরি করতে প্রোফাইলটিতে স্ট্রিম এবং এনকোড

var timer = new Stopwatch();
timer.Start();
using (FileStream fs = File.Open(file_path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    byte[] file_bytes = new byte[fs.Length];
    fs.Read(file_bytes, 0, file_bytes.Length);
    ret_file = Convert.ToBase64String(file_bytes);
}
timer.Stop();
long test = timer.ElapsedMilliseconds;
//Write time elapsed, file size, and length of UTF8 encoded ret_file string to CSV file

ফলাফলগুলি ছিল যে সরল পঠন সর্বদা 0 মিমি নিয়ে থাকে তবে বেস 64 এনকোডিংটি 5 মিমি পর্যন্ত নিয়েছিল। নীচে দীর্ঘতম সময় রয়েছে:

File Size  |  Output Stream Size  |  Time
1352KB        1802KB                 5ms
1031KB        1374KB                 7ms
463KB         617KB                  1ms

যাইহোক, উত্পাদনে আপনি প্রথমে নিজের ডিলিমিটারটি পরীক্ষা না করে কখনই অন্ধভাবে মাল্টপার্ট / ফর্ম-ডেটা লিখবেন না? সুতরাং আমি ফর্ম-ডেটা কোডটি সংশোধন করেছিলাম যাতে এটি ফাইলটিতেই ডিলিমিটার বাইটগুলি পরীক্ষা করে পরীক্ষা করে যায় যে সবকিছু ঠিকঠাক করা যায় ঠিক। আমি একটি অপ্টিমাইজড স্ক্যানিং অ্যালগরিদম লিখিনি, তাই আমি সবেমাত্র ডিলিমিটারটি ছোট করে দিয়েছি যাতে এটি খুব বেশি সময় নষ্ট না করে।

var timer = new Stopwatch();
timer.Start();
using (FileStream fs = File.Open(file_path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    byte[] test_data = new byte[fs.Length];
    fs.Read(test_data, 0, test_data.Length);
    string delim = "--DXX";
    byte[] delim_checker = Encoding.UTF8.GetBytes(delim);

    for (int i = 0; i <= test_data.Length - delim_checker.Length; i++)
    {
        bool match = true;
        for (int j = i; j < i + delim_checker.Length; j++)
        {
            if (test_data[j] != delim_checker[j - i])
            {
                match = false;
                break;
            }
        }
        if (match)
        {
            break;
        }
    }
}
timer.Stop();
long test = timer.ElapsedMilliseconds;

এখন ফলাফলগুলি আমাকে দেখাচ্ছে যে ফর্ম-ডেটা পদ্ধতিটি আসলে উল্লেখযোগ্যভাবে ধীর হবে er নীচে দুটি পদ্ধতির জন্য সময়> 0 মিমি সহ ফলাফল রয়েছে:

File Size | FormData Time | Json/Base64 Time
181Kb       1ms             0ms
1352Kb      13ms            4ms
463Kb       4ms             5ms
133Kb       1ms             0ms
133Kb       1ms             0ms
129Kb       1ms             0ms
284Kb       2ms             1ms
1031Kb      9ms             3ms

দেখে মনে হচ্ছে না যে একটি অপ্টিমাইজড অ্যালগরিদম আমার ডিলিমিটারটি কেবল 5 টি অক্ষরের দীর্ঘ হিসাবে দেখে অনেক ভাল করবে do 3x আরও ভাল নয়, এটি একটি ডিলিমিটারের জন্য ফাইল বাইটগুলি পরীক্ষা করার পরিবর্তে একটি বেস 64 এনকোডিং করার পারফরম্যান্স সুবিধা।

স্পষ্টতই বেস 64৪ এনকোডিংটি প্রথম টেবিলের মতো দেখায় আকারটি বাড়িয়ে দেবে, তবে ইউনিকোড সক্ষম ইউটিএফ -8 এর সাথে এটি আসলে খুব খারাপ নয় এবং যদি ইচ্ছা হয় তবে ভালভাবে সংকোচিত হবে। তবে আসল সুবিধাটি হ'ল আমার কোডটি সুন্দর এবং পরিষ্কার এবং সহজেই বোধগম্য এবং এটি JSON রিকুয়েস্ট পেইলডটিকে অনেক বেশি দেখে আমার চোখের ছোঁয়াগুলিকে আঘাত করে না।

সুতরাং কেন পৃথিবীতে কেউ মাল্টিপার্ট / ফর্ম-ডেটা ব্যবহার না করে কেবল বেস 64 জেএসওনে ফাইলগুলি এনকোড করবে না? মানক রয়েছে, তবে এগুলি তুলনামূলকভাবে প্রায়শই পরিবর্তন হয়। স্ট্যান্ডার্ডগুলি ঠিক কীভাবে ঠিক পরামর্শ দেওয়া যায়?

উত্তর:


16

multipart/form-dataএইচটিএমএল ফর্মগুলির জন্য তৈরি একটি কনস্ট্রাক্ট। আপনি যেটি ইতিবাচক হিসাবে আবিষ্কার করেছেন সেটি multipart/form-dataহ'ল স্থানান্তর আকারটি স্থানান্তরিত হওয়া বস্তুর আকারের আরও কাছাকাছি - যেখানে কোনও পাঠ্যের এনকোডিং-এ বস্তুটির আকার বড় হয়ে যায়। আপনি বুঝতে পারবেন যে প্রোটোকলটি আবিষ্কার করা হয়েছিল তখন ইন্টারনেট ব্যান্ডউইথ সিপিইউ চক্রের চেয়ে মূল্যবান পণ্য ছিল।

ইন্টারনেট অনুযায়ী আমার একাধিক / ফর্ম-ডেটা অনুরোধ ব্যবহার করার কথা am

multipart/form-dataব্রাউজার আপলোডগুলির জন্য সেরা প্রোটোকল কারণ এটি সমস্ত ব্রাউজার দ্বারা সমর্থিত। এটি সার্ভার-থেকে-সার্ভার যোগাযোগের জন্য ব্যবহার করার কোনও কারণ নেই। সার্ভার-থেকে-সার্ভার যোগাযোগ সাধারণত ফর্ম-ভিত্তিক হয় না। যোগাযোগের জিনিসগুলি আরও জটিল এবং নেস্টিং এবং প্রকারের প্রয়োজন - JSON ভালভাবে পরিচালনা করে এমন প্রয়োজনীয়তা। বেইস 64 এনকোডিং হ'ল বাইনারি অবজেক্টগুলি স্থানান্তরিত করার জন্য একটি সহজ সমাধান যা আপনি বেছে নিন সিরিয়ালাইজেশন ফর্ম্যাটটিতে। সিবিওআর বা বিএসএনের মতো বাইনারি প্রোটোকলগুলি আরও ভাল কারণ তারা বেস 64৪ এর চেয়ে ছোট বস্তুগুলিকে সিরিয়ালাইজ করে এবং এগুলি জেএসএনের যথেষ্ট কাছে যে এটি একটি বিদ্যমান জেএসএন যোগাযোগের সহজ এক্সটেনশন (হওয়া উচিত)। সিপিইউ কার্যকারিতা বনাম বেস 64 সম্পর্কে নিশ্চিত নয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.