From 8079272c05ddf87ca54ffc27e4abe3eb7677dd12 Mon Sep 17 00:00:00 2001 From: calvin1978 Date: Tue, 24 Jan 2017 12:06:41 +0800 Subject: [PATCH] =?UTF-8?q?#525=20=20URLResouceUtil=E5=8A=A0=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/utils/base/PropertiesUtil.java | 6 +- .../springside/modules/utils/io/FileUtil.java | 16 ++++ .../modules/utils/io/GeneralResourceUtil.java | 36 --------- .../modules/utils/io/URLResourceUtil.java | 80 +++++++++++++++++++ .../modules/utils/io/URLResourceTest.java | 68 ++++++++++++++++ 5 files changed, 167 insertions(+), 39 deletions(-) delete mode 100644 modules/utils/src/main/java/org/springside/modules/utils/io/GeneralResourceUtil.java create mode 100644 modules/utils/src/main/java/org/springside/modules/utils/io/URLResourceUtil.java create mode 100644 modules/utils/src/test/java/org/springside/modules/utils/io/URLResourceTest.java diff --git a/modules/utils/src/main/java/org/springside/modules/utils/base/PropertiesUtil.java b/modules/utils/src/main/java/org/springside/modules/utils/base/PropertiesUtil.java index 74559ac71..7961a4b60 100644 --- a/modules/utils/src/main/java/org/springside/modules/utils/base/PropertiesUtil.java +++ b/modules/utils/src/main/java/org/springside/modules/utils/base/PropertiesUtil.java @@ -8,8 +8,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springside.modules.utils.io.GeneralResourceUtil; import org.springside.modules.utils.io.IOUtil; +import org.springside.modules.utils.io.URLResourceUtil; import org.springside.modules.utils.number.NumberUtil; /** @@ -51,13 +51,13 @@ public static String getString(Properties p, String name, String defaultValue) { /** * 从文件路径加载properties. * - * 路径支持从外部文件或resources文件加载, "file://"代表外部文件, "classpath://"代表resources, + * 路径支持从外部文件或resources文件加载, "file://"或无前缀代表外部文件, "classpath://"代表resources, */ public static Properties loadFromFile(String generalPath) { Properties p = new Properties(); InputStream is = null; try { - is = GeneralResourceUtil.asStream(generalPath); + is = URLResourceUtil.asStream(generalPath); p.load(is); } catch (IOException e) { logger.warn("Load property from " + generalPath + " fail ", e); diff --git a/modules/utils/src/main/java/org/springside/modules/utils/io/FileUtil.java b/modules/utils/src/main/java/org/springside/modules/utils/io/FileUtil.java index 241769dba..f9240d5b9 100644 --- a/modules/utils/src/main/java/org/springside/modules/utils/io/FileUtil.java +++ b/modules/utils/src/main/java/org/springside/modules/utils/io/FileUtil.java @@ -33,6 +33,8 @@ * @author calvin */ public class FileUtil { + + //////// 文件读写////// @@ -77,6 +79,13 @@ public static void append(final CharSequence from, final File to) throws IOExcep public static InputStream asInputStream(String fileName) throws IOException { return new FileInputStream(getFileByPath(fileName)); } + + /** + * 打开文件为InputStream + */ + public static InputStream asInputStream(File file) throws IOException { + return new FileInputStream(file); + } /** * 打开文件为OutputStream @@ -84,6 +93,13 @@ public static InputStream asInputStream(String fileName) throws IOException { public static OutputStream asOututStream(String fileName) throws IOException { return new FileOutputStream(getFileByPath(fileName)); } + + /** + * 打开文件为OutputStream + */ + public static OutputStream asOututStream(File file) throws IOException { + return new FileOutputStream(file); + } /** * 获取File的BufferedReader diff --git a/modules/utils/src/main/java/org/springside/modules/utils/io/GeneralResourceUtil.java b/modules/utils/src/main/java/org/springside/modules/utils/io/GeneralResourceUtil.java deleted file mode 100644 index 58fc1e893..000000000 --- a/modules/utils/src/main/java/org/springside/modules/utils/io/GeneralResourceUtil.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.springside.modules.utils.io; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.lang3.StringUtils; - -import com.google.common.annotations.Beta; - -/** - * 兼容file://与classpath://的情况的工具集 - * - * @author calvin - */ -@Beta -public class GeneralResourceUtil { - - public static final String CLASSPATH = "classpath://"; - - public static final String FILE = "file://"; - - /** - * 兼容file://与classpath://的情况的打开文件成Stream - */ - public static InputStream asStream(String generalPath) throws IOException { - if (StringUtils.startsWith(generalPath, CLASSPATH)) { - String resourceName = StringUtils.substringAfter(generalPath, CLASSPATH); - return ResourceUtil.asStream(resourceName); - } else if (StringUtils.startsWith(generalPath, FILE)) { - String fileName = StringUtils.substringAfter(generalPath, FILE); - return FileUtil.asInputStream(fileName); - } else { - throw new IllegalArgumentException("unsupport resoure type:" + generalPath); - } - } -} diff --git a/modules/utils/src/main/java/org/springside/modules/utils/io/URLResourceUtil.java b/modules/utils/src/main/java/org/springside/modules/utils/io/URLResourceUtil.java new file mode 100644 index 000000000..94878833a --- /dev/null +++ b/modules/utils/src/main/java/org/springside/modules/utils/io/URLResourceUtil.java @@ -0,0 +1,80 @@ +package org.springside.modules.utils.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +/** + * 兼容url为无前缀,file://与classpath:// 三种情况的工具集 + * + * 参考Spring ResourceUtils + * + * @author calvin + */ +public class URLResourceUtil { + + private static final String CLASSPATH_PREFIX = "classpath://"; + + private static final String URL_PROTOCOL_FILE = "file"; + + /** + * 兼容无前缀, classpath://, file:// 的情况获取文件 + */ + public static File asFile(String generalPath) throws IOException { + if (StringUtils.startsWith(generalPath, CLASSPATH_PREFIX)) { + String resourceName = StringUtils.substringAfter(generalPath, CLASSPATH_PREFIX); + return getFileByURL(ResourceUtil.asUrl(resourceName)); + } + try { + // try URL + return getFileByURL(new URL(generalPath)); + } catch (MalformedURLException ex) { + // no URL -> treat as file path + return new File(generalPath); + } + } + + /** + * 兼容file://与classpath://的情况的打开文件成Stream + */ + public static InputStream asStream(String generalPath) throws IOException { + if (StringUtils.startsWith(generalPath, CLASSPATH_PREFIX)) { + String resourceName = StringUtils.substringAfter(generalPath, CLASSPATH_PREFIX); + return ResourceUtil.asStream(resourceName); + } + + try { + // try URL + return FileUtil.asInputStream(getFileByURL(new URL(generalPath))); + } catch (MalformedURLException ex) { + // no URL -> treat as file path + return FileUtil.asInputStream(generalPath); + } + } + + private static File getFileByURL(URL fileUrl) throws FileNotFoundException { + Validate.notNull(fileUrl, "Resource URL must not be null"); + if (!URL_PROTOCOL_FILE.equals(fileUrl.getProtocol())) { + throw new FileNotFoundException("URL cannot be resolved to absolute file path " + + "because it does not reside in the file system: " + fileUrl); + } + try { + return new File(toURI(fileUrl.toString()).getSchemeSpecificPart()); + } catch (URISyntaxException ex) { + // Fallback for URLs that are not valid URIs (should hardly ever happen). + return new File(fileUrl.getFile()); + } + } + + public static URI toURI(String location) throws URISyntaxException { + return new URI(StringUtils.replace(location, " ", "%20")); + } +} diff --git a/modules/utils/src/test/java/org/springside/modules/utils/io/URLResourceTest.java b/modules/utils/src/test/java/org/springside/modules/utils/io/URLResourceTest.java new file mode 100644 index 000000000..3491d1299 --- /dev/null +++ b/modules/utils/src/test/java/org/springside/modules/utils/io/URLResourceTest.java @@ -0,0 +1,68 @@ +package org.springside.modules.utils.io; + +import static org.assertj.core.api.Assertions.*; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Test; + +public class URLResourceTest { + + @Test + public void resource() throws IOException { + File file = URLResourceUtil.asFile("classpath://application.properties"); + assertThat(FileUtil.toString(file)).isEqualTo("springside.min=1\nspringside.max=10"); + + InputStream is = URLResourceUtil.asStream("classpath://application.properties"); + assertThat(IOUtil.toString(is)).isEqualTo("springside.min=1\nspringside.max=10"); + IOUtil.closeQuietly(is); + + try { + URLResourceUtil.asFile("classpath://notexist.properties"); + fail("should fail"); + } catch (Throwable t) { + assertThat(t).isInstanceOf(IllegalArgumentException.class); + } + + try { + URLResourceUtil.asStream("classpath://notexist.properties"); + fail("should fail"); + } catch (Throwable t) { + assertThat(t).isInstanceOf(IllegalArgumentException.class); + } + + } + + @Test + public void file() throws IOException { + File file = FileUtil.createTempFile(); + FileUtil.write("haha", file); + try { + File file2 = URLResourceUtil.asFile("file://" + file.getAbsolutePath()); + assertThat(FileUtil.toString(file2)).isEqualTo("haha"); + + try { + URLResourceUtil.asFile("file://" + file.getAbsolutePath() + ".noexist"); + fail("should fail"); + } catch (Throwable t) { + assertThat(t).isInstanceOf(IllegalArgumentException.class); + } + + File file3 = URLResourceUtil.asFile(file.getAbsolutePath()); + assertThat(FileUtil.toString(file3)).isEqualTo("haha"); + try { + URLResourceUtil.asFile(file.getAbsolutePath() + ".noexist"); + fail("should fail"); + } catch (Throwable t) { + assertThat(t).isInstanceOf(IllegalArgumentException.class); + } + + } finally { + FileUtil.deleteFile(file); + } + + } + +}