【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能_第5頁
免費預(yù)覽已結(jié)束,剩余1頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能

Android中怎么利用FTP實現(xiàn)多線程斷點續(xù)傳下載上傳功能,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面在下將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。FTP下載原理FTP單線程斷點續(xù)傳FTP和傳統(tǒng)的HTTP協(xié)議有所不同,由于FTP沒有所謂的頭文件,因此我們不能像HTTP那樣通過設(shè)置header向服務(wù)器指定下載區(qū)間。但是FTP協(xié)議提供了一個更好用的命令REST用于從指定位置恢復(fù)任務(wù),同時FTP協(xié)議也提供了一個命令SIZE用于獲取下載的文件大小,有了這兩個命令,F(xiàn)TP斷點續(xù)傳也就沒有什么問題。FTP斷點續(xù)傳的原理和HTTP的斷點續(xù)傳原理差不多,在暫停時記錄文件的停止位置,再次下載時,先讀取記錄的位置,如果位置存在,則通過REST命令告訴服務(wù)器從指定區(qū)間進行下載。FTP多線程斷點續(xù)傳多線程下載的原理和HTTP多線程下載的原理差不多。先獲取文件大小,然后根據(jù)線程數(shù),對整個文件進行分段下載,在任務(wù)停止時,記錄每一條線程的暫停位置,重新開始下載,每一條線程讀取對應(yīng)的下載記錄,然后每一線程從指定位置開始下載。分段下載和HTTP所不同的是,F(xiàn)TP并沒有提供文件區(qū)間的API,因此,F(xiàn)TP在分段下載中,只有起始位置而沒有結(jié)束位置。因此,你需要在指定位置手動停止線程。功能實現(xiàn)本文使用將采用apachecommons-net實現(xiàn)FTP斷點續(xù)傳下載\上傳功能。<br>通過下文的幾步操作,你就能很簡單的實現(xiàn)FTP斷點續(xù)傳。登錄FTP協(xié)議和HTTP協(xié)議有所不同,使用FTP進行下載時,你需要進行登錄操作。當(dāng)然,如果你服務(wù)器沒有登錄功能,你可以忽略登錄操作。FTPClient

client

=

new

FTPClient();

client.connect(serverIp,

port);

//連接到FTP服務(wù)器

client.login(userName,

passsword);通過上面三行代碼,就可以很簡單的登錄到FTP服務(wù)器上。在進行登錄后,還需要驗證是否登錄成功int

reply

=

client.getReplyCode();

if

(!FTPReply.isPositiveCompletion(reply))

{

client.disconnect();

Log.d(TAG,

"無法連接到ftp服務(wù)器,錯誤碼為:"

+

reply);

return;

}由于FTP協(xié)議中,連接成功的狀態(tài)有多個,因此需要通過FTPReply.isPositiveCompletion(reply)用于驗證是否成功連接到FTP服務(wù)器。文件信息獲取在連接到FTP服務(wù)器后,就需要開始獲取下載最重要的幾個參數(shù)(文件長度、文件名)。客戶端可以通過client.listFiles(remotePath)獲取FTP服務(wù)器上該路徑的文件列表。如果路徑是文件,只會返回一個長度為1的數(shù)組。如果該路徑為文件夾,則會返回該文件夾下對應(yīng)的所有文件。String

remotePath

=

"/upload/qjnn.apk";

//FTP服務(wù)器上文件路徑

FTPFile[]

files

=

client.listFiles(remotePath);

FTPFile

file

=

files[0];

//文件信息

long

size

=

file.getSize();

String

fileaName

=

file.getName();如果你的文件為英文名,并且路徑中沒有中文,那么通過上述代碼,便可以獲取到正確的文件信息。但如果FTP上的服務(wù)器上的文件名有中文或路徑有中文,那么上述代碼,你將獲取不到正確的文件信息。正確的寫法由于FTP服務(wù)器默認的編碼是ISO-8859-1,因此,客戶端在獲取文件信息時需要請求服務(wù)器使用UTF-8編碼(如果服務(wù)器支持的話),如果服務(wù)器不支持開啟UTF-8編碼,那么客戶端需要指定字符串編碼格式客戶端在請求remotePath路徑、獲取文件名時,都需要對路徑進行編碼轉(zhuǎn)換處理。String

remotePath

=

"/upload/qjnn.apk";

//FTP服務(wù)器上文件路徑

String

charSet

=

"UTF-8";

if

(!FTPReply.isPositiveCompletion(client.sendCommand("OPTS

UTF8",

"ON")))

{

//向服務(wù)器請求使用"UTF-8"編碼

charSet

=

"GBK";

}

