Cleanup (I/O ops in java-decompiler)

master
Roman Shevchenko 9 years ago
parent 5795c1d9e0
commit 23da5d99d2
  1. 38
      src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
  2. 10
      src/org/jetbrains/java/decompiler/struct/ContextUnit.java
  3. 29
      src/org/jetbrains/java/decompiler/struct/StructContext.java
  4. 10
      src/org/jetbrains/java/decompiler/struct/StructMember.java
  5. 31
      src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java
  6. 31
      src/org/jetbrains/java/decompiler/util/DataInputFullStream.java
  7. 64
      src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
  8. 26
      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.
@ -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);
}
}
}
}

@ -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<StructClass> getClasses() {
return classes;
}
}
}

@ -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<? extends ZipEntry> entries = archive.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
@ -178,12 +170,9 @@ public class StructContext {
}
}
}
finally {
archive.close();
}
}
public Map<String, StructClass> getClasses() {
return classes;
}
}
}

@ -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;
}
}
}

@ -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;
}
}
}
}

@ -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);
}
}
}

@ -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;
}
}
}

@ -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<? extends ZipEntry> 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<? extends ZipEntry> 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);

Loading…
Cancel
Save