URL URI File Path 转换(原创)

File to URI:     
          File file = ...;
          URI uri = file.toURI();


File to URL:     
          File file = ...;
          URL url = file.toURI().URL();


URL to File:     
          URL url = ...;
          File file = new Path(url.getPath()).toFile();


URI to URL:     
          URI uri = ...;
          URL url = uri.toURL();


URL to URI:     
          URL url = ...;
          URI uri = url.toURI();


一般情况下采用上述方式都可以安全的使用.


但是, 当处理本地路径且有空格,或者特殊字符,比如汉字等. 路径在相互的转换过程中, 可能会出现转换的无效字符错误异常.
所以, 可以使用Eclipse提供的工具类org.eclipse.core.runtime.URIUtil (插件: org.eclipse.equinox.simpleconfigurator)来进行转换.
URL <wbr>URI <wbr>File <wbr>Path <wbr>转换(原创)


比如URL to File:   
          URL url = ...;
          File file = URIUtil.toFile(URIUtil.toURI(url));


当URL, URI直接互相转换时,也可以使用该URIUtil工具类.
toURI
toURL


还有一个工具类,就是org.eclipse.core.runtime.FileLocator(插件: org.eclipse.equinox.common) 也可以对URL进行File的格式化. 比如toFileURL方法.




附源码:
 
package org.eclipse.equinox.internal.simpleconfigurator.utils;


import java.io.File;
import java.net.*;




public class URIUtil {


