2017-12-22 18 views
0

私はFTP/CLoudRailを使用してインターネット上のファイルにアクセスするアプリケーションを作成しています。ファイルを開くときは、まずこのメソッドを使用して入力ストリームを取得し、ParcelFileDescriptorとして解析します。問題は、PDFファイルを開くとき、私はbrokenPipeエラーを取得します。これは、ここでの画像/テキストファイルのような他のファイルタイプでpdfファイルの入力ストリームを渡すときにパイプが破損しました

を起こらないように注意することは、私が使用したコードである:それは通常奇妙です何

public class ParcelFileDescriptorUtil { 
public static ParcelFileDescriptor pipeFrom(InputStream inputStream) 
     throws IOException { 
    final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); 
    final OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]); 

    new TransferThread(inputStream, output).start(); 

    return pipe[0]; 
} 

@SuppressWarnings("unused") 
public static ParcelFileDescriptor pipeTo(OutputStream outputStream) 
     throws IOException { 
    final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); 
    final InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(pipe[0]); 

    new TransferThread(input, outputStream).start(); 

    return pipe[1]; 
} 

static class TransferThread extends Thread { 
    final InputStream mIn; 
    final OutputStream mOut; 

    TransferThread(InputStream in, OutputStream out) { 
     super("ParcelFileDescriptor Transfer Thread"); 
     mIn = in; 
     mOut = out; 
     setDaemon(true); 
    } 

    @Override 
    public void run() { 
     try { 
      IoUtils.copy(mIn, mOut); 
     } catch (IOException e) { 
      Log.e("TransferThread", "writing failed"); 
      CrashReportingManager.logException(e); 
     } finally { 
      IoUtils.flushQuietly(mOut); 
      IoUtils.closeQuietly(mIn); 
      IoUtils.closeQuietly(mOut); 
     } 
    } 
} 

public static int parseMode(String mode) { 
    final int modeBits; 
    if ("r".equals(mode)) { 
     modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 
    } else if ("w".equals(mode) || "wt".equals(mode)) { 
     modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 
       | ParcelFileDescriptor.MODE_CREATE 
       | ParcelFileDescriptor.MODE_TRUNCATE; 
    } else if ("wa".equals(mode)) { 
     modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 
       | ParcelFileDescriptor.MODE_CREATE 
       | ParcelFileDescriptor.MODE_APPEND; 
    } else if ("rw".equals(mode)) { 
     modeBits = ParcelFileDescriptor.MODE_READ_WRITE 
       | ParcelFileDescriptor.MODE_CREATE; 
    } else if ("rwt".equals(mode)) { 
     modeBits = ParcelFileDescriptor.MODE_READ_WRITE 
       | ParcelFileDescriptor.MODE_CREATE 
       | ParcelFileDescriptor.MODE_TRUNCATE; 
    } else { 
     throw new IllegalArgumentException("Bad mode '" + mode + "'"); 
    } 
    return modeBits; 
} 

@RequiresApi(api = Build.VERSION_CODES.KITKAT) 
public static ParcelFileDescriptor pipeFrom(InputStream inputStream, IThreadListener listener) 
     throws IOException { 
    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createReliablePipe(); 
    ParcelFileDescriptor readSide = pipe[0]; 
    ParcelFileDescriptor writeSide = pipe[1]; 

    // start the transfer thread 
    new TransferThread2(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide), 
      listener) 
      .start(); 

    return readSide; 
} 

public static ParcelFileDescriptor pipeTo(OutputStream outputStream, IThreadListener listener) 
     throws IOException { 
    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); 
    ParcelFileDescriptor readSide = pipe[0]; 
    ParcelFileDescriptor writeSide = pipe[1]; 

    // start the transfer thread 
    new TransferThread2(new ParcelFileDescriptor.AutoCloseInputStream(readSide), outputStream, 
      listener) 
      .start(); 

    return writeSide; 
} 

static class TransferThread2 extends Thread { 
    final InputStream mIn; 
    final OutputStream mOut; 
    final IThreadListener mListener; 

