抛出 java.io.IOException: 当我尝试从服务器下载 txt 文件时,http:/ 上的流意外结束

Posted

技术标签:

【中文标题】抛出 java.io.IOException: 当我尝试从服务器下载 txt 文件时,http:/ 上的流意外结束【英文标题】:Throw java.io.IOException: unexpected end of stream on http:/ when i try to download txt file from server 【发布时间】:2020-09-21 17:08:16 【问题描述】:

当我尝试从服务器下载文件(.txt)时,我遇到了失败(java.io.IOException:http:) 上的流意外结束。我无法理解问题出在哪里(在服务器上或客户端上)。我从 broswer 和 postman 下载了这个文件,没有问题。我认为客户端有问题,但不知道在哪里。

@RestController
public class DownloadDbController 
   @RequestMapping(path = "/download", method = RequestMethod.GET)
   public ResponseEntity<Resource> download(String param) throws IOException 
       File file = new File("src/main/res/123.txt");

       HttpHeaders header = new HttpHeaders();
       header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=123.txt");


       Path path = Paths.get(file.getAbsolutePath());
       ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path));

       return ResponseEntity.ok()
               .headers(header)
               .contentLength(file.length())
               .contentType(MediaType.TEXT_PLAIN)
               .body(resource);

   

API:

public interface GetDb 
@Streaming
@GET("url")
Observable<ResponseBody> downloadDB(@Path("url") String url);

改造类:

public class RetrofitService 
private static RetrofitService mInstance;
private static final String BASE_URL = "http://localhost:8080/";
private Retrofit mRetrofit;


private RetrofitService() 
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient.Builder client = new OkHttpClient.Builder()
            .retryOnConnectionFailure(true)
            .addInterceptor(interceptor);

    mRetrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addConverterFactory(ScalarsConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(client.build())
            .build();


public static RetrofitService getInstance() 
    if (mInstance == null) 
        mInstance = new RetrofitService();
    
    return mInstance;


public GetDb getJSONApi() 
    return mRetrofit.create(GetDb.class);
  

我尝试下载并写入新文件的类

public class SyncDb 
Context mContext;

public SyncDb(Context mContext) 
    this.mContext = mContext;


public void downloadDB(String path) 
    RetrofitService.getInstance()
            .getJSONApi()
            .downloadDB("download")
            .subscribeOn(Schedulers.io())
            .subscribe(new Observer<ResponseBody>() 
                @Override
                public void onSubscribe(Disposable d) 

                

                @Override
                public void onNext(ResponseBody responseBody) 

                        saveFile(responseBody);
                    Log.d("abc","onNext");


                

                @Override
                public void onError(Throwable e) 
                    Log.d("abc","error");
                    e.printStackTrace();
                
                @Override
                public void onComplete() 
                    Log.d("abc","Completed");
                
            );

   public void saveFile( ResponseBody responseBody ) 
    File folder =new File(mContext.getFilesDir().toString(), "123.txt");
    folder.mkdirs();

    File unzipMe = new File(folder, "123.txt");
    if (!unzipMe.exists())
        try 
            unzipMe.createNewFile();
         catch (IOException e) 
            e.printStackTrace();
        
    
    BufferedOutputStream bos = null;
    try 
        bos = new BufferedOutputStream(new FileOutputStream(unzipMe));
     catch (FileNotFoundException e) 
        e.printStackTrace();
    
    try 
        bos.write(responseBody.bytes());
        bos.flush();
        bos.close();
     catch (IOException e) 
        e.printStackTrace();
    


【问题讨论】:

【参考方案1】:

将protocols(listOf(Protocol.HTTP_1_1)) 行添加到您的OkHttpClient。

示例;

val okHttpClient = OkHttpClient.Builder()
                    .protocols(listOf(Protocol.HTTP_1_1))
                    .readTimeout(40, TimeUnit.SECONDS)
                    .connectTimeout(40, TimeUnit.SECONDS)
                    .addInterceptor(loggingInterceptor)
                    .addInterceptor(authInterceptor)
                    .retryOnConnectionFailure(true)
                    .build()

【讨论】:

以上是关于抛出 java.io.IOException: 当我尝试从服务器下载 txt 文件时,http:/ 上的流意外结束的主要内容,如果未能解决你的问题,请参考以下文章

Spark抛出java.io.IOException:保存part-xxxxx.gz时重命名失败

jsp报错java.io.IOException: Stream closed

java.io.IOException:意外的EOF当Jenkins slave尝试SVN签出时

java.io.IOException:无法解包数据,无效状态

Gradle 构建失败 java.io.IOException:输出 jar 为空

java.io.IOException: %1 不是有效的 Win32 应用程序