    private static final String SCHEME_FILE = "file"; //$NON-NLS-1$
    private static final String UNC_PREFIX = "//"; //$NON-NLS-1$


   
    public static URI append(URI base, String extension) {
        try {
            String path = base.getPath();
            if (path == null)
                return appendOpaque(base, extension);
            //if the base is already a directory then resolve will just do the right thing
            if (path.endsWith("/")) {//$NON-NLS-1$
                URI result = base.resolve(extension);
                //Fix UNC paths that are incorrectly normalized by URI#resolve (see Java bug 4723726)
                String resultPath = result.getPath();
                if (path.startsWith(UNC_PREFIX) && (resultPath == null || !resultPath.startsWith(UNC_PREFIX)))
                    result = new URI(result.getScheme(), "///" + result.getSchemeSpecificPart(), result.getFragment()); //$NON-NLS-1$
                return result;
            }
            path = path + "/" + extension; //$NON-NLS-1$
            return new URI(base.getScheme(), base.getUserInfo(), base.getHost(), base.getPort(), path, base.getQuery(), base.getFragment());
        } catch (URISyntaxException e) {
            //shouldn't happen because we started from a valid URI
            throw new RuntimeException(e);
        }
    }


   
    private static URI appendOpaque(URI base, String extension) throws URISyntaxException {
        String ssp = base.getSchemeSpecificPart();
        if (ssp.endsWith("/")) //$NON-NLS-1$
            ssp += extension;
        else
            ssp = ssp + "/" + extension; //$NON-NLS-1$
        return new URI(base.getScheme(), ssp, base.getFragment());
    }


   
    public static URI fromString(String uriString) throws URISyntaxException {
        int colon = uriString.indexOf(':');
        int hash = uriString.lastIndexOf('#');
        boolean noHash = hash < 0;
        if (noHash)
            hash = uriString.length();
        String scheme = colon < 0 ? null : uriString.substring(0, colon);
        String ssp = uriString.substring(colon + 1, hash);
        String fragment = noHash ? null : uriString.substring(hash + 1);
        //use java.io.File for constructing file: URIs
        if (scheme != null && scheme.equals(SCHEME_FILE)) {
            File file = new File(uriString.substring(5));
            if (file.isAbsolute())
                return file.toURI();
            scheme = null;
            if (File.separatorChar != '/')
                ssp = ssp.replace(File.separatorChar, '/');
        }
        return new URI(scheme, ssp, fragment);
    }


   
    public static boolean sameURI(URI url1, URI url2) {
        if (url1 == url2)
            return true;
        if (url1 == null || url2 == null)
            return false;
        if (url1.equals(url2))
            return true;


        if (url1.isAbsolute() != url2.isAbsolute())
            return false;


        // check if we have two local file references that are case variants
        File file1 = toFile(url1);
        return file1 == null ? false : file1.equals(toFile(url2));
    }


   
    public static File toFile(URI uri) {
        try {
            if (!SCHEME_FILE.equalsIgnoreCase(uri.getScheme()))
                return null;
            //assume all illegal characters have been properly encoded, so use URI class to unencode
            return new File(uri);
        } catch (IllegalArgumentException e) {
            //File constructor does not support non-hierarchical URI
            String path = uri.getPath();
            //path is null for non-hierarchical URI such as file:c:/tmp
            if (path == null)
                path = uri.getSchemeSpecificPart();
            return new File(path);
        }
    }


   
    public static String toUnencodedString(URI uri) {
        StringBuffer result = new StringBuffer();
        String scheme = uri.getScheme();
        if (scheme != null)
            result.append(scheme).append(':');
        //there is always a ssp
        result.append(uri.getSchemeSpecificPart());
        String fragment = uri.getFragment();
        if (fragment != null)
            result.append('#').append(fragment);
        return result.toString();
    }


   
    public static URI toURI(URL url) throws URISyntaxException {
        //URL behaves differently across platforms so for file: URLs we parse from string form
        if (SCHEME_FILE.equals(url.getProtocol())) {
            String pathString = url.toExternalForm().substring(5);
            //ensure there is a leading slash to handle common malformed URLs such as file:c:/tmp
            if (pathString.indexOf('/') != 0)
                pathString = '/' + pathString;
            else if (pathString.startsWith(UNC_PREFIX) && !pathString.startsWith(UNC_PREFIX, 2)) {
                //URL encodes UNC path with two slashes, but URI uses four (see bug 207103)
                pathString = UNC_PREFIX + pathString;
            }
            return new URI(SCHEME_FILE, null, pathString, null);
        }
        try {
            return new URI(url.toExternalForm());
        } catch (URISyntaxException e) {
            //try multi-argument URI constructor to perform encoding
            return new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
        }
    }


   
    public static URL toURL(URI uri) throws MalformedURLException {
        return new URL(uri.toString());
    }
}
当出现 `invalid URI path error` 时,通常意味着程序尝试解析一个不符合预期格式的统一资源标识符(Uniform Resource Identifier, URI)。这种错误可能出现在多种编程语言和框架中,例如 Java、Hadoop、Python 等。以下是常见的原因和排查方法: ### URI路径错误的常见原因 1. **URI格式不完整或缺失主机名** URI 应该包含协议类型、主机名以及路径信息。例如:`hdfs://host/path` 或 `file:///path/to/file`。如果 URI 中缺少主机部分(如 `hdfs:///user/ds/Wikipedia`),则会抛出异常[^1]。 2. **使用了错误的协议前缀** 某些系统要求特定的协议(如 HDFS、HTTPS、FTP)来访问数据源。如果使用了不支持的协议或拼写错误,例如 `htps://example.com`,也会导致 URI 解析失败。 3. **路径中存在非法字符或空格** URI 路径中不应包含特殊字符(如 `#`, `{`, `}` 等),除非它们被正确编码。未编码的空格也可能导致解析失败。 4. **本地文件系统路径误用为 URI** 在某些库或框架中(如 Apache Hadoop),期望输入的是标准 URI 格式,而不是本地文件路径。此时应将本地路径转换为 `file:///` 类型的 URI。 5. **操作系统相关限制(如 Windows 路径格式问题)** Windows 上的路径通常采用 `C:\path\to\file` 格式,而 URI 更倾向于 `/` 分隔符。在跨平台开发中,路径格式未做适配可能导致 URI 错误。 ### 排查与解决方法 - **检查 URI 的结构是否完整** 确保 URI 包含协议头和主机信息(如果是网络资源),例如 `hdfs://namenode:9000/user/ds/Wikipedia`。对于本地文件路径,可使用 `file:///` 协议进行封装。 - **对路径进行 URL 编码处理** 如果路径中包含中文、空格或特殊字符,需对其进行编码。例如,将空格替换为 `%20`,将中文字符转换为 UTF-8 编码后的百分号表示形式。 - **验证配置文件中的路径设置** 若 URI 来自配置文件(如 XML、YAML 或 JSON),请检查是否存在拼写错误或格式问题。建议使用配置校验工具辅助排查。 - **使用日志或调试器定位具体出错位置** 在代码中加入日志输出语句或使用调试器,查看传入 URI 构造函数的具体字符串内容,确认其格式是否符合预期。 - **参考系统错误代码定位底层问题** 在某些情况下,操作系统会返回特定的错误代码(System Error Codes),帮助识别路径无法访问的根本原因。例如在 Windows 平台上,可通过错误码查询对应含义[^2]。 ### 示例:Java 中修复 HDFS URI 问题 ```java import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; public class HDFSTest { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); // 正确的 URI 应包含主机名和端口 FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"), conf); System.out.println("Connected to HDFS"); fs.close(); } } ``` 若 URI 写成 `hdfs:///user/ds/Wikipedia`,则会抛出 `IOException`,提示“Incomplete HDFS URI, no host”[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值