2015-08-02 1 views
2

Я пытаюсь написать InputStream к MultiPartEntity, но я держать удар:чтения не удалось при переходе InputStream в другой поток

08-01 17:25:13.523 2737-2787/com.[project].[package].test E/Volley﹕ [12495] BasicNetwork.performRequest: Unexpected response code 401 for https://api.[project].com/ 
08-01 17:25:13.603 2737-2737/com.[project].[package].test W/System.err﹕ com.android.volley.NoConnectionError: java.io.IOException: read failed: EBADF (Bad file number) 
08-01 17:25:13.603 2737-2737/com.[project].[package].test W/System.err﹕ at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:151) 
08-01 17:25:13.603 2737-2737/com.[project].[package].test W/System.err﹕ at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112) 
08-01 17:25:13.604 2737-2737/com.[project].[package].test W/System.err﹕ Caused by: java.io.IOException: read failed: EBADF (Bad file number) 
08-01 17:25:13.605 2737-2737/com.[project].[package].test W/System.err﹕ at libcore.io.IoBridge.read(IoBridge.java:482) 
08-01 17:25:13.605 2737-2737/com.[project].[package].test W/System.err﹕ at java.io.FileInputStream.read(FileInputStream.java:177) 
08-01 17:25:13.605 2737-2737/com.[project].[package].test W/System.err﹕ at java.io.InputStream.read(InputStream.java:162) 
08-01 17:25:13.605 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.entity.mime.content.InputStreamBody.writeTo(InputStreamBody.java:91) 
08-01 17:25:13.605 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.entity.mime.AbstractMultipartForm.doWriteTo(AbstractMultipartForm.java:150) 
08-01 17:25:13.606 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.entity.mime.AbstractMultipartForm.writeTo(AbstractMultipartForm.java:173) 
08-01 17:25:13.606 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.entity.mime.MultipartFormEntity.writeTo(MultipartFormEntity.java:97) 
08-01 17:25:13.606 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.execchain.RequestEntityProxy.writeTo(RequestEntityProxy.java:116) 
08-01 17:25:13.606 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:155) 
08-01 17:25:13.606 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:149) 
08-01 17:25:13.606 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:242) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:260) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:178) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) 
08-01 17:25:13.607 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) 
08-01 17:25:13.608 2737-2737/com.[project].[package].test W/System.err﹕ at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) 
08-01 17:25:13.608 2737-2737/com.[project].[package].test W/System.err﹕ at com.android.volley.toolbox.HttpClientStack.performRequest(HttpClientStack.java:87) 
08-01 17:25:13.608 2737-2737/com.[project].[package].test W/System.err﹕ at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96) 
08-01 17:25:13.608 2737-2737/com.[project].[package].test W/System.err﹕ ... 1 more 
08-01 17:25:13.609 2737-2737/com.[project].[package].test W/System.err﹕ Caused by: android.system.ErrnoException: read failed: EBADF (Bad file number) 
08-01 17:25:13.610 2737-2737/com.[project].[package].test W/System.err﹕ at libcore.io.Posix.readBytes(Native Method) 
08-01 17:25:13.610 2737-2737/com.[project].[package].test W/System.err﹕ at libcore.io.Posix.read(Posix.java:165) 
08-01 17:25:13.610 2737-2737/com.[project].[package].test W/System.err﹕ at libcore.io.BlockGuardOs.read(BlockGuardOs.java:230) 
08-01 17:25:13.610 2737-2737/com.[project].[package].test W/System.err﹕ at libcore.io.IoBridge.read(IoBridge.java:472) 
08-01 17:25:13.610 2737-2737/com.[project].[package].test W/System.err﹕ ... 21 more 

поток является FileInputStream вернулся из AssetFileDescriptor.createInputStream()

Здесь я получаю AssetFileDescriptor

AssetFileDescriptor file = getContext().getContentResolver().openAssetFileDescriptor(person, 
        "r"); 

затем добавить его в многоголосных:

multipartRequest.addFileBody("file", file.createInputStream()); 

который использует MultipartEntityBuilder:

public void addFileBody(String name, InputStream in){ 
    multipartEntityBuilder.addBinaryBody(name, in); 
} 

Я использую HttpURLConnection и пишу тело здесь:

это (вместе со всей связи) происходит на другой нить

private static void addBodyIfExists(HttpURLConnection connection, Request<?> request) 
     throws IOException, AuthFailureError { 
    if(request.getEntity() != null){ 
     connection.setDoOutput(true); 
     connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType()); 
     connection.setChunkedStreamingMode(0); 
     OutputStream out = connection.getOutputStream(); 
     request.getEntity().writeTo(out); 
     out.flush(); 
     out.close(); 
    } else { 

Я попытался найти его, но все, что я мог узнать, это то, что InputStream закрыт, но я его нигде не закрываю.

EDIT: Кажется, проблема в том, что я пытаюсь сделать запрос из отдельной ветви, так как все это прекрасно работает, когда это происходит в той же теме.

Редакция: Тема А получает филе и создает объект запроса, добавляет поток к объекту. Thread B запускает и принимает указанный объект, открывает соединение и пытается прочитать поток/запись в соединение, в этот момент происходит ошибка чтения.

+1

Перед отправкой сообщения вы закрываете 'файл'. – EJP

+0

@EJP «Я пробовал искать его, но все, что я мог узнать, это то, что, скорее всего, InputStream закрыт, но я его нигде не закрываю». после вызова multipartRequest.addFileBody ("file", file.createInputStream()); Я ничего не делаю с файлом, и я не закрываю поток anywher – Epicblood

+0

Тем не менее это то, что означает исключение. Файл закрыт. Нет двух способов. Тот факт, что задействованы два потока (почему?), Делает более возможным то, что код не ведет себя так, как вы думаете. – EJP

ответ

1

[[Оказывается, что он/она читает актив и отправляет его на пульт дистанционного управления, поэтому этот ответ действительно не помогает. Сейчас я собираюсь оставить его в качестве заполнителя. ]]

System.err: Вызванный: android.system.ErrnoException: Не удалось прочитать: EBADF (Bad номер файла)

Как уже упоминалось @EJP, это пытается сказать вам, что самая когда фоновый поток переходит к чтению из потока, он был закрыт.

Поскольку это, кажется, веб-клиент, я подозреваю, что вы пытаетесь прочитать файл из ответа GET или POST, и контейнер ответа был отключен и закрыт к тому времени, когда поток отправится его читать.

Есть несколько способов, чтобы исправить это:

  • Нить делающего запрос может прочитать в самом файле, а затем передавать байты в буфер для фонового потока для обработки.

  • Поток, содержащий запрос, может быть прочитан в файле и сохранить его во временном файле на диске, а затем передать имя временного файла в фоновый поток.

Но независимо от того, поток, обрабатывающий веб-запрос, должен заполнить IO по запросу до того, как контейнер веб-запроса будет закрыт.

+0

Поток поступает из 'AssetFileDescriptor' [' createInputStream() '] (https://developer.android.com/reference/android/content/res/AssetFileDescriptor.html#createInputStream()), и я не могу найти причина, что он должен быть закрыт, единственное место, где я закрываю его, - это другое направление после того, как я его прочитал. – Epicblood

+0

Huh «Вы владеете этим дескриптором и несете ответственность за его закрытие», - говорится в javadocs. Кажется, что _someone_ закрывает его. Может быть, поставить точку останова на InputStream.close() или что-то еще и посмотреть, что всплывает? – Gray

Смежные вопросы