传递PDF文件的输入流时,损坏的管道



我正在创建一个应用程序,该应用程序使用FTP/Cloudrail通过Internet访问文件。打开文件时,我使用此方法首先获取输入流,然后将其作为包裹式列表分析。问题是,在打开PDF文件时,我会出现brokerpipe错误。请注意,其他文件类型(例如图像/文本文件

)不会发生这种情况。

这是我使用的代码:

@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);
    }
}

这是包裹的词法:

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);
    }
}

什么是奇怪的,通常会在您没有根许可的情况下会发生这种情况。但是,要显示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

现在解决了问题。奇怪的是,引起它的原因是我在应用程序中打开PDF文件的方式。我通过了新的InputStreamDatasource(),但是,我关闭了输入流,这导致了例外。奇怪的是,它现在起作用

相关内容

  • 没有找到相关文章

最新更新