java - 多文件上传只上传最后一个文件而不上传其余文件

标签 java php android file-upload

我创建了一个应用程序,它应该一个接一个地上传特定目录中的所有文件。该代码仅上传目录中的最后一个文件,而不是所有文件。

Activity 类:

public class UploadAudioDemo extends Activity {

    private static final int SELECT_AUDIO = 2;
    String selectedPath = "";

    ArrayList<String> selectedPathList = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_audio_demo);



        openGalleryAudio();
    }

    public void openGalleryAudio(){

        String name = null;

        File sdCardRoot = Environment.getExternalStorageDirectory();
        File yourDir = new File(sdCardRoot, "/My_records");
        for (File f : yourDir.listFiles()) 
        {
            if (f.isFile())
                name = f.getName();

            selectedPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/My_records/"+name;

            // Do your stuff
            Log.d("selectedPath", selectedPath);
            selectedPathList.add(selectedPath);
        }


        new Thread(new Runnable() 
        {
            public void run() 
            {
                runOnUiThread(new Runnable() 
                {
                    public void run() 
                    {

                    }
                });                      
                Iterator<String> it = selectedPathList.iterator();
                while (it.hasNext()) 
                {
                    doFileUpload(it.next()+"");
                }

            }
        }).start();    

    }


    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    private void doFileUpload(String myFileUrl)
    {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary =  "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1*1024*1024;
        String responseFromServer = "";
        String urlString = "http://bumba27.byethost16.com/Tracker/Services/recordedAudio/file_upload_new.php?mb_code='mb_code1'";

        try
        {
            //------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(myFileUrl) );
            // 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=\"" + selectedPath + "\"" + 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
            Log.e("Debug","File is written");
            fileInputStream.close();
            dos.flush();
            dos.close();
        }
        catch (MalformedURLException ex)
        {
            Log.e("Debug", "error: " + ex.getMessage(), ex);
        }
        catch (IOException ioe)
        {
            Log.e("Debug", "error: " + ioe.getMessage(), ioe);
        }
        //------------------ read the SERVER RESPONSE
        try {
            inStream = new DataInputStream ( conn.getInputStream() );
            String str;

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

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

logcat 报告:

/storage/sdcard0/My_records/10_12_2013_13_00_12.amr
/storage/sdcard0/My_records/10_12_2013_13_01_27.amr
File is written
Server Response The file is: 10_12_2013_13_01_27.amr and mb_code is: 'mb_code1'
File is written
Server Response The file is: 10_12_2013_13_01_27.amr and mb_code is: 'mb_code1'

从 logcat 输出我们可以了解到,在迭代数组时,我们获取了两个文件链接,但在上传时只上传了最后一个文件。

我错过了什么?如何纠正?

最佳答案

我认为问题在于您对所有上传使用相同的后台线程。

也就是说,它开始上传文件 1..n-1,但不断被上传下一个 n+1 文件的新需求打断。最后一个文件上传没有中断,因此成功。

我建议查看 IntentServices:http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/

有了用于上传文件的 IntentService,您可以直接在 UI 线程中对文件进行简单循环。

for (filesYouWantToUpload) {
     Intent i = new Intent(context, UploadIntentService.class);
     i.putStringExtra(file);
     startService(i);
}

编辑:

无法测试代码,但它应该看起来像这样。

FileUploader IntentService:

public class FileUploader extends IntentService {

private static final String TAG = FileUploader.class.getName();


public FileUploader() {
    super("FileUploader");
}

@Override
protected void onHandleIntent(Intent intent) {

    String selectedPath = intent.getStringExtra("selectedPath");
    String myFileUrl = intent.getStringExtra("myFileUrl");

    doFileUpload(selectedPath, myFileUrl);

}

 private void doFileUpload(String selectedPath, String myFileUrl)
    {
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        DataInputStream inStream = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary =  "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1*1024*1024;
        String responseFromServer = "";
        String urlString = "http://bumba27.byethost16.com/Tracker/Services/recordedAudio/file_upload_new.php?mb_code='mb_code1'";

        try
        {
            //------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(myFileUrl) );
            // 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=\"" + selectedPath + "\"" + 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
            Log.e("Debug","File is written");
            fileInputStream.close();
            dos.flush();
            dos.close();
        }
        catch (MalformedURLException ex)
        {
            Log.e("Debug", "error: " + ex.getMessage(), ex);
        }
        catch (IOException ioe)
        {
            Log.e("Debug", "error: " + ioe.getMessage(), ioe);
        }
        //------------------ read the SERVER RESPONSE
        try {
            inStream = new DataInputStream ( conn.getInputStream() );
            String str;

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

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

 }

记得更新你的 list :

 <service android:name="yourpackage.FileUploader " />

最后 openGalleryAudio() 会是这样的:

  public void openGalleryAudio(){

    String name = null;

    File sdCardRoot = Environment.getExternalStorageDirectory();
    File yourDir = new File(sdCardRoot, "/My_records");
    for (File f : yourDir.listFiles()) 
    {
        if (f.isFile())
            name = f.getName();

        selectedPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/My_records/"+name;

        // Do your stuff
        Log.d("selectedPath", selectedPath);
        selectedPathList.add(selectedPath);
    }



    Iterator<String> it = selectedPathList.iterator();
    while (it.hasNext()) 
    {
        Intent i = new Intent(this, FileUploader.class)
        i.putExtra("selectedPath", selectedPath);
        i.putExtra("myFileUrl", it.next()+"");
        startService(i);
    }


}

关于java - 多文件上传只上传最后一个文件而不上传其余文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20518260/

相关文章:

java - 如何在 OSGi 中欺骗 java 包(以及 API 的一部分)?

java - Android折叠工具栏在折叠时没有隐藏其他元素

java - 如何创建 Exp(-x^2) 函数?

java - 如何使用 spring boot + .yaml 创建配置文件?

php - jQuery UI 自动完成显示 html 代码

php - 在 Laravel 中的每个急切加载的元素上使用 Eloquent 作用域

java - 通知监听器服务 UI 更新

android - Eclipse 将您的 apk 文件(您正在开发和测试的)放在哪里?

php - Paypal 金额篡改

android - 如何在 Android 10 中替换 FileObserver?