Retrofit2文件上傳與下載

Retrofit2文件上傳與下載通俗易懂教程赂苗。

之前在使用retrofit的時(shí)候,遇到文件上傳和下載的功能,搜索了好久才完成功能,搜索的有很多都讓人困惑,更有些寫的讓人絕望,我就想著自己寫一篇簡(jiǎn)單易懂的,如對(duì)您有幫助,可以點(diǎn)個(gè)贊和喜歡,一個(gè)小小的舉動(dòng)就是對(duì)作者最大的鼓勵(lì)蕉鸳。Thanks?(?ω?)?

源碼地址

點(diǎn)擊即達(dá)

https://github.com/QiaoYang0923/RetrofitDownloadAndUpLoading

文件上傳:(包括多文件上傳)

第一步:創(chuàng)建服務(wù)返回?cái)?shù)據(jù)的bean類;(此處服務(wù)器返回的是json字符串);

public class BaseBean{

    private int Code;
    private String Msg;
    private String Data;
    //...setget方法

}

第二步:創(chuàng)建用于描述網(wǎng)絡(luò)請(qǐng)求的接口

public interface Api {
/**
* 上傳
* Multipart 這個(gè)注解代表多表單上傳
* @param partList 表單信息
* @return .
*/
@Multipart
@POST("服務(wù)器地址(就創(chuàng)建retrofit設(shè)置的基站地址后面的具體地址)")
Call<BaseBean> upLoading(@Part List<MultipartBody.Part> partList);

 }

第三步:創(chuàng)建表單,里面存儲(chǔ)服務(wù)器本接口所需要的數(shù)據(jù);

 參數(shù)添加
 MultipartBody.Builder builder = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            //在這里添加服務(wù)器除了文件之外的其他參數(shù)
            .addFormDataPart("參數(shù)1", "值1")
            .addFormDataPart("參數(shù)2", "值2");
創(chuàng)建文件(你需要上傳到服務(wù)器的文件)
File file = new File(file1Location); //file1Location文件的路徑 ,我是在手機(jī)存儲(chǔ)根目錄下創(chuàng)建了一個(gè)文件夾,里面放著了一張圖片;                 
設(shè)置文件的格式
    RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);

    //添加文件(uploadfile就是你服務(wù)器中需要的文件參數(shù))

    builder.addFormDataPart("uploadfile", file.getName(), imageBody);         
生成接口需要的list
    List<MultipartBody.Part> parts = builder.build().parts();
創(chuàng)建設(shè)置OkHttpClient
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .writeTimeout(20, TimeUnit.SECONDS)
            //允許失敗重試
            .retryOnConnectionFailure(true)
            .build();
創(chuàng)建retrofit實(shí)例對(duì)象
    Retrofit retrofit = new Retrofit.Builder()
            //設(shè)置基站地址(基站地址+描述網(wǎng)絡(luò)請(qǐng)求的接口上面注釋的Post地址,就是要上傳文件到服務(wù)器的地址,
            // 這只是一種設(shè)置地址的方法,還有其他方式,不在贅述)
            .baseUrl("你的基站地址")
            //設(shè)置委托,使用OKHttp聯(lián)網(wǎng),也可以設(shè)置其他的;
            .client(okHttpClient)
            //設(shè)置數(shù)據(jù)解析器,如果沒(méi)有這個(gè)類需要添加依賴:
            .addConverterFactory(GsonConverterFactory.create())
            //設(shè)置支持rxJava
            // .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
實(shí)例化請(qǐng)求接口,把表單傳遞過(guò)去;
    Call<BaseBean> call = retrofit.create(Api.class).upLoading(parts);
    //開(kāi)始請(qǐng)求
    call.enqueue(new Callback<BaseBean>() {

        @Override
        public void onResponse(Call<BaseBean> call, Response<BaseBean> response) {
            //聯(lián)網(wǎng)有響應(yīng)或有返回?cái)?shù)據(jù)
            System.out.println(response.body().toString());
        }

        @Override
        public void onFailure(Call<BaseBean> call, Throwable t) {
            //連接失敗,多數(shù)是網(wǎng)絡(luò)不可用導(dǎo)致的
            System.out.println("網(wǎng)絡(luò)不可用");
        }
    });
}

這就ok了,單個(gè)文件上傳完畢!!!

多文件上傳(以兩個(gè)文件為例)

    對(duì)比一個(gè)文件,這個(gè)只需要在[設(shè)置文件的格式] 這一步,多添加一個(gè)即可;
    RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
    RequestBody imageBody1 = RequestBody.create(MediaType.parse("multipart/form-data"), file1);
    //添加文件(uploadfile就是你服務(wù)器中需要的文件參數(shù))
    builder.addFormDataPart("uploadfile", file.getName(), imageBody);
    builder.addFormDataPart("uploadfile1", file1.getName(), imageBody1);

接下來(lái)看文件下載?

文件下載:

首先還是要在API接口創(chuàng)建一個(gè)方法;

/**
* 下載文件
* 如果下載大文件的一定要加上  @Streaming  注解
*
* @param fileUrl 文件的路徑
* @return 請(qǐng)求call
*/
@GET
Call<ResponseBody> download(@Url String fileUrl);

然后就是創(chuàng)建一個(gè)retrofit對(duì)象,跟上面一樣(由于每次創(chuàng)建retrofit對(duì)象會(huì)用到很多重復(fù)的代碼,可以抽取成一個(gè)公共方法)

實(shí)例化請(qǐng)求接口:

