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.byteOut
的ByteArrayOutputStream
中,然后从中构建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
您可以添加返回false
或break
循环
对于读取字节方法,如果不存在字节,则它将ret -1
好吧,我对@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);