【问题标题】:Android FTP file Upload [duplicate]Android FTP文件上传[重复]
【发布时间】:2013-08-25 03:52:09
【问题描述】:

我想将现有文件从我的 Android 上传到 FTP 服务器。

以下代码有效,但仅在其自己的项目中有效。

public class FtpConnectDemo {
    public static void main(String[] args) {
        uploadDatei(SERVER, "SERVER/htdocs/wa/data/ArtikelDatenbank.csv", "ArtikelDatenbank.csv", USER, PASSWORD);
    }



    public static void uploadDatei(String ftpServer, String pfadUndDateiName, String dateiName, String benutzer, String passwort) {
        StringBuffer sb = new StringBuffer("ftp://");

        sb.append(benutzer);
        sb.append(':');
        sb.append(passwort);
        sb.append('@');
        sb.append(ftpServer);
        sb.append('/');
        sb.append(pfadUndDateiName);
        sb.append(";type=a");

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            URL url = new URL(sb.toString());
            URLConnection urlc = url.openConnection();

            bos = new BufferedOutputStream(urlc.getOutputStream());
            bis = new BufferedInputStream(new FileInputStream(dateiName));

            int i;
            // read byte by byte until end of stream
            while ((i = bis.read()) != -1) {
                bos.write(i);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }
}

如果我将此代码包含到我的其他项目中,它将不再起作用。通过单击按钮调用该方法。 onClickListener 应该调用第二种方法uploadCsvAufServer()

这是我的另一个项目。

调用方法:

private void initObjekte() {

        dbHelper = new DBController(this);

        this.buttonSync = (Button) this.findViewById(R.id.button_sync);
        this.buttonSync.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // 1. Erstellen einer csv-Datei, die die Werte aus 1. enthält: OK
                Synchronisierung.this.saveUpdateDateiAufSdCard();

                // 2. Kopieren der Datei auf den Webserver
                Synchronisierung.this.uploadCsvAufServer();

                // Bisher als "nein" gekennzeichnete Werte werden als sychronisiert markiert und auf "ja" gesetzt
                Synchronisierung.this.dbHelper.updateSyncStatus();
                Synchronisierung.this.getNichtSyncedDaten();
            }
        });
}

调用方法:

public void uploadCsvAufServer() {

    StringBuffer sb = new StringBuffer("ftp://");
    sb.append(this.BENUTZER);
    sb.append(':');
    sb.append(this.PASSWORT);
    sb.append('@');
    sb.append(this.SERVER);
    sb.append('/');
    sb.append(this.SERVER_DATEINAME);
    sb.append(";type=a");

    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        URL url = new URL(sb.toString());
        URLConnection urlc = url.openConnection();

        bos = new BufferedOutputStream(urlc.getOutputStream());
        bis = new BufferedInputStream(new FileInputStream(this.DATEINAME));

        int i;
        // read byte by byte until end of stream
        while ((i = bis.read()) != -1)
        {
            bos.write(i);
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (bis != null) {
            try
            {
                bis.close();
            } catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
        }
        if (bos != null) {
            try
            {
                bos.close();
            } catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
        }
    }
}

来自以下 LogCatsee 的错误:

