在2个android设备之间传输文件

时间:2015-07-10 12:49:19

标签: android file upload

我想在两个设备,服务器和客户端之间传输文件..我在客户端有一点问题。 我在logcat中遇到了这个错误:

java.lang.ArrayIndexOutOfBoundsException: length=1024; regionStart=0; regionLength=-1

如果我的代码错了请告诉我。我想制作一个应用程序,我正在进行4天的转移工作。它让我觉得糟透了。请帮忙

这是客户:

package com.example.test;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Bundle;
import android.os.Environment;

public class MainActivity extends ActionBarActivity {

    EditText editTextAddress;
    Button buttonConnect;
    TextView textPort;

    static final int SocketServerPORT = 8000;

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

        editTextAddress = (EditText) findViewById(R.id.address);
        textPort = (TextView) findViewById(R.id.port);
        textPort.setText("port: " + SocketServerPORT);
        buttonConnect = (Button) findViewById(R.id.connect);

        buttonConnect.setOnClickListener(new OnClickListener(){

                @Override
                public void onClick(View v) {
                ClientRxThread clientRxThread = 
                new ClientRxThread(
                        editTextAddress.getText().toString(), 
                        SocketServerPORT);

                clientRxThread.start();
                }});
    }

    private class ClientRxThread extends Thread {
        String dstAddress;
        int dstPort;

        ClientRxThread(String address, int port) {
            dstAddress = address;
            dstPort = port;
        }

        @Override
        public void run() {
            Socket socket = null;

            try {
                socket = new Socket(dstAddress, dstPort);

                File file = new File(
                        Environment.getExternalStorageDirectory(), 
                        "input.jpg");

                byte[] bytes = new byte[1024];
                InputStream is = socket.getInputStream();
                FileOutputStream fos = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                int bytesRead = is.read(bytes, 0, bytes.length);
                bos.write(bytes, 0, bytesRead);
                bos.close();
                socket.close();

                MainActivity.this.runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                        Toast.makeText(MainActivity.this, 
                                "Finished", 
                                Toast.LENGTH_LONG).show();
                        }});

            } catch (IOException e) {

                e.printStackTrace();

                final String eMsg = "Something wrong: " + e.getMessage();
                MainActivity.this.runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                        Toast.makeText(MainActivity.this, 
                                eMsg, 
                                Toast.LENGTH_LONG).show();
                        }});

            } finally {
                if(socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}

client xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidsocketfiletransferclient.MainActivity" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:autoLink="web"
    android:text="http://android-er.blogspot.com/"
    android:textStyle="bold" />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="File Transfer Client"
    android:textStyle="bold" />

<EditText
    android:id="@+id/address"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="dstAddress" />

<TextView
    android:id="@+id/port"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:id="@+id/connect"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Connect..." />

客户端清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >

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

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

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="19" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.test.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

服务器:

package com.example.testserverandroid;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

TextView infoIp, infoPort;

static final int SocketServerPORT = 8000;
ServerSocket serverSocket;

ServerSocketThread serverSocketThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    infoIp = (TextView) findViewById(R.id.infoip);
    infoPort = (TextView) findViewById(R.id.infoport);

    infoIp.setText(getIpAddress());

    serverSocketThread = new ServerSocketThread();
    serverSocketThread.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();

    if (serverSocket != null) {
        try {
            serverSocket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

private String getIpAddress() {
    String ip = "";
    try {
        Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                .getNetworkInterfaces();
        while (enumNetworkInterfaces.hasMoreElements()) {
            NetworkInterface networkInterface = enumNetworkInterfaces
                    .nextElement();
            Enumeration<InetAddress> enumInetAddress = networkInterface
                    .getInetAddresses();
            while (enumInetAddress.hasMoreElements()) {
                InetAddress inetAddress = enumInetAddress.nextElement();

                if (inetAddress.isSiteLocalAddress()) {
                    ip += "SiteLocalAddress: "
                            + inetAddress.getHostAddress() + "\n";
                }

            }

        }

    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        ip += "Something Wrong! " + e.toString() + "\n";
    }

    return ip;
}

public class ServerSocketThread extends Thread {

    @Override
    public void run() {
        Socket socket = null;

        try {
            serverSocket = new ServerSocket(SocketServerPORT);
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    infoPort.setText("I'm waiting here: "
                            + serverSocket.getLocalPort());
                }
            });

            while (true) {
                socket = serverSocket.accept();
                FileTxThread fileTxThread = new FileTxThread(socket);
                fileTxThread.start();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

}

public class FileTxThread extends Thread {
    Socket socket;

    FileTxThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        File file = new File(Environment.getExternalStorageDirectory(),
                "test.txt");

        byte[] bytes = new byte[(int) file.length()];
        BufferedInputStream bis;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            bis.read(bytes, 0, bytes.length);
            OutputStream os = socket.getOutputStream();
            os.write(bytes, 0, bytes.length);
            os.flush();
            socket.close();

            final String sentMsg = "File sent to: "
                    + socket.getInetAddress();
            MainActivity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, sentMsg,
                            Toast.LENGTH_LONG).show();
                }
            });

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}
}

服务器清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >

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

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

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="19" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.test.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

1 个答案:

答案 0 :(得分:0)

在您的客户端中,当您从输入流中读取时,如果您已经在流的末尾,则读取的字节数将为-1。这在documentation for InputStream

中有所描述

执行此语句并且ArrayIndexOutOfBoundsException为-1时发生bytesRead异常。

bos.write(bytes, 0, bytesRead);

您需要重新构建读取输入流的客户端代码,以检查流末尾。

替换它:

int bytesRead = is.read(bytes, 0, bytes.length);
bos.write(bytes, 0, bytesRead);

有了这个:

int bytesRead;
while ((bytesRead = is.read(bytes)) > 0) {
    bos.write(bytes, 0, bytesRead);
}