This commit is contained in:
Looly 2023-07-29 12:58:43 +08:00
parent 09f4abf75a
commit ed84445a6c
13 changed files with 172 additions and 24 deletions

View File

@ -64,6 +64,11 @@ public class BytesResource implements Resource, Serializable {
return null;
}
@Override
public long size() {
return this.bytes.length;
}
@Override
public InputStream getStream() {
return new ByteArrayInputStream(this.bytes);

View File

@ -77,6 +77,11 @@ public class CharSequenceResource implements Resource, Serializable {
return null;
}
@Override
public long size() {
return data.length();
}
@Override
public InputStream getStream() {
return new ByteArrayInputStream(readBytes());

View File

@ -14,6 +14,7 @@ package org.dromara.hutool.core.io.resource;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.net.url.URLUtil;
import javax.tools.FileObject;
import java.io.BufferedReader;
@ -65,6 +66,11 @@ public class FileObjectResource implements Resource {
}
}
@Override
public long size() {
return URLUtil.size(getUrl());
}
@Override
public InputStream getStream() {
try {

View File

@ -89,6 +89,11 @@ public class FileResource implements Resource, Serializable {
return URLUtil.getURL(this.file);
}
@Override
public long size() {
return this.file.length();
}
@Override
public InputStream getStream() throws NoResourceException {
return FileUtil.getInputStream(this.file);

View File

@ -51,6 +51,11 @@ public class HttpResource implements Resource, Serializable {
return resource.getUrl();
}
@Override
public long size() {
return resource.size();
}
@Override
public InputStream getStream() {
return resource.getStream();

View File

@ -12,6 +12,9 @@
package org.dromara.hutool.core.io.resource;
import org.dromara.hutool.core.io.IORuntimeException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
@ -59,6 +62,15 @@ public class InputStreamResource implements Resource, Serializable {
return null;
}
@Override
public long size() {
try {
return this.in.available();
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
@Override
public InputStream getStream() {
return this.in;

View File

@ -70,6 +70,11 @@ public class MultiResource implements Resource, Iterable<Resource>, Iterator<Res
return resources.get(cursor).getUrl();
}
@Override
public long size() {
return resources.get(cursor).size();
}
@Override
public InputStream getStream() {
return resources.get(cursor).getStream();

View File

@ -12,7 +12,6 @@
package org.dromara.hutool.core.io.resource;
import org.dromara.hutool.core.exception.ExceptionUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.text.StrUtil;
@ -25,24 +24,72 @@ import org.dromara.hutool.core.text.StrUtil;
public class NoResourceException extends IORuntimeException {
private static final long serialVersionUID = -623254467603299129L;
public NoResourceException(final Throwable e) {
super(ExceptionUtil.getMessage(e), e);
/**
* 构造
*/
public NoResourceException() {
super();
}
/**
* 构造
*
* @param e 异常
*/
public NoResourceException(final Throwable e) {
super(e);
}
/**
* 构造
*
* @param message 消息
*/
public NoResourceException(final String message) {
super(message);
}
/**
* 构造
*
* @param messageTemplate 消息模板
* @param params 参数
*/
public NoResourceException(final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public NoResourceException(final String message, final Throwable throwable) {
super(message, throwable);
/**
* 构造
*
* @param message 消息
* @param cause 被包装的子异常
*/
public NoResourceException(final String message, final Throwable cause) {
super(message, cause);
}
public NoResourceException(final Throwable throwable, final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
/**
* 构造
*
* @param message 消息
* @param cause 被包装的子异常
* @param enableSuppression 是否启用抑制
* @param writableStackTrace 堆栈跟踪是否应该是可写的
*/
public NoResourceException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
/**
* 构造
*
* @param cause 被包装的子异常
* @param messageTemplate 消息模板
* @param params 参数
*/
public NoResourceException(final Throwable cause, final String messageTemplate, final Object... params) {
super(StrUtil.format(messageTemplate, params), cause);
}
/**

View File

@ -58,6 +58,13 @@ public interface Resource {
*/
URL getUrl();
/**
* 获取资源大小
*
* @return 资源大小
*/
long size();
/**
* 获得 {@link InputStream}
*

View File

@ -12,16 +12,15 @@
package org.dromara.hutool.core.io.resource;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.file.FileNameUtil;
import org.dromara.hutool.core.net.NetUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.core.net.url.URLUtil;
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.io.*;
import java.net.*;
/**
* URL资源访问类
@ -78,6 +77,11 @@ public class UrlResource implements Resource, Serializable{
return this.url;
}
@Override
public long size() {
return URLUtil.size(this.url);
}
@Override
public InputStream getStream() throws NoResourceException{
if(null == this.url){

View File

@ -112,6 +112,7 @@ public class VfsResource implements Resource {
*
* @return VFS文件大小
*/
@Override
public long size() {
return MethodUtil.invoke(virtualFile, VIRTUAL_FILE_METHOD_GET_SIZE);
}

View File

@ -679,7 +679,14 @@ public class NetUtil {
return name;
}
// ----------------------------------------------------------------------------------------- Private method start
/**
* 如果连接为JNLP方式则打开缓存
*
* @param con {@link URLConnection}
* @since 6.0.0
*/
public static void useCachesIfNecessary(URLConnection con) {
con.setUseCaches(con.getClass().getSimpleName().startsWith("JNLP"));
}
// ----------------------------------------------------------------------------------------- Private method end
}

View File

@ -17,8 +17,10 @@ import org.dromara.hutool.core.exception.HutoolException;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.io.file.FileNameUtil;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.net.NetUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.CharsetUtil;
@ -112,12 +114,12 @@ public class URLUtil {
*
* @param uri {@link URI}
* @return URL对象
* @see URI#toURL()
* @throws HutoolException {@link MalformedURLException}包装URI格式有问题时抛出
* @see URI#toURL()
* @since 5.7.21
*/
public static URL url(final URI uri) throws HutoolException {
if(null == uri){
if (null == uri) {
return null;
}
try {
@ -146,7 +148,7 @@ public class URLUtil {
* @since 4.1.1
*/
public static URL url(String url, final URLStreamHandler handler) {
if(null == url){
if (null == url) {
return null;
}
@ -176,7 +178,7 @@ public class URLUtil {
* @since 5.5.2
*/
public static URI getStringURI(final CharSequence content) {
if(null == content){
if (null == content) {
return null;
}
final String contentStr = StrUtil.addPrefixIfNot(content, "string:///");
@ -420,8 +422,8 @@ public class URLUtil {
Assert.notNull(url, "URL must be not null");
final String protocol = url.getProtocol();
return (URL_PROTOCOL_FILE.equals(protocol) || //
URL_PROTOCOL_VFSFILE.equals(protocol) || //
URL_PROTOCOL_VFS.equals(protocol));
URL_PROTOCOL_VFSFILE.equals(protocol) || //
URL_PROTOCOL_VFS.equals(protocol));
}
/**
@ -434,9 +436,9 @@ public class URLUtil {
Assert.notNull(url, "URL must be not null");
final String protocol = url.getProtocol();
return (URL_PROTOCOL_JAR.equals(protocol) || //
URL_PROTOCOL_ZIP.equals(protocol) || //
URL_PROTOCOL_VFSZIP.equals(protocol) || //
URL_PROTOCOL_WSJAR.equals(protocol));
URL_PROTOCOL_ZIP.equals(protocol) || //
URL_PROTOCOL_VFSZIP.equals(protocol) || //
URL_PROTOCOL_WSJAR.equals(protocol));
}
/**
@ -449,7 +451,7 @@ public class URLUtil {
public static boolean isJarFileURL(final URL url) {
Assert.notNull(url, "URL must be not null");
return (URL_PROTOCOL_FILE.equals(url.getProtocol()) && //
url.getPath().toLowerCase().endsWith(FileNameUtil.EXT_JAR));
url.getPath().toLowerCase().endsWith(FileNameUtil.EXT_JAR));
}
/**
@ -706,4 +708,41 @@ public class URLUtil {
return builder.toString();
}
/**
* 获取URL对应数据长度
* <ul>
* <li>如果URL为文件转换为文件获取文件长度</li>
* <li>其它情况获取{@link URLConnection#getContentLengthLong()}</li>
* </ul>
*
* @param url URL
* @return 长度
* @since 6.0.0
*/
public static long size(final URL url) {
if (URLUtil.isFileURL(url)) {
// 如果资源以独立文件形式存在尝试获取文件长度
final File file = FileUtil.file(url);
final long length = file.length();
if (length == 0L && !file.exists()) {
throw new IORuntimeException("File not exist or size is zero!");
}
return length;
} else {
// 如果资源打在jar包中或来自网络使用网络请求长度
// issue#3226, 来自Spring的AbstractFileResolvingResource
try {
final URLConnection con = url.openConnection();
NetUtil.useCachesIfNecessary(con);
if (con instanceof HttpURLConnection) {
final HttpURLConnection httpCon = (HttpURLConnection) con;
httpCon.setRequestMethod("HEAD");
}
return con.getContentLengthLong();
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
}
}