08-22 14:03:15.793: E/AndroidRuntime(773): FATAL EXCEPTION: main
08-22 14:03:15.793: E/AndroidRuntime(773): android.os.NetworkOnMainThreadException
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.net.InetAddress.getByName(InetAddress.java:289)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.net.InetSocketAddress.<init>(InetSocketAddress.java:105)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.net.InetSocketAddress.<init>(InetSocketAddress.java:90)
08-22 14:03:15.793: E/AndroidRuntime(773):  at libcore.net.url.FtpURLConnection.connectInternal(FtpURLConnection.java:219)
08-22 14:03:15.793: E/AndroidRuntime(773):  at libcore.net.url.FtpURLConnection.connect(FtpURLConnection.java:191)
08-22 14:03:15.793: E/AndroidRuntime(773):  at libcore.net.url.FtpURLConnection.getOutputStream(FtpURLConnection.java:339)
08-22 14:03:15.793: E/AndroidRuntime(773):  at de.noretec.nfcsync.view.Synchronisierung.uploadCsvAufServer(Synchronisierung.java:244)
08-22 14:03:15.793: E/AndroidRuntime(773):  at de.noretec.nfcsync.view.Synchronisierung$1.onClick(Synchronisierung.java:95)
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.view.View.performClick(View.java:4204)
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.view.View$PerformClick.run(View.java:17355)
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.os.Handler.handleCallback(Handler.java:725)
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.os.Handler.dispatchMessage(Handler.java:92)
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.os.Looper.loop(Looper.java:137)
08-22 14:03:15.793: E/AndroidRuntime(773):  at android.app.ActivityThread.main(ActivityThread.java:5041)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.lang.reflect.Method.invokeNative(Native Method)
08-22 14:03:15.793: E/AndroidRuntime(773):  at java.lang.reflect.Method.invoke(Method.java:511)
08-22 14:03:15.793: E/AndroidRuntime(773):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-22 14:03:15.793: E/AndroidRuntime(773):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-22 14:03:15.793: E/AndroidRuntime(773):  at dalvik.system.NativeStart.main(Native Method)
08-22 14:03:19.773: E/Trace(787): error opening trace file: No such file or directory (2)

有人知道我为什么会收到这些错误吗?

=======

更新:

=======

如您所说,这是 android.os.NetworkOnMainThreadException 的问题。我无法在主 (UI) 线程中使用网络接口。所以我尝试了一个从 AsyncTask 扩展的单独类。 现在我的应用不再崩溃,但会抛出警告。

08-22 17:14:24.852: W/System.err(780): java.io.IOException: Unable to connect to server: Unable to retrieve file: 550
08-22 17:14:24.870: W/System.err(780):  at libcore.net.url.FtpURLConnection.connect(FtpURLConnection.java:203)
08-22 17:14:24.870: W/System.err(780):  at libcore.net.url.FtpURLConnection.getOutputStream(FtpURLConnection.java:339)
08-22 17:14:24.870: W/System.err(780):  at de.noretec.nfcsync.controller.FileUpload.doInBackground(FileUpload.java:40)
08-22 17:14:24.870: W/System.err(780):  at de.noretec.nfcsync.controller.FileUpload.doInBackground(FileUpload.java:1)
08-22 17:14:24.878: W/System.err(780):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-22 17:14:24.878: W/System.err(780):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
08-22 17:14:24.878: W/System.err(780):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-22 17:14:24.878: W/System.err(780):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
08-22 17:14:24.878: W/System.err(780):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
08-22 17:14:24.878: W/System.err(780):  at java.lang.Thread.run(Thread.java:856)
08-22 17:14:26.148: W/System.err(780): java.io.IOException: Unable to connect to server: Unable to retrieve file: 550
08-22 17:14:26.148: W/System.err(780):  at libcore.net.url.FtpURLConnection.connect(FtpURLConnection.java:203)
08-22 17:14:26.148: W/System.err(780):  at libcore.net.url.FtpURLConnection.getOutputStream(FtpURLConnection.java:339)
08-22 17:14:26.148: W/System.err(780):  at de.noretec.nfcsync.controller.FileUpload.doInBackground(FileUpload.java:40)
08-22 17:14:26.148: W/System.err(780):  at de.noretec.nfcsync.controller.FileUpload.doInBackground(FileUpload.java:1)
08-22 17:14:26.148: W/System.err(780):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
08-22 17:14:26.148: W/System.err(780):  at java.util.concurrent.FutureTask.run(FutureTask.java:234)
08-22 17:14:26.148: W/System.err(780):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
08-22 17:14:26.148: W/System.err(780):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
08-22 17:14:26.148: W/System.err(780):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
08-22 17:14:26.148: W/System.err(780):  at java.lang.Thread.run(Thread.java:856)

要做一个异步线程,我想我必须使用 protected Void doInBackground(String... arg0) 方法。

