是在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
sInteger
- 事实上,我必须将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);
}
}
}
}