Add comments to FileUtils and IOUtils

This commit is contained in:
huanghongxun 2019-02-23 23:42:05 +08:00
parent a388450f94
commit 9add2387b9
8 changed files with 91 additions and 38 deletions

View File

@ -225,16 +225,16 @@ public class LibraryDownloadTask extends Task {
int x = decompressed.length;
int len = decompressed[(x - 8)] & 0xFF | (decompressed[(x - 7)] & 0xFF) << 8 | (decompressed[(x - 6)] & 0xFF) << 16 | (decompressed[(x - 5)] & 0xFF) << 24;
File temp = FileUtils.createTempFile("minecraft", ".pack");
Path temp = Files.createTempFile("minecraft", ".pack");
byte[] checksums = Arrays.copyOfRange(decompressed, decompressed.length - len - 8, decompressed.length - 8);
OutputStream out = new FileOutputStream(temp);
out.write(decompressed, 0, decompressed.length - len - 8);
out.close();
try (OutputStream out = Files.newOutputStream(temp)) {
out.write(decompressed, 0, decompressed.length - len - 8);
}
try (FileOutputStream jarBytes = new FileOutputStream(dest); JarOutputStream jos = new JarOutputStream(jarBytes)) {
Pack200.newUnpacker().unpack(temp, jos);
Pack200.newUnpacker().unpack(temp.toFile(), jos);
JarEntry checksumsFile = new JarEntry("checksums.sha1");
checksumsFile.setTime(0L);
@ -243,6 +243,6 @@ public class LibraryDownloadTask extends Task {
jos.closeEntry();
}
temp.delete();
Files.delete(temp);
}
}

View File

@ -53,8 +53,6 @@ public final class VersionJsonSaveTask extends TaskResult<Version> {
@Override
public void execute() throws Exception {
File json = repository.getVersionJson(version.getId()).getAbsoluteFile();
if (!FileUtils.makeFile(json))
throw new IOException("Cannot create file " + json);
FileUtils.writeText(json, JsonUtils.GSON.toJson(version));
}
}

View File