这是我的实际代码。我不确定我是否为班级负责人使用了正确的表格: 公共类 FileUpload 扩展 AsyncTask 我没有任何参数,但我可以使用一个。

    public class FileUpload extends AsyncTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... arg0) {
        Server server = new Server();
        StringBuffer sb = new StringBuffer("ftp://");

        sb.append(server.getBenutzer());
        sb.append(':');
        sb.append(server.getPasswort());
        sb.append('@');
        sb.append(server.getFtpServer());
        sb.append('/');
        sb.append(server.getPfadUndDateiName());
        sb.append(";type=a");

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            URL url = new URL(sb.toString());
            URLConnection urlc = url.openConnection();

            bos = new BufferedOutputStream(urlc.getOutputStream());
            bis = new BufferedInputStream(new FileInputStream(server.getDateiName()));

            int i;
            // read byte by byte until end of stream
            while ((i = bis.read()) != -1)
            {
                bos.write(i);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try
                {
                    bis.close();
                } catch (IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }
            if (bos != null) {
                try
                {
                    bos.close();
                } catch (IOException ioe)
                {
                    ioe.printStackTrace();
                }
            }
        }
        return null;
    }



    protected void onProgressUpdate(Integer... progress) {

    }



    protected void onPostExecute(Long result) {

    }
}

=========

已解决

=========

我使用了一个从 AsyncTask 扩展而来的单独类。

我称之为:

new FTPFileUpload().execute(                    
    server.getFtpServer(),
    server.getBenutzer(),
    server.getPasswort(),
    Synchronisierung.this.notSyncedContent.toString(),
    server.getPfadUndDateiName());

使用:

public class FTPFileUpload extends AsyncTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... params) {
        FTPClient con = new FTPClient();
        try {

            con.connect(InetAddress.getByName(params[0]));

            if (con.login(params[1], params[2])) {
                con.enterLocalPassiveMode();
                String data = params[3];
                ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes());
                boolean result = con.storeFile(params[4], in);
                in.close();
                // if (result)
                // System.out.println("upload result: " + result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            con.logout();
            con.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

【问题讨论】:

  • -1 您是否尝试向 google 询问您的例外情况?
  • 对这个问题投了赞成票,因为其中的解决方案帮助了我 12-13 小时的斗争。谢谢!

标签: android file upload ftp


【解决方案1】:

尝试使用 Apache commons net ftp 库。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

public class FTPUploader {

    FTPClient ftp = null;

    public FTPUploader(String host, String user, String pwd) throws Exception{
        ftp = new FTPClient();
        ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
        int reply;
        ftp.connect(host);
        reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftp.disconnect();
            throw new Exception("Exception in connecting to FTP Server");
        }
        ftp.login(user, pwd);
        ftp.setFileType(FTP.BINARY_FILE_TYPE);
        ftp.enterLocalPassiveMode();
    }
    public void uploadFile(String localFileFullName, String fileName, String hostDir)
            throws Exception {
        try(InputStream input = new FileInputStream(new File(localFileFullName))){
        this.ftp.storeFile(hostDir + fileName, input);
        }
    }

    public void disconnect(){
        if (this.ftp.isConnected()) {
            try {
                this.ftp.logout();
                this.ftp.disconnect();
            } catch (IOException f) {
                // do nothing as file is already saved to server
            }
        }
    }

更新:

尝试使用 Thread 或服务中的代码,因为在高于 gingerbread 的 android 版本上,操作系统不允许你在 Ui 主线程上联网,所以这个 Exception 已经发生

 android.os.NetworkOnMainThreadException

要进一步阅读,请访问site.

更新:

尝试改变这一行

sb.append(";type=a");

sb.append(";type=i");

【讨论】:

  • 我尝试使用 AsyncTask。但是在我的更新下面还有其他警告。我不确定我是否使用了正确的 doInBackground() 语法方法。我没有任何参数,但我可以给一个。
  • 我把类型从a改成了i。没有改动。
  • 我使用了您的课程,但是在上传文件时,我得到的文件大小为零。我在拧什么?
【解决方案2】:

08-22 14:03:15.793: E/AndroidRuntime(773): 致命异常: main 08-22 14:03:15.793: E/AndroidRuntime(773): android.os.NetworkOnMainThreadException

问题出在 2.x + android 版本中,您无法在主 UI 线程上进行网络操作,因为您阻止了它。您应该使用 AsynTask 它非常适合这种操作。或者你创建一个 FileTransferThread 类。

【讨论】:

  • 我尝试使用 AsyncTask。但是在我的更新下面还有其他警告。我不确定我是否使用了正确的 doInBackground() 语法方法。我没有任何参数,但我可以给一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 2012-07-06
  • 1970-01-01
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多