简体   繁体   English

如何使用 Java 1.8 更改/重构方法以将 FileInputStream 用于本地文件以及将 InputStream 用于 URL?

[英]How to alter / refactor method to use FileInputStream for a local file along with InputStream for a URL using Java 1.8?

Using Java 1.8, I created a class which obtains a zip file from an external HTTP URL: Using Java 1.8, I created a class which obtains a zip file from an external HTTP URL:

eg例如

https://raw.githubusercontent.com/mlampros/DataSets/master/fastText_data.zip

and converts it into a String based MD5 hash:并将其转换为基于字符串的 MD5 hash:

6aa2fe666f83953a089a2caa8b13b80e

My utility class:我的实用程序 class:

public class HashUtils {
 
    public static String makeHashFromUrl(String fileUrl) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            InputStream is = new URL(fileUrl).openStream();

            try {
                is = new DigestInputStream(is, md);

                // Up to 8K per read
                byte[] ignoredBuffer = new byte[8 * 1024];

                while (is.read(ignoredBuffer) > 0) { }
            } finally {
                is.close();
            }
            byte[] digest = md.digest();
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < digest.length; i++) {
                sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
            }
            return sb.toString();

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

Whereas this is fine for an external URL containing zip file (or any file with any type of file extension), I need to be be able to use the same code (algorithm) for files that reside on a local filesystem.虽然这对于包含 zip 文件(或具有任何类型文件扩展名的任何文件)的外部 URL 来说很好,但我需要能够对驻留在本地文件系统上的文件使用相同的代码(算法)。

eg例如

Inside $CATALINA_HOME/temp/fastText_data.zip $CATALINA_HOME/temp/fastText_data.zip

Would need to use this instead:需要改用这个:

InputStream fis =  new FileInputStream(filename);

How could I do this using the same method (don't want to violate DRY - Don't Repeat Yourself)?我怎么能使用相同的方法来做到这一点(不想违反 DRY - 不要重复自己)?

Of course, creating a brand new method containing the same code but using the InputStream fis = new FileInputStream(filename);当然,创建一个包含相同代码但使用InputStream fis = new FileInputStream(filename); instead of InputStream is = new URL(fileUrl).openStream();而不是InputStream is = new URL(fileUrl).openStream(); would be violating the DRY principle?会违反 DRY 原则吗?

What would be a good way to refactor this out?什么是重构它的好方法? Two public methods with a refactored private method containing the same lines of code?两个包含相同代码行的重构私有方法的公共方法?

Make three methods: A private method that expects an InputStream argument which is given to your current logic, and two very short public methods which each call the private method with an InputStream they create.创建三个方法:一个私有方法,它需要一个 InputStream 参数,该参数提供给您当前的逻辑,以及两个非常短的公共方法,每个方法都使用他们创建的 InputStream 调用私有方法。

public static String makeHashFromUrl(String url) {
    try (InputStream stream = new URL(url).openStream()) {
        return makeHashFromStream(stream);
    }
}

public static String makeHashFromFile(File file) {
    try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
        return makeHashFromStream(stream);
    }
}

private static String makeHashFromStream(InputStream is) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");

        try {
            is = new DigestInputStream(is, md);

            // etc.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM