Httpslconnication মাল্টিপার্ট / ফর্ম-ডেটা ব্যবহার করে অ্যারেলিস্ট আপলোড করুন


11

আমার Arraylistকোনও লাইব্রেরি ব্যবহার না করেই সার্ভারে ছবি আপলোড করা দরকার । আমি Asynctaskএকক চিত্র আপলোড করতে ব্যবহার করছি এবং এটি httpslconnication মাল্টিপার্ট / ফর্ম-ডেটার সাহায্যে নিখুঁতভাবে কাজ করছে। এখন ব্যবহার করে যে কোনও ধরণের একাধিক ফাইল আপলোড করার জন্য আমার কোডটি পরিবর্তন করতে হবে Arraylist<String>তবে আমার সমস্যাটি হ'ল FileinputStreamকোডগুলি অ্যারেলিস্ট সমর্থন করে না Fileinputstreamএবং সার্ভারে অ্যারেলিস্ট আপলোড করার পরিবর্তে আমি কী ব্যবহার করব তা আমার ধারণা নেই এবং আমিও করি না এটির জন্য যে কোনও গ্রন্থাগার ব্যবহার করতে চাই।

public class multipart_test extends AsyncTask<Void,Void,String> {
    Context context;
    String Images;
    public static final String TAG = "###Image Uploading###";


    public multipart_test(Context context,String Upload_Images) {
        this.context = context;
        this.Images = Upload_Images;

    }

    @Override
    protected String doInBackground(Void... params) {
        BufferedReader reader;
        String WebPath = null;
        try {
            String lineEnd = "\r\n";
            String twoHyphens = "--";
            String boundary = "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 1024 * 1024;
            //todo change URL as per client ( MOST IMPORTANT )
            URL url = new URL("10.0.0.1/uploadMultipart.php");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // Allow Inputs &amp; Outputs.
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);

            // Set HTTP method to POST.
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            FileInputStream fileInputStream;
            DataOutputStream outputStream;
            outputStream = new DataOutputStream(connection.getOutputStream());
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);

            outputStream.writeBytes("Content-Disposition: form-data; name=\"reference\""+ lineEnd);
            outputStream.writeBytes(lineEnd);
            //outputStream.writeBytes("my_refrence_text");
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);

            outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadFile\";filename=\"" + "profileImage" +"\"" + lineEnd);
            outputStream.writeBytes(lineEnd);

            //Dummy ArrayList for upload
            ArrayList<String> uploadFiles = new ArrayList<>();
            uploadFiles.add(Images);
            uploadFiles.add(Images);
            uploadFiles.add(Images);
            uploadFiles.add(Images);


            fileInputStream = new FileInputStream(uploadFiles); // NOT SUPPORTING ARRAYLIST HERE
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

            // Read file
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            while (bytesRead > 0) {
                outputStream.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                fileInputStream.close();
            }
            // Responses from the server (code and message)
            int serverResponseCode = connection.getResponseCode();
            String result = null;
            if (serverResponseCode == 200) {
                StringBuilder s_buffer = new StringBuilder();
                InputStream is = new BufferedInputStream(connection.getInputStream());
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String inputLine;
                while ((inputLine = br.readLine()) != null) {
                    s_buffer.append(inputLine);
                }
                result = s_buffer.toString();
            }
            connection.getInputStream().close();
            outputStream.flush();
            outputStream.close();
            if (result != null) {
                Log.d("result_for upload", result);
            }
            return WebPath;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


}

আমি FileInputStreamলুপে রাখার চেষ্টাও করেছি তবে একাধিক অনুরোধে চিত্রগুলি আপলোড করা আমি চাই তা নয়। আমার সার্ভারের এন সংখ্যার চিত্রের জন্য একক অনুরোধ করার জন্য অ্যাপটির প্রয়োজন require যে কোনও সহায়তা প্রশংসিত হবে তবে কোনও লাইব্রেরি ব্যবহার ছাড়াই


এইচটিপি ক্লাসগুলি অবচিত করা হয়েছে, পুনঃনির্মাণ বা অন্যান্য গ্রন্থাগার ব্যবহার করুন
জয়প্রকাশ সনি

