【问题标题】:Android: How to download a ftp file without being corrupted?Android:如何在不损坏的情况下下载 ftp 文件?
【发布时间】:2012-10-27 11:49:22
【问题描述】:

此代码现在可以使用。 LogCat 仅用于其他人的回退问题

如何从我的 ftp 服务器下载文件而不被损坏(下载的文件)? 我可以下载文件,但它有 0 字节....

但所有相同的 .txt、.png、.exe、.apk 文件在我的手机上每次都损坏/无法读取(0 字节)。 例如,我的 ftp 服务器上有一个名为 init.txt 的文件(其中包含以下文本:“testfileini!!”),它的大小在 ftp 上为 13 字节,在手机上为 0 字节。

OnItemClickListener(用于直接从 ftp 文件列表中选择文件)

lv.setOnItemClickListener(new OnItemClickListener() {
          public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              String file = (String) lv.getItemAtPosition(position);
              new DownloadFile().execute(file);   
          }

        });

AsyncTask 下载文件(用于后台下载)

    private class DownloadFile extends AsyncTask<String, Integer, String> {
    @Override
    protected String doInBackground(String... filename) {
        try {
            System.out.println("Filename->: " + filename[0]);
            GetFileFTP("/subdomains/giveyourapps/httpdocs/apps/"+filename[0], Environment.getExternalStorageDirectory() + "/Download/", filename[0]);

        } finally {
            disconnectFTP();
        }
        return null;
    }
}

GetFileFTP

public void GetFileFTP(String srcFileSpec, String destpath, String destname) {
    FTPClient client = new FTPClient();
    Log.v("pathSpec: ", destpath); 

    try {
        client.connect("176.28.25.46");
        client.login("ftp031220", "hSigSf");

        client.enterLocalPassiveMode();
        client.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);            

        InputStream input = client.retrieveFileStream(srcFileSpec);
        if(input != null) Log.v("GetFileFTP: ", "Input Stream Opened successfully");
        Log.v("Fileinputstream: ", srcFileSpec); 

        File output_file = new File(destpath + destname);
        Log.v("OUTPUTFILE: ", destpath + destname); 

        inputstreamcopy(input, output_file);

        disconnectFTP();

    }catch (IOException e) {
            Log.e("FTP", "Error Getting File");
            e.printStackTrace();
    }
 } 

copyInputStreamToFile

