使用POST将大型(mp3)文件从android上传到node.js

时间:2015-02-18 13:50:38

标签: android node.js file-upload

我想从我的应用程序上传一个mp3文件到node.js。 node.js接受两个参数,即email_address和mp3文件。

以下是我使用的代码但未能达到所需的功能。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

FileInputStream fileInputStream = new FileInputStream(sourceFile);
                 URL url = new URL(SERVER_PATH);

             // Open a HTTP  connection to  the URL
             conn = (HttpURLConnection) url.openConnection(); 
             conn.setUseCaches(false); // Don't use a Cached Copy
             conn.setConnectTimeout(30000);
             conn.setDoInput(true); // Allow Inputs
             conn.setDoOutput(true); // Allow Outputs

             conn.setRequestMethod("POST");
             conn.setRequestProperty("Connection", "Keep-Alive");
             conn.setRequestProperty("ENCTYPE", "multipart/form-data");
             conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
             conn.setRequestProperty("user_file", fileName); 
             //conn.connect();                 

             dos = new DataOutputStream(conn.getOutputStream());

             dos.writeBytes(twoHyphens + boundary + lineEnd);
             dos.writeBytes("Content-Disposition: form-data; name=\"user_email\""+ lineEnd);
             dos.writeBytes(lineEnd);
             dos.writeBytes(EMAIL_ADDRESS);
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + lineEnd);

             dos.writeBytes("Content-Disposition: form-data; name=\"user_file\";filename=\"" + fileName +"\"" + 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);

             // Responses from the server (code and message)
             int serverResponseCode = conn.getResponseCode();
             String serverResponseMessage = conn.getResponseMessage();

             Log.i("uploadFile", "HTTP Response is : "
                     + serverResponseMessage + ": " + serverResponseCode);

             if(serverResponseCode == 200){

                 Toast.makeText(getApplicationContext() ,"File Upload Complete.", 
                         Toast.LENGTH_SHORT).show();

             }    

             //close the streams //
             fileInputStream.close();
             dos.flush();
             dos.close();

当我运行此代码时,我得到一个异常。抛出的异常对象也为null。因此,作为Android的初学者,我无法找到问题。

1 个答案:

答案 0 :(得分:2)

好像您使用android上传。因此,请在下面尝试一下。来自sheetalgiri enter link description here

的信用

创建MainActivity.java

package com.example.recorder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import org.json.JSONObject;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final AudioRecorder recorder=new AudioRecorder();
    final ImageButton recordButton=(ImageButton) findViewById(R.id.recordButton);
    recordButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if(motionEvent.getAction()==motionEvent.ACTION_DOWN)
                recorder.startRecording();
            if(motionEvent.getAction()==motionEvent.ACTION_UP) {
                recorder.stopRecording();
            }
            return false;
        }
    });
}
}

AudioRecorder.java

    package com.example.recorder;

    import android.media.MediaRecorder;
    import android.os.Environment;
    import android.util.Log;

    import org.json.JSONObject;

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;

    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Executor;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;

    /**
     * Created by home on 6/9/16.
     */
    public class AudioRecorder extends MediaRecorder {
        MediaRecorder recorder;
        String outputFile;
    void startRecording(){
        recorder=new MediaRecorder();
        outputFile= Environment.getExternalStorageDirectory().getAbsolutePath()+"/recording.amr";
        recorder.setAudioSource(AudioSource.MIC);
        recorder.setOutputFormat(OutputFormat.AMR_WB);
        recorder.setAudioEncoder(AudioEncoder.AMR_WB);
        recorder.setAudioSamplingRate(16000);
        try{
            recorder.setOutputFile(outputFile);
        }
        catch(Exception e){
            Log.e("Output File","failed");
        }

        try{
            recorder.prepare();
        }
        catch(IOException e){
            Log.e("Audio Record", "prepare() failed");
        }
        recorder.start();
    }

    void stopRecording(){
        recorder.stop();
        recorder.reset();
        recorder.release();
        upload();
    }

    void readFile(){
        InputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(outputFile));
        }
        catch(FileNotFoundException e){
            e.printStackTrace();
        }
        finally {
            if (in != null)
                try{
                    in.close();
                }
                catch(IOException e){
                    e.printStackTrace();
                }
        }
    }

    public void upload() {
        String response=null;
        AudioSender sender=new AudioSender(outputFile);
        FutureTask<String> uploadTask=new FutureTask<String>(sender);
        ExecutorService executorService= Executors.newFixedThreadPool(1);
        executorService.execute(uploadTask);
        while(true){
            if(uploadTask.isDone()){
                try{
                    response=uploadTask.get();
                    break;
                }catch(InterruptedException|ExecutionException e){
                    e.printStackTrace();
                    Log.e("Upload","Exception",e.getCause());
                }
            }
        }


        }

    }

AudioSender.java

    package com.example.recorder;

import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * Created by home on 6/11/16.
 */
public class AudioSender implements Callable<String> {

    String outputFile;

    AudioSender(String fileLocation){
        outputFile=fileLocation;
    }

    public String call(){

        File output=new File(outputFile);
        String response = new String ();
        try {
            MultipartUtility multipart = new MultipartUtility("http://10.42.0.1:3000/upload");
            multipart.addFilePart("audio", output);
            response = multipart.finish();
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            Log.d("SR", "SERVER REPLIED:");
            return response;
        }

    }
}

MultipartUtility.java

package com.example.recorder;

import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

public class MultipartUtility {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    private OutputStream outputStream;

    /**
     * This constructor initializes a new HTTP POST request with content type
     * is set to multipart/form-data
     *
     * @param requestURL
     * @throws IOException
     */
    public MultipartUtility(String requestURL)
            throws IOException {
        // creates a unique boundary based on time stamp
        boundary = "===" + System.currentTimeMillis() + "===";
        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setUseCaches(false);
        httpConn.setDoOutput(true);    // indicates POST method
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + boundary);
        outputStream = httpConn.getOutputStream();
    }


    /**
     * Adds a upload file section to the request
     *
     * @param fieldName  name attribute in <input type="file" name="..." />
     * @param uploadFile a File to be uploaded
     * @throws IOException
     */
    public void addFilePart(String fieldName, File uploadFile)
            throws IOException {
        String fileName = uploadFile.getName();
        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
            Log.d("sending",buffer.toString());
        }
        outputStream.flush();
        inputStream.close();
    }

    /**
     * Completes the request and receives response from the server.
     *
     * @return a list of Strings as response in case the server returned
     * status OK, otherwise an exception is thrown.
     * @throws IOException
     */
    public String finish() throws IOException {
        String response = new String();
        // checks server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    httpConn.getInputStream()));
            response=reader.readLine();
            reader.close();
            httpConn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }
        return response;
    }
}

server.js

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var port = process.env.PORT || 8080;
var globalres;

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});


var fs= require('fs');
var chunks=[];
var path='audio.amr';

app.get('/', function (req, res) {
    res.send('Hello world!');
});

app.get('/audio',function(req,res){
    res.sendFile(__dirname+'/audio.amr');
});
app.post('/upload',function(req,res){
     chunks=[];
     req.on('data',function(chunk){
        chunks.push(chunk);

     });

     req.on('end',function(){
        var data=Buffer.concat(chunks);
    fs.writeFile(path,data,'binary',function(err){
        if(err)
            console.log('couldnt make file'+err);
        else{
            console.log("Audio Recieved:");
            console.log(data);
        }
    });
     });
});

我测试过。运行了 我不知道管理员是否会看到此消息,但是当我回答文本时,我有点不知所措,总是向上和向下查看,为什么不直接使用可编辑的内容?