@ -168,8 +168,8 @@ public class DefaultGameRepository implements GameRepository {
versions.remove(id);
if (FileUtils.isMovingToTrashSupported()) {
return FileUtils.moveToTrash(removedFile);
if (FileUtils.isMovingToTrashSupported() && FileUtils.moveToTrash(removedFile)) {
return true;
}
// remove json files first to ensure HMCL will not recognize this folder as a valid version.

View File

@ -23,7 +23,7 @@ import com.google.gson.reflect.TypeToken;
import org.jackhuang.hmcl.util.*;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.IOUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.File;
import java.io.IOException;
@ -119,7 +119,7 @@ public final class ForgeModMetadata {
Path mcmod = fs.getPath("mcmod.info");
if (Files.notExists(mcmod))
throw new IOException("File " + modFile + " is not a Forge mod.");
List<ForgeModMetadata> modList = JsonUtils.GSON.fromJson(IOUtils.readFullyAsString(Files.newInputStream(mcmod)),
List<ForgeModMetadata> modList = JsonUtils.GSON.fromJson(FileUtils.readText(mcmod),
new TypeToken<List<ForgeModMetadata>>() {
}.getType());
if (modList == null || modList.isEmpty())

View File

@ -33,6 +33,7 @@ import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.Optional;
@ -212,7 +213,7 @@ public class FileDownloadTask extends Task {
break;
}
File temp = null;
Path temp = null;
try {
updateProgress(0);
@ -242,15 +243,15 @@ public class FileDownloadTask extends Task {
if (!FileUtils.makeDirectory(file.getAbsoluteFile().getParentFile()))
throw new IOException("Could not make directory " + file.getAbsoluteFile().getParent());
temp = FileUtils.createTempFile();
rFile = new RandomAccessFile(temp, "rw");
temp = Files.createTempFile(null, null);
rFile = new RandomAccessFile(temp.toFile(), "rw");
MessageDigest digest = integrityCheck == null ? null : integrityCheck.createDigest();
stream = con.getInputStream();
int lastDownloaded = 0, downloaded = 0;
long lastTime = System.currentTimeMillis();
byte buffer[] = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
byte[] buffer = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
while (true) {
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
@ -283,16 +284,15 @@ public class FileDownloadTask extends Task {
// Restore temp file to original name.
if (Thread.interrupted()) {
temp.delete();
temp.toFile().delete();
Thread.currentThread().interrupt();
break;
} else {
if (file.exists() && !file.delete())
throw new IOException("Unable to delete existent file " + file);
Files.deleteIfExists(file.toPath());
if (!FileUtils.makeDirectory(file.getAbsoluteFile().getParentFile()))
throw new IOException("Unable to make parent directory " + file);
try {
FileUtils.moveFile(temp, file);
FileUtils.moveFile(temp.toFile(), file);
} catch (Exception e) {
throw new IOException("Unable to move temp file from " + temp + " to " + file, e);
}
@ -321,7 +321,7 @@ public class FileDownloadTask extends Task {
return;
} catch (IOException | IllegalStateException e) {
if (temp != null)
temp.delete();
temp.toFile().delete();
exception = e;
} finally {
closeFiles();

View File

@ -293,6 +293,11 @@ public abstract class Task {
return new TaskResult<R>() {
TaskResult<R> then;
@Override
public Collection<? extends Task> getDependents() {
return Collections.singleton(Task.this);
}
@Override
public void execute() throws Exception {
then = taskSupplier.get().storeTo(this::setResult);

View File

@ -116,14 +116,43 @@ public final class FileUtils {
return new String(Files.readAllBytes(file), charset);
}
/**
* Write plain text to file. Characters are encoded into bytes using UTF-8.
*
* We don't care about platform difference of line separator. Because readText accept all possibilities of line separator.
* It will create the file if it does not exist, or truncate the existing file to empty for rewriting.
* All characters in text will be written into the file in binary format. Existing data will be erased.
* @param file the path to the file
* @param text the text being written to file
* @throws IOException if an I/O error occurs
*/
public static void writeText(File file, String text) throws IOException {
writeText(file, text, UTF_8);
}
/**
* Write plain text to file.
*
* We don't care about platform difference of line separator. Because readText accept all possibilities of line separator.
* It will create the file if it does not exist, or truncate the existing file to empty for rewriting.
* All characters in text will be written into the file in binary format. Existing data will be erased.
* @param file the path to the file
* @param text the text being written to file
* @param charset the charset to use for encoding
* @throws IOException if an I/O error occurs
*/
public static void writeText(File file, String text, Charset charset) throws IOException {
writeBytes(file, text.getBytes(charset));
}
/**
* Write byte array to file.
* It will create the file if it does not exist, or truncate the existing file to empty for rewriting.
* All bytes in byte array will be written into the file in binary format. Existing data will be erased.
* @param file the path to the file
* @param array the data being written to file
* @throws IOException if an I/O error occurs
*/
public static void writeBytes(File file, byte[] array) throws IOException {
Files.createDirectories(file.toPath().getParent());
Files.write(file.toPath(), array);
@ -153,6 +182,14 @@ public final class FileUtils {
}
}
/**
* Copy directory.
* Paths of all files relative to source directory will be the same as the ones relative to destination directory.
*
* @param src the source directory.
* @param dest the destination directory, which will be created if not existing.
* @throws IOException if an I/O error occurs.
*/
public static void copyDirectory(Path src, Path dest) throws IOException {
Files.walkFileTree(src, new SimpleFileVisitor<Path>(){
@Override
@ -173,6 +210,20 @@ public final class FileUtils {
});
}
/**
* Move file to trash.
*
* This method is only implemented in Java 9. Please check we are using Java 9 by invoking isMovingToTrashSupported.
* Example:
* <pre>{@code
* if (FileUtils.isMovingToTrashSupported()) {
* FileUtils.moveToTrash(file);
* }
* }</pre>
* @param file the file being moved to trash.
* @see FileUtils#isMovingToTrashSupported()
* @return false if moveToTrash does not exist, or platform does not support Desktop.Action.MOVE_TO_TRASH
*/
public static boolean moveToTrash(File file) {
try {
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
@ -314,20 +365,4 @@ public final class FileUtils {
result.add(it);
return result;
}
public static File createTempFile() throws IOException {
return createTempFile("tmp");
}
public static File createTempFile(String prefix) throws IOException {
return createTempFile(prefix, null);
}
public static File createTempFile(String prefix, String suffix) throws IOException {
return createTempFile(prefix, suffix, null);
}
public static File createTempFile(String prefix, String suffix, File directory) throws IOException {
return File.createTempFile(prefix, suffix, directory);
}
}

View File

@ -21,8 +21,9 @@ import java.io.*;
import java.nio.charset.Charset;
/**
* This utility class consists of some util methods operating on InputStream/OutputStream.
*
* @author huang
* @author huangyuhui
*/
public final class IOUtils {
@ -31,12 +32,26 @@ public final class IOUtils {
public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
/**
* Read all bytes to a buffer from given input stream. The stream will not be closed.
*
* @param stream the InputStream being read.
* @return all bytes read from the stream
* @throws IOException if an I/O error occurs.
*/
public static byte[] readFullyWithoutClosing(InputStream stream) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
copyTo(stream, result);
return result.toByteArray();
}
/**
* Read all bytes to a buffer from given input stream, and close the input stream finally.
*
* @param stream the InputStream being read, closed finally.
* @return all bytes read from the stream
* @throws IOException if an I/O error occurs.
*/
public static ByteArrayOutputStream readFully(InputStream stream) throws IOException {
try (InputStream is = stream) {
ByteArrayOutputStream result = new ByteArrayOutputStream();