public static void inputstreamcopy(InputStream source,
        File destination){
    try {
        org.apache.commons.io.FileUtils.copyInputStreamToFile(source, destination);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

LogCat

11-07 15:09:08.675: D/GestureDetector(15746): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 3 mFalseSizeCnt:0
11-07 15:09:08.905: I/System.out(15746): status :: 211-Status of 'ProFTPD'

11-07 15:09:08.905: I/System.out(15746):  Connected from 109.164.221.167 (109.164.221.167)

11-07 15:09:08.905: I/System.out(15746):  Logged in as ftp031220

11-07 15:09:08.905: I/System.out(15746):  TYPE: BINARY, STRUcture: File, Mode: Stream

11-07 15:09:08.905: I/System.out(15746):  No data connection

11-07 15:09:08.910: I/System.out(15746): 211 End of status

11-07 15:09:09.025: D/dalvikvm(15746): GC_CONCURRENT freed 93K, 10% free 12464K/13703K, paused 15ms+12ms, total 58ms
11-07 15:09:09.390: I/System.out(15746): Files->: 1Tap_Cleaner_Pro_v1.45.apk
11-07 15:09:09.390: I/System.out(15746): Files->: AppBrain_App_Market_v7.5.apk
11-07 15:09:09.395: I/System.out(15746): Files->: Apparatus_v1.0.4_ADFREE_ANDROiD-P2P.apk
11-07 15:09:09.395: I/System.out(15746): Files->: Atomic_Bomber_5.0.apk
11-07 15:09:09.395: I/System.out(15746): Files->: IMG_20120917_120935.jpg
11-07 15:09:09.395: I/System.out(15746): Files->: init.txt
11-07 15:09:09.395: I/System.out(15746): Files->: unnamed.png
11-07 15:09:09.500: E/SpannableStringBuilder(15746): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
11-07 15:09:09.500: E/SpannableStringBuilder(15746): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
11-07 15:09:13.805: D/GestureDetector(15746): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 2 mFalseSizeCnt:0
11-07 15:09:13.880: I/System.out(15746): Filename->: init.txt
11-07 15:09:13.880: V/pathSpec:(15746): /storage/sdcard0/Download/
11-07 15:09:14.310: V/GetFileFTP:(15746): Input Stream Opened successfully
11-07 15:09:14.310: V/Fileinputstream:(15746): /subdomains/giveyourapps/httpdocs/apps/init.txt
11-07 15:09:14.310: V/OUTPUTFILE:(15746): /storage/sdcard0/Download/outputfile.txt
11-07 15:09:14.310: I/dalvikvm(15746): threadid=11: stack overflow on call to Lcom/mseiz/give/your/apps/MainSite;.copyInputStreamToFile:VLL
11-07 15:09:14.310: I/dalvikvm(15746):   method requires 8+20+8=36 bytes, fp is 0x5ec4b310 (16 left)
11-07 15:09:14.310: I/dalvikvm(15746):   expanding stack end (0x5ec4b300 to 0x5ec4b000)
11-07 15:09:14.315: I/dalvikvm(15746): Shrank stack (to 0x5ec4b300, curFrame is 0x5ec4eeb0)
11-07 15:09:14.315: W/dalvikvm(15746): threadid=11: thread exiting with uncaught exception (group=0x40d9f2a0)
11-07 15:09:14.375: D/dalvikvm(15746): GC_CONCURRENT freed 283K, 10% free 12654K/14023K, paused 14ms+11ms, total 47ms
11-07 15:09:14.405: D/dalvikvm(15746): GC_FOR_ALLOC freed 314K, 11% free 12682K/14215K, paused 10ms, total 10ms
11-07 15:09:14.405: E/AndroidRuntime(15746): FATAL EXCEPTION: AsyncTask #1
11-07 15:09:14.405: E/AndroidRuntime(15746): java.lang.RuntimeException: An error occured while executing doInBackground()
11-07 15:09:14.405: E/AndroidRuntime(15746):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at java.lang.Thread.run(Thread.java:856)
11-07 15:09:14.405: E/AndroidRuntime(15746): Caused by: java.lang.StackOverflowError
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(MainSite.java:119)
11-07 15:09:14.405: E/AndroidRuntime(15746):    at com.mseiz.give.your.apps.MainSite.copyInputStreamToFile(Ma
11-07 15:09:14.420: D/dalvikvm(15746): GC_CONCURRENT freed 553K, 12% free 12644K/14343K, paused 2ms+2ms, total 12ms
11-07 15:09:14.420: D/dalvikvm(15746): WAIT_FOR_CONCURRENT_GC blocked 9ms
11-07 15:09:14.440: D/dalvikvm(15746): GC_CONCURRENT freed 324K, 11% free 12802K/14343K, paused 1ms+2ms, total 17ms

【问题讨论】:

    标签: android ftp download apache-commons


    【解决方案1】:

    这一行:

    readBytes(input);
    

    什么都不做。您需要将这些返回的字节写入FileOutputStream。顺便说一句,考虑使用org.apache.commons.io.IOUtils.copy(InputStream, OutputStream) 或类似的。如果下载的文件足够大,将字节数组存储在内存中会抛出OutOfMemoryErrors

    更新:
    更好的是:
    org.apache.commons.io.FileUtils.copyInputStreamToFile(InputStream,File)

    【讨论】:

    • 我怎样才能将它添加到我的代码中? File input_file = new File(destpath + destname); copyInputStreamToFile(input, input_file); 到 GetFileFTP 和 public static void copyInputStreamToFile(InputStream source, File destination){ copyInputStreamToFile(source,destination); }
    • 是的,你会这样做。提示:file 参数是输出文件,它是您从 ftp 下载的文件,因此output_file 是该变量的更好名称。
    • 现在出现错误...我将根据我的问题发布新情况和当前代码...
    • 好的,刚刚阅读了您编辑的代码。您可以摆脱FileOutputStream。这在旧代码中用于编写下载的文件。现在copyInputStreamToFile 将为您做到这一点。该文件应该就在那里。
    • 一个StackOverflowError!大声笑在网上没有更好的网站来发布这个。问题出在您自己的 copyInputStreamToFile 函数中。您正在从内部递归调用它。您应该改用 ApacheIO 的那个。更好的是:只需直接调用 apache 函数。并获得 FileOutputStream 变量声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 2019-06-08
    • 2016-09-27
    • 2018-08-24
    相关资源
    最近更新 更多