From 23da5d99d2c4cc523067da0f3c1bb2a931dd47eb Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Mar 2016 11:22:21 +0100 Subject: [PATCH] Cleanup (I/O ops in java-decompiler) --- .../main/decompiler/ConsoleDecompiler.java | 38 +++-------- .../java/decompiler/struct/ContextUnit.java | 10 +-- .../java/decompiler/struct/StructContext.java | 29 +++------ .../java/decompiler/struct/StructMember.java | 10 +-- .../decompiler/struct/lazy/LazyLoader.java | 31 +++------ .../decompiler/util/DataInputFullStream.java | 31 ++------- .../java/decompiler/util/InterpreterUtil.java | 64 ++++++++----------- .../decompiler/BulkDecompilationTest.java | 26 +++----- 8 files changed, 78 insertions(+), 161 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java index 7924b1c..ea08023 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -150,17 +150,11 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { return InterpreterUtil.getBytes(file); } else { - ZipFile archive = new ZipFile(file); - try { + try (ZipFile archive = new ZipFile(file)) { ZipEntry entry = archive.getEntry(internalPath); - if (entry == null) { - throw new IOException("Entry not found: " + internalPath); - } + if (entry == null) throw new IOException("Entry not found: " + internalPath); return InterpreterUtil.getBytes(archive, entry); } - finally { - archive.close(); - } } } @@ -193,14 +187,8 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { @Override public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) { File file = new File(getAbsolutePath(path), entryName); - try { - Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8"); - try { - out.write(content); - } - finally { - out.close(); - } + try (Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8")) { + out.write(content); } catch (IOException ex) { DecompilerContext.getLogger().writeMessage("Cannot write class file " + file, ex); @@ -238,21 +226,15 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { return; } - try { - ZipFile srcArchive = new ZipFile(new File(source)); - try { - ZipEntry entry = srcArchive.getEntry(entryName); - if (entry != null) { - InputStream in = srcArchive.getInputStream(entry); + try (ZipFile srcArchive = new ZipFile(new File(source))) { + ZipEntry entry = srcArchive.getEntry(entryName); + if (entry != null) { + try (InputStream in = srcArchive.getInputStream(entry)) { ZipOutputStream out = mapArchiveStreams.get(file); out.putNextEntry(new ZipEntry(entryName)); InterpreterUtil.copyStream(in, out); - in.close(); } } - finally { - srcArchive.close(); - } } catch (IOException ex) { String message = "Cannot copy entry " + entryName + " from " + source + " to " + file; @@ -306,4 +288,4 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { DecompilerContext.getLogger().writeMessage("Cannot close " + file, IFernflowerLogger.Severity.WARN); } } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java index 850c3d8..69125e1 100644 --- a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java +++ b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,13 +78,9 @@ public class ContextUnit { String oldName = cl.qualifiedName; StructClass newCl; - DataInputFullStream in = loader.getClassStream(oldName); - try { + try (DataInputFullStream in = loader.getClassStream(oldName)) { newCl = new StructClass(in, cl.isOwn(), loader); } - finally { - in.close(); - } lstClasses.add(newCl); @@ -168,4 +164,4 @@ public class ContextUnit { public List getClasses() { return classes; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java index 7bfb139..d47de60 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,17 +119,11 @@ public class StructContext { } if (filename.endsWith(".class")) { - try { - DataInputFullStream in = loader.getClassStream(file.getAbsolutePath(), null); - try { - StructClass cl = new StructClass(in, isOwn, loader); - classes.put(cl.qualifiedName, cl); - unit.addClass(cl, filename); - loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null)); - } - finally { - in.close(); - } + try (DataInputFullStream in = loader.getClassStream(file.getAbsolutePath(), null)) { + StructClass cl = new StructClass(in, isOwn, loader); + classes.put(cl.qualifiedName, cl); + unit.addClass(cl, filename); + loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null)); } catch (IOException ex) { String message = "Corrupted class file: " + file; @@ -143,10 +137,8 @@ public class StructContext { } private void addArchive(String path, File file, int type, boolean isOwn) throws IOException { - @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file); - - try { + //noinspection IOResourceOpenedButNotSafelyClosed + try (ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file)) { Enumeration entries = archive.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); @@ -178,12 +170,9 @@ public class StructContext { } } } - finally { - archive.close(); - } } public Map getClasses() { return classes; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index f681e19..bc8b931 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,15 +73,15 @@ public class StructMember { protected StructGeneralAttribute readAttribute(DataInputFullStream in, ConstantPool pool, String name) throws IOException { StructGeneralAttribute attribute = StructGeneralAttribute.createAttribute(name); + int length = in.readInt(); if (attribute == null) { - in.discard(in.readInt()); + in.discard(length); } else { - byte[] data = new byte[in.readInt()]; - in.readFull(data); + byte[] data = in.read(length); attribute.setInfo(data); attribute.initContent(pool); } return attribute; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java index d75c93d..40944c1 100644 --- a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java +++ b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,17 +47,13 @@ public class LazyLoader { } public ConstantPool loadPool(String classname) { - try { - DataInputFullStream in = getClassStream(classname); - if (in == null) return null; - - try { + try (DataInputFullStream in = getClassStream(classname)) { + if (in != null) { in.discard(8); return new ConstantPool(in); } - finally { - in.close(); - } + + return null; } catch (IOException ex) { throw new RuntimeException(ex); @@ -67,11 +63,8 @@ public class LazyLoader { public byte[] loadBytecode(StructMethod mt, int codeFullLength) { String className = mt.getClassStruct().qualifiedName; - try { - DataInputFullStream in = getClassStream(className); - if (in == null) return null; - - try { + try (DataInputFullStream in = getClassStream(className)) { + if (in != null) { in.discard(8); ConstantPool pool = mt.getClassStruct().getPool(); @@ -118,17 +111,13 @@ public class LazyLoader { } in.discard(12); - byte[] code = new byte[codeFullLength]; - in.readFull(code); - return code; + + return in.read(codeFullLength); } break; } } - finally { - in.close(); - } return null; } @@ -170,4 +159,4 @@ public class LazyLoader { this.internalPath = internalPath; } } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java b/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java index 011edde..ac71e20 100644 --- a/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java +++ b/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,36 +20,15 @@ import java.io.DataInputStream; import java.io.IOException; public class DataInputFullStream extends DataInputStream { - public DataInputFullStream(byte[] bytes) { super(new ByteArrayInputStream(bytes)); } - public int readFull(byte[] b) throws IOException { - int length = b.length; - byte[] temp = new byte[length]; - int pos = 0; - - int bytes_read; - while (true) { - bytes_read = read(temp, 0, length - pos); - if (bytes_read == -1) { - return -1; - } - - System.arraycopy(temp, 0, b, pos, bytes_read); - pos += bytes_read; - if (pos == length) { - break; - } - } - - return length; + public byte[] read(int n) throws IOException { + return InterpreterUtil.readBytes(this, n); } public void discard(int n) throws IOException { - if (super.skip(n) != n) { - throw new IOException("Skip failed"); - } + InterpreterUtil.discardBytes(this, n); } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java index 8ec1aaa..8130145 100644 --- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import java.io.*; -import java.nio.channels.FileChannel; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -31,27 +30,11 @@ public class InterpreterUtil { public static final int[] EMPTY_INT_ARRAY = new int[0]; - private static final int CHANNEL_WINDOW_SIZE = IS_WINDOWS ? 64 * 1024 * 1024 - (32 * 1024) : 64 * 1024 * 1024; // magic number for Windows private static final int BUFFER_SIZE = 16 * 1024; - public static void copyFile(File in, File out) throws IOException { - FileInputStream inStream = new FileInputStream(in); - try { - FileOutputStream outStream = new FileOutputStream(out); - try { - FileChannel inChannel = inStream.getChannel(); - FileChannel outChannel = outStream.getChannel(); - long size = inChannel.size(), position = 0; - while (position < size) { - position += inChannel.transferTo(position, CHANNEL_WINDOW_SIZE, outChannel); - } - } - finally { - outStream.close(); - } - } - finally { - inStream.close(); + public static void copyFile(File source, File target) throws IOException { + try (FileInputStream in = new FileInputStream(source); FileOutputStream out = new FileOutputStream(target)) { + copyStream(in, out); } } @@ -64,28 +47,35 @@ public class InterpreterUtil { } public static byte[] getBytes(ZipFile archive, ZipEntry entry) throws IOException { - return readAndClose(archive.getInputStream(entry), (int)entry.getSize()); + try (InputStream stream = archive.getInputStream(entry)) { + return readBytes(stream, (int)entry.getSize()); + } } public static byte[] getBytes(File file) throws IOException { - return readAndClose(new FileInputStream(file), (int)file.length()); + try (FileInputStream stream = new FileInputStream(file)) { + return readBytes(stream, (int)file.length()); + } } - private static byte[] readAndClose(InputStream stream, int length) throws IOException { - try { - byte[] bytes = new byte[length]; - int n = 0, off = 0; - while (n < length) { - int count = stream.read(bytes, off + n, length - n); - if (count < 0) { - throw new IOException("premature end of stream"); - } - n += count; + public static byte[] readBytes(InputStream stream, int length) throws IOException { + byte[] bytes = new byte[length]; + + int n = 0, off = 0; + while (n < length) { + int count = stream.read(bytes, off + n, length - n); + if (count < 0) { + throw new IOException("premature end of stream"); } - return bytes; + n += count; } - finally { - stream.close(); + + return bytes; + } + + public static void discardBytes(InputStream stream, int length) throws IOException { + if (stream.skip(length) != length) { + throw new IOException("premature end of stream"); } } @@ -159,4 +149,4 @@ public class InterpreterUtil { public static String makeUniqueKey(String name, String descriptor1, String descriptor2) { return name + ' ' + descriptor1 + ' ' + descriptor2; } -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java index 31778cb..7837905 100644 --- a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java +++ b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,26 +69,18 @@ public class BulkDecompilationTest { } private static void unpack(File archive, File targetDir) { - try { - ZipFile zip = new ZipFile(archive); - try { - Enumeration entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - if (!entry.isDirectory()) { - File file = new File(targetDir, entry.getName()); - assertTrue(file.getParentFile().mkdirs() || file.getParentFile().isDirectory()); - InputStream in = zip.getInputStream(entry); - OutputStream out = new FileOutputStream(file); + try (ZipFile zip = new ZipFile(archive)) { + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if (!entry.isDirectory()) { + File file = new File(targetDir, entry.getName()); + assertTrue(file.getParentFile().mkdirs() || file.getParentFile().isDirectory()); + try (InputStream in = zip.getInputStream(entry); OutputStream out = new FileOutputStream(file)) { InterpreterUtil.copyStream(in, out); - out.close(); - in.close(); } } } - finally { - zip.close(); - } } catch (IOException e) { throw new RuntimeException(e);