1

私は使用しようとしました:

@Override
    protected String doInBackground(Void... params) {
        // TODO Auto-generated method stub
        String path = "http://192.168.1.112/johnson/learn/android/uploads/";
        String sUrl1 = "productSock";
        String sUrl2 = "productHistory";
        downloadFile(path, sUrl2);
        downloadFile(path, sUrl1);
        return null;
    }

    private boolean downloadFile(String path, String sUrl) {
        // TODO Auto-generated method stub
        try {
            String toUrl = path + sUrl;
            URL url = new URL(toUrl);
            URLConnection connection = url.openConnection();
            connection.connect();
            // this will be useful so that you can show a typical 0-100%
            // progress bar
            int fileLength = connection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(Environment
                    .getExternalStorageDirectory().getAbsolutePath()
                    + "/Android/data/com.android.avs.amp.inventory/files/"
                    + sUrl);

            byte data[] = new byte[1024];
            long total = 0;
            int count = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                publishProgress((int) (total * 100 / fileLength));
                output.write(data);
            }
            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {
        }
        return true;
    }

2 番目のファイルをアップロードすると、31% でスタックし、最初のファイルでも 0% でスタックすることがある

コードを変更するには?または他の方法?

そして私のアップロード

@Override
    protected Boolean doInBackground(Void... params) {
        // TODO Auto-generated method stub
        uploadFile("productStock");
        uploadFile("productHistory");
        return false;
    }

    private void uploadFile(String path) {
        // TODO Auto-generated method stub
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String existingFileName = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/Android/data/com.android.avs.amp.inventory/files/"+path;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        String responseFromServer = "";
        String urlString = "http://192.168.1.112/johnson/learn/android/";
        try {
            // ------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(
                    existingFileName));
            // open a URL connection to the Servlet
            URL url = new URL(urlString);
            // Open a HTTP connection to the URL
            conn = (HttpURLConnection) url.openConnection();
            // Allow Inputs
            conn.setDoInput(true);
            // Allow Outputs
            conn.setDoOutput(true);
            // Don't use a cached copy.
            conn.setUseCaches(false);
            // Use a post method.
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);
            dos = new DataOutputStream(conn.getOutputStream());
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
                    + existingFileName + "\"" + lineEnd);
            dos.writeBytes(lineEnd);
            // create a buffer of maximum size
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];
            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
            }
            // send multipart form data necesssary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            // close streams
            fileInputStream.close();
            dos.flush();
            dos.close();
        } catch (MalformedURLException ex) {
            // Log.e("Debug", "error: " + ex.getMessage(), ex);
            mErrorMsg = "error: " + ex.getMessage();
        } catch (IOException ioe) {
            // Log.e("Debug", "error: " + ioe.getMessage(), ioe);
            mErrorMsg = "error: " + ioe.getMessage();
        } 
        // ------------------ read the SERVER RESPONSE
        try {
            inStream = new DataInputStream(conn.getInputStream());
            String str;

            while ((str = inStream.readLine()) != null) {
                // Log.e("Debug", "Server Response " + str);
                mErrorMsg = "Upload Successful";
            }
            inStream.close();

        } catch (IOException ioex) {
            // Log.e("Debug", "error: " + ioex.getMessage(), ioex);
            mErrorMsg = "error: " + ioex.getMessage();
        }
    }

アップロードするファイルが存在しない場合、進行状況ダイアログでスタックしますか、または複数のファイルをアップロードするためのより良い方法はありますか?

前もって感謝します

4

1 に答える 1

1

コードが特定の割合でハングする原因はわかりませんが、破損したデータが生成される理由はわかります。

アップロード/ダウンロード コードでは、このメソッドを使用して読み取りバイトを書き込みます。

stream.write(buffer, 0, bufferSize);

さて、これの問題は、write(byte[], int, int)-methodに長さの間違ったパラメーターを与えていることです。

ストリームから読み取る場合、read()-method は以下を返します

戻り値: buffer に読み取られた合計バイト数、またはストリームの終わりに達したためにそれ以上データがない場合は -1。

つまり、byte[]配列の長さがbuffer_sizeバイト長 (たとえば 1024) であっても、読み取られる場所が 1024 バイトであることを意味するわけではありません (バッファがいっぱいでないなど、それよりも少ない可能性があります)。読み取られた実際のバイト数は、メソッドによって返されますread()

そのため、メソッドwrite()に書き込むバイト数が間違っているため、ファイルが破損する null バイトが書き込まれます。

正しい実装は次のようになります。

byte data[] = new byte[1024];
int read_count = 0;
while ((read_count = input.read(data, 0, data.length)) != -1) {
    output.write(data, 0, read_count);
}

バイナリ データをアップロードしない場合は、通常、既にバッファリングされているライター実装 ( BufferedWriter / BufferedReaderなど) を使用することをお勧めします。


このトピックについては、このブログ投稿でもう少し詳しく説明しました:バッファリングされていないストリームの作業

于 2012-08-10T09:57:00.107 に答える