    TransferThread2(InputStream in, OutputStream out, IThreadListener listener) { 
     super("ParcelFileDescriptor Transfer Thread"); 
     mIn = in; 
     mOut = out; 
     mListener = listener; 
     setDaemon(true); 
    } 

    @Override 
    public void run() { 
     byte[] buf = new byte[1024*8]; 
     int len; 

     try { 
      while ((len = mIn.read(buf)) > 0) { 
       mOut.write(buf, 0, len); 
      } 
      mOut.flush(); // just to be safe 
     } catch (IOException e) { 
      Log.e("TransferThread", "writing failed"); 
      e.printStackTrace(); 
     } finally { 
      try { 
       mIn.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      try { 
       mOut.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     if (mListener != null) 
      mListener.onThreadFinished(this); 
    } 
} 

:ここ

@Override 
public ParcelFileDescriptor openDocument(final String documentId, final String mode, 
             CancellationSignal signal) 
     throws FileNotFoundException { 
    Log.d(TAG,"Opening document"); 
    final CloudFile file = getFileForDocId(documentId); 
    final CloudConnection connection = getCloudConnection(documentId); 
    //TODO Open a file 
    try { 
     final boolean isWrite = (mode.indexOf('w') != -1); 
     if (isWrite) { 
      return null; 
     } else { 
      InputStream inputStream = connection.getConnectedClient().download(file.getPath()); 
      if(null != inputStream){ 
       return ParcelFileDescriptorUtil.pipeFrom(inputStream); 
      } 
     } 

     return null; 
    } catch (Exception e) { 
     CrashReportingManager.logException(e); 
     throw new FileNotFoundException("Failed to open document with id " + documentId + 
       " and mode " + mode); 
    } 
} 

はParcelFileDescriptorUtilですあなたがroot権限を持っていないときに起こります。しかし、pdfを表示するには、もちろんその必要はありません。

12-22 17:37:48.516 9112-9691/com.tproductions.Openit.pro W/System.err: java.io.IOException: write failed: EPIPE (Broken pipe) 
12-22 17:37:48.516 9112-9691/com.tproductions.Openit.pro W/System.err:  at libcore.io.IoBridge.write(IoBridge.java:558) 
12-22 17:37:48.516 9112-9691/com.tproductions.Openit.pro W/System.err:  at java.io.FileOutputStream.write(FileOutputStream.java:326) 
12-22 17:37:48.516 9112-9691/com.tproductions.Openit.pro W/System.err:  at com.tproductions.Openit.libcore.io.IoUtils.copyLarge(IoUtils.java:310) 
12-22 17:37:48.516 9112-9691/com.tproductions.Openit.pro W/System.err:  at com.tproductions.Openit.libcore.io.IoUtils.copy(IoUtils.java:283) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err:  at com.tproductions.Openit.misc.ParcelFileDescriptorUtil$TransferThread.run(ParcelFileDescriptorUtil.java:70) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err: Caused by: android.system.ErrnoException: write failed: EPIPE (Broken pipe) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err:  at libcore.io.Linux.writeBytes(Native Method) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err:  at libcore.io.Linux.write(Linux.java:286) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err:  at libcore.io.BlockGuardOs.write(BlockGuardOs.java:345) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err:  at libcore.io.IoBridge.write(IoBridge.java:553) 
12-22 17:37:48.517 9112-9691/com.tproductions.Openit.pro W/System.err: ... 4 more 
+0

ありがとう、私は入力ストリームを使用していますが、UriとMIMEタイプは使用していません。私が紛失しているものはありますか? – Traabefi

+0

いいえ、それはただの内部クラスです、私はUtilクラスのthread2で見ることができる単純なwhileループです – Traabefi

答えて

0

問題が解決されました:ところで

は、ここでエラーです。奇妙なことに、私のアプリでPDFファイルを開く方法でした。私は新しいInputStreamDataSource()を渡していましたが、その後例外が発生した入力ストリームを閉じました。奇妙なことに、今は動作します

関連する問題