实际上是在Java中尝试捕捉这个笨拙的人,或者我只是不知道这种优雅的方法


public void lock() {
    if (this.isLocked()) return;
    try {
        this.dataOut.flush();
        this.dataOut.close();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    DataInputStream inputStream =
        new DataInputStream(
        new BufferedInputStream(
        new ByteArrayInputStream(
            this.byteOut.toByteArray())));
    IntStream.Builder intStreamBuilder = IntStream.builder();
    try {
        try {
            while (true) {
                intStreamBuilder.accept(inputStream.readInt());
            }
        } catch (EOFException e) {
            // logic to be executed after stream has been fully read
            int[] pool = intStreamBuilder.build().toArray();
            super.lock(pool);
        } finally {
            inputStream.close();
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

我在这里做的是将包含Integer s的DataOutputStream,将其剩余的内容冲入名为this.byteOutByteArrayOutputStream中,然后从中构建IntStream

我来自C#域,在学习Java的过程中,因此这里的代码没有任何实际目的。

有什么方法可以在Java中更优雅地做我在这里做的事情?

我的两个主要问题是:

  • 我确定DataInputStream已充分阅读的方式是捕获EOFException并将逻辑放置在catch块内部读取后要执行的逻辑。我不喜欢那样,因为我想投掷和捕捉例外有点贵吗?有没有更好的方法来确定该流不再包含Integer S?
  • 我必须在一个trycatch块上包裹一个try-catch块,以便能够在内部finally块中调用inputStream.close()。有没有那么笨拙的解决方案?

主要是你。如果您不喜欢尝试使用资源构建的尝试,您仍然可以结合所有尝试仪表并堆叠捕获块。

public void lock()
{
    DataInputStream inputStream = null;
    IntStream.Builder intStreamBuilder;
    if (isLocked())
    {
        return;
    }
    try
    {
        inputStream = new DataInputStream(
            new BufferedInputStream(
                new ByteArrayInputStream(
                    byteOut.toByteArray())));
        intStreamBuilder = IntStream.builder();
        dataOut.flush();
        dataOut.close();
        while (true)
        {
            intStreamBuilder.accept(
                inputStream.readInt());
        }
    }
    catch (IOException exception)
    {
        throw new RuntimeException(exception);
    }
    catch (EOFException ignoredException)
    {
        // logic to be executed after stream has been fully read
        int[] pool = intStreamBuilder.build().toArray();
        super.lock(pool);
    }
    finally
    {
        if (inputSream != null)
        {
            try
            {
                inputStream.close();
            }
            catch (IOException exception)
            {
                throw new RuntimeException(exception);
            }
        }
    }
}

最终需要的尝试。

我更喜欢try-with-resources构造。

如果我是您,我将更改我的代码为以下

 //try-with-resources-close
 try (DataInputStream inputStream =
                 new DataInputStream(
                         new BufferedInputStream(
                                 new ByteArrayInputStream(
                                         this.byteOut.toByteArray())))) {
        IntStream.Builder intStreamBuilder = IntStream.builder();
        byte[] byts = new byte[4];
        while (inputStream.read(byts) > -1) {// read  4 bytes and convert them to int
            int result = ByteBuffer.wrap(byts).getInt();
            intStreamBuilder.accept(result);
        }
        // logic to be executed after stream has been fully read
        int[] pool = intStreamBuilder.build().toArray();
        super.lock(pool);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

try-with-resours在Java 7中添加了这种新方法,以关闭在执行Try Block时自动实现自动磁的任何对象

读取方法它的工作原理如下读取4个bteys,然后将它们转换为int

    int ch1 = in.read();
    int ch2 = in.read();
    int ch3 = in.read();
    int ch4 = in.read();
    if ((ch1 | ch2 | ch3 | ch4) < 0)
        throw new EOFException();
    return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

//因此您也可以做同样的事情,而不是抛出EOFException您可以添加返回falsebreak循环

对于读取字节方法,如果不存在字节,则它将ret -1

ret

好吧,我对@oliver charlesworth找到了更好的解决方案:

    try (DataInputStream inputStream =
        new DataInputStream(
        new BufferedInputStream(
        new ByteArrayInputStream(this.byteOut.toByteArray())))) {
        while (true)
            intStreamBuilder.accept(inputStream.readInt());
    } catch (EOFException e) {
        int[] pool = intStreamBuilder.build().toArray();
        super.lock(pool);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

catch内部仍然具有逻辑,代码看起来绝对干净。

但是,我无法提出一种更好的方法来决定InputDataStream已完全读取。

我对此感到困扰的是,到达流的结束是可以预期的,如果没有例外,IMO首先击败了例外的目的,实际上将是非凡的。


我在此处提出了一个单独的问题,即可能在此处使用Java Nio的IntBuffer类。我的上述片段可以更改为:

IntBuffer intBuffer = ByteBuffer.wrap(this.byteOut.toByteArray()).asIntBuffer();
while (intBuffer.hasRemaining()){
    intStreamBuilder.accept(intBuffer.get());
}
int[] pool = intStreamBuilder.build().toArray();
super.lock(pool);

相关内容