FTPFile[]

files

=

client.listFiles(new

String(remotePath.getBytes(charSet),

"ISO-8859-1"));

//對remotePath進行編碼轉(zhuǎn)換

FTPFile

file

=

files[0];

//文件信息

long

size

=

file.getSize();

String

fileaName

=

new

String(fileName.getBytes(),

Charset.forName(charSet));通過以上代碼,便可以獲取到正確的文件信息。文件下載配置每條線程的下載區(qū)間long

fileLength

=

mEntity.getFileSize();

Properties

pro

=

CommonUtil.loadConfig(mConfigFile);

int

blockSize

=

(int)

(fileLength

/

mThreadNum);

int[]

recordL

=

new

int[mThreadNum];

for

(int

i

=

0;

i

<

mThreadNum;

i++)

{

recordL[i]

=

-1;

}

int

rl

=

0;

for

(int

i

=

0;

i

<

mThreadNum;

i++)

{

long

startL

=

i

*

blockSize,

endL

=

(i

+

1)

*

blockSize;

Object

state

=

pro.getProperty(mTempFile.getName()

+

"_state_"

+

i);

if

(state

!=

null

&&

Integer.parseInt(state

+

"")

==

1)

{

//該線程已經(jīng)完成

if

(resumeRecordLocation(i,

startL,

endL))

return;

continue;

}

//分配下載位置

Object

record

=

pro.getProperty(fileName

+

"_record_"

+

i);

//如果有記錄,則恢復(fù)下載

if

(record

!=

null

&&

Long.parseLong(record

+

"")

>=

0)

{

Long

r

=

Long.parseLong(record

+

"");

mConstance.CURRENT_LOCATION

+=

r

-

startL;

Log.d(TAG,

"任務(wù)【"

+

mEntity.getFileName()

+

"】線程__"

+

i

+

"__恢復(fù)下載");

startL

=

r;

recordL[rl]

=

i;

rl++;

}

else

{

recordL[rl]

=

i;

rl++;

}

//最后一個線程的結(jié)束位置即為文件的總長度

if

(i

==

(mThreadNum

-

1))

endL

=

fileLength;

//創(chuàng)建分段線程

AbsThreadTask

task

=

createSingThreadTask(i,

startL,

endL,

fileLength);

if

(task

==

null)

return;

mTask.put(i,

task);

}

startSingleTask(recordL);在上面的代碼中,主要做了兩步操作:在文件下載前,先從本地文件中讀取當(dāng)前下載的每一條線程的下載情況如果下載記錄存在,從記錄位置開始下載,如果記錄不存在,則重新開始下載FTP分段線程區(qū)間自動停止由于FTP協(xié)議沒有區(qū)間下載的原因,為了讓線程只下載特定區(qū)間的內(nèi)容,需要客戶端在單條線程累計讀的數(shù)據(jù)長度已經(jīng)超過了所分配的區(qū)間長度的時候,停止該條線程。

client.enterLocalPassiveMode();

//設(shè)置被動模式

client.setFileType(FTP.BINARY_FILE_TYPE);

//設(shè)置文件傳輸模式

client.setRestartOffset(mConfig.START_LOCATION);

//設(shè)置恢復(fù)下載的位置

client.allocate(mBufSize);

is

=

client.retrieveFileStream(new

String(remotePath.getBytes(charSet),

SERVER_CHARSET));

//發(fā)送第二次指令時,還需要再做一次判斷

reply

=

client.getReplyCode();

if

(!FTPReply.isPositivePreliminary(reply))

{

client.disconnect();

fail(mChildCurrentLocation,

"獲取文件信息錯誤,錯誤碼為:"

+

reply,

null);

return;

}

file

=

new

BufferedRandomAccessFile(mConfig.TEMP_FILE,

"rwd",

mBufSize);

file.seek(mConfig.START_LOCATION);

byte[]

buffer

=

new

byte[mBufSize];

int

len;

while

((len

=

is.read(buffer))

!=

-1)

{

//如果該條線程讀取的數(shù)據(jù)長度大于所分配的區(qū)間長度,則只能讀到區(qū)間的最大長度

if

(mChildCurrentLocation

+

len

>=

mConfig.END_LOCATION)

{

len

=

(int)

(mConfig.END_LOCATION

-

mChildCurrentLocation);

file.write(buffer,

0,

len);

progress(len);

break;

}

else

{

file.write(buffer,

0,

len);

progress(len);

}

}這里還有幾個坑需要處理一下:對于FTP客戶端來說,一般需要設(shè)置被動模式,被動模式和

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論