我在百度上找到一張圖片,把他的地址拆分了一下,最后一個(gè)斜杠之前的url設(shè)置為了baseUrl,斜杠之后設(shè)置在這里;

   地址拆分:    .baseUrl("https://gss3.bdstatic.com/-Po3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=e3dc64d05a3d26972ed30f5b6dc0d5c6/")

  //整體地址https://gss3.bdstatic.com/Po3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=e3dc64d05a3d26972ed30f5b6dc0d5c6/(在這里拆分了)241f95cad1c8a7868a2713146c09c93d70cf509e.jpg

    Call<ResponseBody> download = retrofit.create(Api.class).download("241f95cad1c8a7868a2713146c09c93d70cf509e.jpg");
    download.enqueue(new Callback<ResponseBody>() {

        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response != null && response.isSuccessful()) {
            // writeResponseBodyToDisk 是我寫的下載保存本地工具類,可以參考一下
                boolean toDisk = writeResponseBodyToDisk(response.body());
                if (toDisk) {
                    System.out.println("下載成功請(qǐng)查看");
                } else {
                    System.out.println("下載失敗,請(qǐng)稍后重試");
                }
            } else {
                System.out.println("服務(wù)器返回錯(cuò)誤");
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            //連接失敗,多數(shù)是網(wǎng)絡(luò)不可用導(dǎo)致的
            System.out.println("網(wǎng)絡(luò)不可用");
        }
    });

writeResponseBodyToDisk(下載文件保存到本地工具類)

/**
* 下載到本地
*
* @param body 內(nèi)容
* @return 成功或者失敗
*/
private boolean writeResponseBodyToDisk(ResponseBody body) {
    try {
        //判斷文件夾是否存在
        File files = new File(SD_HOME_DIR);//跟目錄一個(gè)文件夾
        if (!files.exists()) {
            //不存在就創(chuàng)建出來(lái)
            files.mkdirs();
        }
        //創(chuàng)建一個(gè)文件
        File futureStudioIconFile = new File(SD_HOME_DIR + "download.jpg");
        //初始化輸入流
        InputStream inputStream = null;
        //初始化輸出流
        OutputStream outputStream = null;
        try {
            //設(shè)置每次讀寫的字節(jié)
            byte[] fileReader = new byte[4096];
            long fileSize = body.contentLength();
            long fileSizeDownloaded = 0;
            //請(qǐng)求返回的字節(jié)流
            inputStream = body.byteStream();
            //創(chuàng)建輸出流
            outputStream = new FileOutputStream(futureStudioIconFile);
            //進(jìn)行讀取操作
            while (true) {
                int read = inputStream.read(fileReader);
                if (read == -1) {
                    break;
                }
                //進(jìn)行寫入操作
                outputStream.write(fileReader, 0, read);
                fileSizeDownloaded += read;
            }

            //刷新
            outputStream.flush();
            return true;
        } catch (IOException e) {
            return false;
        } finally {
            if (inputStream != null) {
                //關(guān)閉輸入流
                inputStream.close();
            }
            if (outputStream != null) {
                //關(guān)閉輸出流
                outputStream.close();
            }
        }
    } catch (IOException e) {
        return false;
    }
}

下載下來(lái)的圖片展示

241f95cad1c8a7868a2713146c09c93d70cf509e.jpg

如有問(wèn)題請(qǐng)留言!

全文完!!!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辕近,一起剝皮案震驚了整個(gè)濱河市桩引,隨后出現(xiàn)的幾起案子滚秩,更是在濱河造成了極大的恐慌盅称,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件飞几,死亡現(xiàn)場(chǎng)離奇詭異砚哆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)循狰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門窟社,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人绪钥,你說(shuō)我怎么就攤上這事」亓叮” “怎么了程腹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)儒拂。 經(jīng)常有香客問(wèn)我寸潦,道長(zhǎng),這世上最難降的妖魔是什么社痛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任见转,我火速辦了婚禮,結(jié)果婚禮上蒜哀,老公的妹妹穿的比我還像新娘斩箫。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布乘客。 她就那樣靜靜地躺著狐血,像睡著了一般。 火紅的嫁衣襯著肌膚如雪易核。 梳的紋絲不亂的頭發(fā)上匈织,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音牡直,去河邊找鬼缀匕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碰逸,可吹牛的內(nèi)容都是我干的乡小。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼花竞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼劲件!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起约急,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤零远,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后厌蔽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體牵辣,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年奴饮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纬向。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戴卜,死狀恐怖逾条,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情投剥,我是刑警寧澤师脂,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站江锨,受9級(jí)特大地震影響吃警,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啄育,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一酌心、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挑豌,春花似錦安券、人聲如沸墩崩。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)泰鸡。三九已至,卻和暖如春壳鹤,著一層夾襖步出監(jiān)牢的瞬間盛龄,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工芳誓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留余舶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓锹淌,卻偏偏與公主長(zhǎng)得像匿值,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赂摆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理挟憔,服務(wù)發(fā)現(xiàn),斷路器烟号,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 用兩張圖告訴你绊谭,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,730評(píng)論 2 59
  • 曾經(jīng)我以為說(shuō)話模棱兩可便不會(huì)得罪人汪拥,現(xiàn)在我覺(jué)得曾經(jīng)的想法很愚蠢达传。 不,都錯(cuò)了迫筑。這個(gè)世界上哪有那么多的“我覺(jué)得”“我...
    那天幕后閱讀 1,480評(píng)論 0 0
  • (一) 小果剛搬來(lái)C市宪赶,覺(jué)得這里的一切都充滿了新鮮感,他在房間一邊整理著衣物脯燃,一邊規(guī)劃著未來(lái)的藍(lán)圖搂妻。他是個(gè)有野心的...
    嘟妹嘟嘟閱讀 371評(píng)論 0 1