আপনি একক অনুরোধে retrofit ব্যবহার করতে এবং একাধিক চিত্র আপলোড করতে পারেন
প্রিয়ঙ্কব

উত্তর:


4

দ্রষ্টব্য যে এই কোডটি নিখুঁতভাবে এইচটিটিপিআরএল সংযোগের সাথে কাজ করে তবে আমি চেষ্টা করিনি।

আমি ইন্টারনেট থেকে যা পড়েছি তা থেকে আপনি এখনও উল্লিখিত লুপটি ব্যবহার করতে পারেন তবে কিছু সংশোধন করে।

আমি এখানে ডিভ.টো.র জন্য মাল্টিপার্ট / ফর্ম-ডেটা সম্পর্কিত টিউটোরিয়ালটি অনুসরণ করেছি , একটি আরও শেখার পোস্ট তৈরি করতে আমি আপনাকে বলব যে এই পদ্ধতিটি কী হওয়া উচিত is

একাধিক / ফর্ম-ডেটা ভালো পাঠানো হয়

--boundary
Content-Disposition: form-data; name="something1"

data1
--boundary
Content-Disposition: form-data; name="something2"

data2
--boundary--

আমি যা করব তা হল একটি নতুন পদ্ধতি তৈরি করা তবে আপনি কেবল ইতিমধ্যে বিদ্যমান পদ্ধতিতে কোডটি লিখতে পারেন।

public byte[] get_multipart_data(List<String> files, String boundary)

তোমাদের কাছে লিখলাম চান সীমানা দ্বারা অনুসরণ স্বভাব এবং তারপর ডাটা । সমস্ত ফাইলের জন্য এটি করুন এবং তারপরে আপনি ক্লোজিং বাউন্ডারিটি প্রেরণ করুন । এটি আপনার পছন্দসই মাল্টিপার্ট / ফর্ম-ডেটা কাঠামো তৈরি করবে ।

স্যুডো-কোডে এটি হবে

loop for all files
    write "--boundary"
    write "Content-Disposition: ...."
    write image_data
end
write "--boundary--"

কোডটি এভাবে লেখা যেতে পারে, প্রথমে আপনার ভেরিয়েবলগুলি সংজ্ঞায়িত করুন

ByteArrayOutputStream message = null;
DataOutputStream stream = null;

FileInputStream fileInputStream;

int maxBufferSize = 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
byte[] sendData = new byte[0];

এখানে ডেটা উত্পন্ন হবে। এটি সীমানা নির্ধারণ করে এবং তারপরে ডেটা পড়ার সাথে শুরু হয় । সেই ডেটা স্ট্রিমে লেখা এবং আপনি সমস্ত ফাইল / চিত্রের লুপ চালিয়ে যান।

try {
    message = new ByteArrayOutputStream();
    stream = new DataOutputStream(message);

    // Loop though all file names
    for(String fileName : files) {
        stream.writeBytes("--" + boundary + "\r\n"); // Start boundary
        stream.writeBytes("Content-Disposition: form-data; name=\"" + fileName + "\"\r\n\r\n");

        // Read the image data
        fileInputStream = new FileInputStream(fileName);
        int readBytes = 0;
        while((readBytes = fileInputStream.read(buffer)) != -1) {
            // Write file data to output
            stream.write(buffer, 0, readBytes);
        }
        fileInputStream.close();

        stream.writeBytes("\r\n");
    }
    stream.writeBytes("--" + boundary + "--\r\n"); // Closing boundary

    sendData = message.toByteArray();
} catch(IOException e) {
    e.printStackTrace();
}

এখন বাইট অ্যারের sendDataউপস্থিত থাকবে একাধিক / ফর্ম-ডেটা যা আপনি আপনার HttpURLConnection সঙ্গে পাঠাতে হবে।

আমি এখানে দীর্ঘকাল ধরে সক্রিয় ছিলাম না। আপনার যদি আরও কিছু নির্দিষ্টকরণের প্রয়োজন হয় বা আমি আমার পাঠ্যটি স্পষ্ট করে বলি: ডি


আমি যদি লুপ চালাই তবে অ্যারে আপলোডের জন্য আমার একাধিক অনুরোধ করা দরকার। আমার একক কলে সার্ভারে একটি অ্যারে আপলোড করতে হবে।
রিতু

আমি যে বিষয়টিকে আন্ডারটড করি তা থেকে আপনি একক এইচটিটিপিআরএল সংযোগ কলটিতে সার্ভারে এন চিত্রগুলি প্রেরণ করতে চান। আপনি একটি জিপ ফর্ম্যাট ব্যবহার করার চেষ্টা করতে পারেন যেখানে আপনি জিপইন্ট্রি দিয়ে ফাইলগুলি ইনপুট করুন অন্যথায় আমি যা লিখেছি তা কেবল একটি অনুরোধ হবে। @ রিতু
হার্ডকোড

আপনার পক্ষে এটি কি সম্ভব যে আপনার অ্যাসিনটাস্কের বাইরে লুপ ব্যবহার করে? । উদাহরণস্বরূপ, যদি আপনার কাছে আপলোডের জন্য 3 টি ফাইল থাকে তবে আপনি 3 টি অ্যাসিনটাস্ক স্বাধীনভাবে কার্যকর করেন। এইভাবে যদি কোনও চিত্র (আপলোড প্রক্রিয়া) এর জন্য কোনও সমস্যা বা সমস্যা খুঁজে পাওয়া যায়, অন্য চিত্রগুলি (প্রক্রিয়াগুলি) আপলোড করা চালিয়ে যায় every প্রতিটি অ্যাসিঙ্কটাস শেষ হলে আপনি পারেন আপনার ক্লাসে কাউন্টার হিসাবে গণনা করুন এবং প্রয়োজনে একটি বিলম্বের সময় (আনুমানিক সময়) রাখুন (আপলোড করার ক্ষেত্রে কোনও সমস্যার জন্য সতর্কতার জন্য)।
মানিক

1
@ মানিয়াক এটি একই কাজের জন্য একাধিক অ্যাসিঙ্কটাস্ক চালানোর জন্য সর্বোত্তম কোড নয়। আমরা যেখানেই পারি নেটওয়ার্ক কল এড়ানো উচিত।
অ্যান্ড্রয়েডএক্সপি

0

ফাইল ইনপুট স্ট্রিম অ্যারেলিস্ট সমর্থন করে না। তবে অবজেক্টআউটপুট স্ট্রিম ব্যবহার করে চারপাশে একটি উপায় রয়েছে । এটি আপনার অ্যারেলিস্টকেও সিরিয়ালাইজ করবে। কোডের পরিবর্তনগুলি পরীক্ষা করুন।

       //Changes required in your code
        ArrayList<String> uploadFiles = new ArrayList<>();
        uploadFiles.add(Images);
        uploadFiles.add(Images);
        uploadFiles.add(Images);
        uploadFiles.add(Images);

        fileInputStream = new FileInputStream("listImages"); 
        java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(fileInputStream); 
        oos.writeObject(uploadFiles);

        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, maxBufferSize);
        buffer = new byte[bufferSize];
        ...
        ...
        ...
        oos.close();

শুভ কোডিং :)


0

সিঙ্গেল অ্যাসিঙ্ক টাস্কটি ব্যবহার করা আপনার পক্ষে আবশ্যক কিনা তা নিশ্চিত নয়।

যেমনটি আপনি বলেছেন, আপনার কোড একক চিত্রের জন্য একেবারে সূক্ষ্ম কাজ করে। সুতরাং অ্যারেলিস্ট থেকে একাধিক ফাইল আপলোড করার জন্য আপনাকে কেবল আপনার অ্যাসিঙ্কটাস্কটি কিছুটা পরিবর্তন করতে হবে। একের পর এক ফাইল আপলোড করুন বা আপনি যদি এত বেশি পরিবর্তন করতে না চান তবে কেবল আপলোড করা আইটেমের সূচী ধারণ করে বৈশ্বিক পরিবর্তনশীল ঘোষণা করুন এবং অনপোস্টএকসিকিউটে অ্যাসিঙ্ক টাস্কের নতুন উদাহরণ তৈরি করুন এবং পরবর্তী আইটেমটি অ্যারেলিস্টে পাস করুন। আশা করি এটি পরিষ্কার হয়ে গেছে।

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