Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是在Java中尝试捕捉这种笨拙的东西,还是我不知道这种优雅的方法?_Java_Try Catch - Fatal编程技术网

是在Java中尝试捕捉这种笨拙的东西,还是我不知道这种优雅的方法?

是在Java中尝试捕捉这种笨拙的东西,还是我不知道这种优雅的方法?,java,try-catch,Java,Try Catch,这里我要做的是获取一个包含Integers的DataOutputStream,将其剩余内容刷新到一个名为this.byteOut的ByteArrayOutputStream中,然后从中构建一个IntStream 我来自C#领域,正在学习Java,因此这里的代码没有任何实际用途 有没有什么方法可以让我在这里用Java做得更优雅 我关注的两个主要问题是: 确定DataInputStream已被完全读取的方法是捕获eofeexception并将读取后要执行的逻辑放入catch块中。我不喜欢这样,因为

这里我要做的是获取一个包含
Integer
s的
DataOutputStream
,将其剩余内容刷新到一个名为
this.byteOut
ByteArrayOutputStream
中,然后从中构建一个
IntStream

我来自C#领域,正在学习Java,因此这里的代码没有任何实际用途

有没有什么方法可以让我在这里用Java做得更优雅

我关注的两个主要问题是:

  • 确定
    DataInputStream
    已被完全读取的方法是捕获
    eofeexception
    并将读取后要执行的逻辑放入
    catch
    块中。我不喜欢这样,因为我认为抛出和捕获异常有点昂贵?有没有更好的方法来确定流不包含更多的
    Integer
    s
  • 事实上,我必须将try-catch块包装在try-catch块周围,以便能够调用内部
    finally
    块中的
    inputStream.close()
    。有没有一个解决方案不是那么笨重

如果我是你,我会将我的代码更改如下

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);
    }
}
Java7中添加了这种新方法,可以在执行try块时关闭任何实现自动关闭的对象

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

 //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);
    }
int ch1=in.read();
int ch2=in.read();
int ch3=in.read();
int ch4=in.read();
如果((ch1 | ch2 | ch3 | ch4)<0)
抛出新的EOFEException();

return((ch1好吧,多亏@Oliver Charlesworth,我找到了更好的解决方案,如下所示:

    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));
这仍然在
catch
块中包含逻辑,代码看起来更干净

但是,我想不出更好的方法来确定
InputDataStream
已被完全读取

关于这一点,让我感到不安的是,到达流的末尾是意料之中的,如果没有抛出异常,这实际上是异常的,而IMO首先违背了异常的目的


我问了一个关于Java NIO的
IntBuffer
类的可能使用的单独问题

    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);
    }
主要是你。 如果您不喜欢“尝试使用资源”结构, 您仍然可以组合所有的try stations并堆叠catch块

IntBuffer intBuffer = ByteBuffer.wrap(this.byteOut.toByteArray()).asIntBuffer();
while (intBuffer.hasRemaining()){
    intStreamBuilder.accept(intBuffer.get());
}
int[] pool = intStreamBuilder.build().toArray();
super.lock(pool);
需要在finally中进行尝试


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

关于第二点,您可能想研究一下。@OliverCharlesworth goshhh,这是我在Java中非常缺少的东西,因为它来自C#。
使用(var-ms=new MemoryStream())
的C#等价于此。多亏了这么多,您可以有多个catch块和一个finally块与单个try关联。IIRC最具体的catch应该在更多通用catch之前列出(例如,EOFEException比IOException更具体).@Gus我知道,但只要您在
finally
块中放入一条语句,该语句可能会引发一个选中的异常,您就需要将其包装在另一个
try catch
中。resources构造负责
流。close()
,从而消除了其他需要的额外包装。哦,我确实喜欢resources构造,我只是不知道它是
try
本身的一部分。在C中,它是一个单独的构造,名为
using
。请参阅我的答案,了解我的首选解决方案。我曾想过复制
readInt
,但我认为这是个坏主意,因为我会复制框架的实现细节吗?在我自己研究答案时,我遇到了
IntBuffer
类,它甚至比您的
ByteBuffer
解决方案更简单。请参见我的答案。
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);
            }
        }
    }
}