urlfilesystem.java

来自「开源项目openfire的完整源程序」· Java 代码 · 共 620 行 · 第 1/2 页

JAVA
620
字号
     * Returns the name of the file contained by the {@link URL}, not
     * including any protocol, hostname authentication, directory path,
     * anchor, or query.  This simply returns the simple filename.  For
     * example, if you pass in an {@link URL} whose string representation
     * is:
     * <p/>
     * <BLOCKQUOTE><CODE>
     * protocol://host:1010/dir1/dir2/file.ext1.ext2#anchor?query
     * </CODE></BLOCKQUOTE>
     * <p/>
     * the returned value is "<CODE>file</CODE>" (without the quotes).<P>
     * <p/>
     * The returned file name should only be used for display purposes
     * and not for opening streams or otherwise trying to locate the
     * resource indicated by the {@link URL}.<P>
     * <p/>
     * The default implementation first calls {@link #getFileName(URL)} to
     * get the file name part.  Then all characters starting with the
     * first occurrence of '.' are removed.  The remaining string is then
     * returned.
     */
    public static String getName(URL url) {
        final String fileName = getFileName(url);
        final int firstDot = fileName.lastIndexOf('.');
        return firstDot > 0 ? fileName.substring(0, firstDot) : fileName;
    }


    /**
     * Returns the path part of the {@link URL}.
     * <p/>
     * The default implementation delegates to {@link URL#getPath()}.
     */
    public String getPath(URL url) {
        return url.getPath();
    }


    /**
     * Returns the path part of the {@link URL} without the last file
     * extension.  To clarify, the following examples demonstrate the
     * different cases that come up:
     * <p/>
     * <TABLE BORDER COLS=2 WIDTH="100%">
     * <TR>
     * <TD><CENTER>Path part of input {@link URL}</CENTER></TD>
     * <TD><CENTER>Output {@link String}</CENTER</TD>
     * </TR>
     * <TR>
     * <TD><CODE>/dir/file.ext</CODE></TD>
     * <TD><CODE>/dir/file</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/dir/file.ext1.ext2</CODE></TD>
     * <TD><CODE>/dir/file.ext1</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/dir1.ext1/dir2.ext2/file.ext1.ext2</CODE></TD>
     * <TD><CODE>/dir1.ext1/dir2.ext2/file.ext1</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/file.ext</CODE></TD>
     * <TD><CODE>/file</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/dir.ext/file</CODE></TD>
     * <TD><CODE>/dir.ext/file</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/dir/file</CODE></TD>
     * <TD><CODE>/dir/file</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/file</CODE></TD>
     * <TD><CODE>/file</CODE></TD>
     * <TR>
     * <TR>
     * <TD><CODE>/.ext</CODE></TD>
     * <TD><CODE>/</CODE></TD>
     * <TR>
     * </TABLE>
     * <p/>
     * The default implementation gets the path from {@link
     * #getPath(URL)} and then trims off all of the characters beginning
     * with the last "." in the path, if and only if the last "." comes
     * after the last "/" in the path.  If the last "." comes before
     * the last "/" or if there is no "." at all, then the entire path
     * is returned.
     */
    public String getPathNoExt(URL url) {
        final String path = getPath(url);
        final int lastSlash = path.lastIndexOf("/");
        final int lastDot = path.lastIndexOf(".");
        if (lastDot <= lastSlash) {
            //  When the lastDot < lastSlash, it means that one of the
            //  directories has an extension, but the filename itself has
            //  no extension.  In this case, returning the whole path is
            //  the correct behavior.
            //
            //  The only time that lastDot and lastSlash can be equal occurs
            //  when both of them are -1.  In that case, returning the whole
            //  path is the correct behavior.
            return path;
        }
        //  At this point, we know that lastDot must be non-negative, so
        //  we can return the whole path string up to the last dot.
        return path.substring(0, lastDot);
    }


    /**
     * Returns the platform-dependent String representation of the
     * {@link URL}; the returned string should be considered acceptable
     * for users to read.  In general, the returned string should omit
     * as many parts of the {@link URL} as possible.  For the "file"
     * protocol, therefore, the platform pathname should just be the
     * pathname alone (no protocol) using the appropriate file separator
     * character for the current platform.  For other protocols, it may
     * be necessary to reformat the {@link URL} string into a more
     * human-readable form.  That decision is left to each
     * <CODE>URLFileSystemHelper</CODE> implementor.
     * <p/>
     * The default implementation returns <CODE>url.toString()</CODE>.
     * If the {@link URL} is <CODE>null</CODE>, the empty string is
     * returned.
     *
     * @return The path portion of the specified {@link URL} in
     *         platform-dependent notation.  This value should only be used for
     *         display purposes and not for opening streams or otherwise trying
     *         to locate the document.
     */
    public String getPlatformPathName(URL url) {
        return url != null ? url.toString() : "";
    }

    public static URL newFileURL(File file) {
        String filePath = file.getPath();
        if (filePath == null) {
            return null;
        }
        final String path = sanitizePath(filePath);
        return newURL("file", path);
    }

    public static URL newFileURL(String filePath) {
        if (filePath == null) {
            return null;
        }
        final String path = sanitizePath(filePath);
        return newURL("file", path);
    }

    /**
     * This "sanitizes" the specified string path by converting all
     * {@link File#separatorChar} characters to forward slash ('/').
     * Also, a leading forward slash is prepended if the path does
     * not begin with one.
     */
    private static String sanitizePath(String path) {
        if (File.separatorChar != '/') {
            path = path.replace(File.separatorChar, '/');
        }
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        return path;
    }

    public static URL newURL(String protocol, String path) {
        return newURL(protocol, null, null, -1, path, null, null);
    }

    //--------------------------------------------------------------------------
    //  direct access factory methods...
    //--------------------------------------------------------------------------

    /**
     * Creates a new {@link URL} whose parts have the exact values that
     * are specified.  <EM>In general, you should avoid calling this
     * method directly.</EM><P>
     * <p/>
     * This method is the ultimate place where all of the other
     * <CODE>URLFactory</CODE> methods end up when creating an
     * {@link URL}.
     * <p/>
     * Non-sanitizing.
     */
    public static URL newURL(String protocol, String userinfo,
                             String host, int port,
                             String path, String query, String ref) {
        try {
            final URL seed = new URL(protocol, "", -1, "");
            final String authority = port < 0 ? host : host + ":" + port;
            final Object[] args = new Object[]
                    {
                            protocol, host, new Integer(port),
                            authority, userinfo,
                            path, query, ref,
                    };

            //  IMPORTANT -- this *MUST* be the only place in URLFactory where
            //  the URL.set(...) method is used.  --jdijamco
            urlSet.invoke(seed, args);
            return seed;
        }
        catch (Exception e) {
            Log.error(e);
            return null;
        }
    }

    /**
     * This {@link Method} is used to work-around a bug in Sun's
     * <CODE>java.net.URL</CODE> implementation.  The {@link Method}
     * allows us to set the parts of an {@link URL} directly.
     */
    private static final Method urlSet;

    static {
        final Class str = String.class;
        try {
            urlSet = URL.class.getDeclaredMethod("set", new Class[]{str, str, int.class, str, str, str, str, str});

            //  IMPORTANT:  This call to setAccessible effectively overrides
            //  the "protected" visibility constraint on the URL.set(...)
            //  method.  This is an intentional breaking of encapsulation to
            //  work-around severe bugs in Sun's java.net.URL implementation
            //  having to do with:
            //    *  poor handling of special characters like #, ?, and ;
            //    *  poor handling of whitespace
            //    *  no go way to disambiguate UNC paths on Win32
            //
            //  The use of setAccessible is an implementation detail of the
            //  URLFactory, and if Sun some day fixes their java.net.URL
            //  implementation to address the problems above, we may be able
            //  to change the internal mechanism to use the regular URL
            //  constructors.  For the time being, after having weighed the
            //  various other alternatives and even tried some of them (and
            //  encountered other problems), our decision is to force our way
            //  through to the URL.set(...) method, taking care to invoke
            //  it method exactly once per URL object with the exactly the
            //  right arguments.
            //
            //  --jdijamco  March 14, 2001
            urlSet.setAccessible(true);
        }
        catch (NoSuchMethodException e) {
            //!jdijamco -- Have some fallback option so that <clinit> doesn't
            //!jdijamco -- just totally barf and prevent the IDE from starting?
            throw new IllegalStateException();
        }
    }

    public static final File url2File(URL url) {
        final String path = url.getPath();
        final File file = new File(path);
        return file;
    }

    public static URL getParent(URL url) {
        final File file = url2File(url);
        final File parentFile = file.getParentFile();
        if (parentFile != null && !file.equals(parentFile)) {
            try {
                return parentFile.toURL();
            }
            catch (Exception ex) {
                return null;
            }
        }
        return null;
    }

    /**
     * Allows for the copying of entire directories/sub-dirs and their files.
     *
     * @param src the root directory to copy.
     * @param dst the destination directory.
     * @throws IOException thrown if there is an issue copying over the files.
     */
    public static void copyDir(File src, File dst) throws IOException {
        // Create the destination directory
        dst.mkdirs();

        // Loop through the files and directories in the source directory and copy them
        File[] files = src.listFiles();
        for (int i = 0; i < files.length; ++i) {
            if (files[i].isFile()) {
                copyFile(files[i], new File(dst, files[i].getName()));
            }
            else if (files[i].isDirectory()) {
                copyDir(files[i], new File(dst, files[i].getName()));
            }
        }
    }

    private static void copyFile(File src, File dst) throws IOException {
        FileChannel in = new FileInputStream(src).getChannel();
        FileChannel out = new FileOutputStream(dst).getChannel();

        // Fast and efficient way to copy a file
        in.transferTo(0, in.size(), out);

        in.close();
        out.close();
    }


}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?