📄 utils.java
字号:
{
return plainUrl( null, urlStr );
}
/// Figure out the base URL for a given URL. What this means is
// if the URL points to a directory, you get that directory; if the
// URL points to a file, you get the directory the file is in.
public static String baseUrlStr( String urlStr )
{
if ( urlStr.endsWith( "/" ) )
return urlStr;
if ( urlStrIsDir( urlStr ) )
return urlStr + "/";
return urlStr.substring( 0, urlStr.lastIndexOf( '/' ) + 1 );
}
/// Makes sure if a URL is a directory, it ends with a slash.
public static String fixDirUrlStr( String urlStr )
{
if ( urlStr.endsWith( "/" ) )
return urlStr;
if ( urlStrIsDir( urlStr ) )
return urlStr + "/";
return urlStr;
}
/// Figures out whether a URL points to a directory or not.
// Web servers are lenient and accept directory-URLs without
// the trailing slash. What they actually do is return a
// redirect to the same URL with the trailing slash appended.
// Unfortunately, Java doesn't let us see that such a redirect
// happened. Instead we have to figure out it's a directory
// indirectly and heuristically.
public static boolean urlStrIsDir( String urlStr )
{
// If it ends with a slash, it's probably a directory.
if ( urlStr.endsWith( "/" ) )
return true;
// If the last component has a dot, it's probably not a directory.
int lastSlash = urlStr.lastIndexOf( '/' );
int lastPeriod = urlStr.lastIndexOf( '.' );
if ( lastPeriod != -1 && ( lastSlash == -1 || lastPeriod > lastSlash ) )
return false;
// Otherwise, append a slash and try to connect. This is
// fairly expensive.
String urlStrWithSlash = urlStr + "/";
try
{
URL url = new URL( urlStrWithSlash );
InputStream f = url.openStream();
f.close();
// Worked fine - it's probably a directory.
return true;
}
catch ( Exception e )
{
// Got an error - must not be a directory.
return false;
}
}
// Figures out whether a URL is absolute or not.
public static boolean urlStrIsAbsolute( String urlStr )
{
if ( urlStr.startsWith( "/" ) || urlStr.indexOf( ":/" ) != -1 )
return true;
// Should handle :8000/ and such too.
return false;
}
// Returns an equivalent URL string that is guaranteed to be absolute.
public static String absoluteUrlStr( String urlStr, URL contextUrl ) throws MalformedURLException
{
URL url = new URL( contextUrl, urlStr );
return url.toExternalForm();
}
/// URLDecoder to go along with java.net.URLEncoder. Why there isn't
// already a decoder in the standard library is a mystery to me.
public static String urlDecoder( String encoded )
{
StringBuffer decoded = new StringBuffer();
int len = encoded.length();
for ( int i = 0; i < len; ++i )
{
if ( encoded.charAt( i ) == '%' && i + 2 < len )
{
int d1 = Character.digit( encoded.charAt( i + 1 ), 16 );
int d2 = Character.digit( encoded.charAt( i + 2 ), 16 );
if ( d1 != -1 && d2 != -1 )
decoded.append( (char) ( ( d1 << 4 ) + d2 ) );
i += 2;
}
else if ( encoded.charAt( i ) == '+' )
decoded.append( ' ' );
else
decoded.append( encoded.charAt( i ) );
}
return decoded.toString();
}
/// A base-64 encoder, necessary for doing the client side of Basic
// Authentication. This encodes binary data as printable ASCII
// characters. Three 8-bit binary bytes are turned into four 6-bit
// values, like so:
//
// [11111111] [22222222] [33333333]
//
// [111111] [112222] [222233] [333333]
//
// Then the 6-bit values are represented using the characters "A-Za-z0-9+/".
public static String base64Encode( byte[] src )
{
StringBuffer encoded = new StringBuffer();
int i, phase = 0;
char c = 0;
for ( i = 0; i < src.length; ++i )
{
switch ( phase )
{
case 0:
c = b64EncodeTable[( src[i] >> 2 ) & 0x3f];
encoded.append( c );
c = b64EncodeTable[( src[i] & 0x3 ) << 4];
encoded.append( c );
++phase;
break;
case 1:
c = b64EncodeTable[
( b64DecodeTable[c] | ( src[i] >> 4 ) ) & 0x3f];
encoded.setCharAt( encoded.length() - 1, c );
c = b64EncodeTable[( src[i] & 0xf ) << 2];
encoded.append( c );
++phase;
break;
case 2:
c = b64EncodeTable[
( b64DecodeTable[c] | ( src[i] >> 6 ) ) & 0x3f];
encoded.setCharAt( encoded.length() - 1, c );
c = b64EncodeTable[src[i] & 0x3f];
encoded.append( c );
phase = 0;
break;
}
}
/* Pad with ='s. */
while ( phase++ < 3 )
encoded.append( '=' );
return encoded.toString();
}
private static char b64EncodeTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 00-07
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 08-15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16-23
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24-31
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32-39
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40-47
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48-55
'4', '5', '6', '7', '8', '9', '+', '/' // 56-63
};
private static int b64DecodeTable[] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 00-0F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 10-1F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, // 20-2F
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, // 30-3F
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, // 40-4F
15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, // 50-5F
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, // 60-6F
41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, // 70-7F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 80-8F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 90-9F
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // A0-AF
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // B0-BF
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // C0-CF
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // D0-DF
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // E0-EF
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 // F0-FF
};
/// A base-64 encoder that takes a String, for convenience.
public static String base64Encode( String srcString )
{
byte[] src = new byte[srcString.length()];
srcString.getBytes( 0, src.length, src, 0 );
return base64Encode( src );
}
/// Check if an array contains a given element.
public static boolean arraycontains( Object[] array, Object element )
{
for ( int i = 0; i < array.length; ++i )
if ( array[i].equals( element ) )
return true;
return false;
}
/// Run a program on the host system.
// <P>
// This routine runs the specified command, waits for it to
// finish, and returns the exit status.
// This is like the Unix system() routine. Unlike the Unix version,
// though, stdout and stderr get thrown away unless you redirect them.
public static int system( String cmd )
{
try
{
return runCommand( cmd ).waitFor();
}
catch ( IOException e )
{
return -1;
}
catch ( InterruptedException e )
{
return -1;
}
}
/// Run a program on the host system, and capture the output.
// <P>
// This routine runs the specified command, and returns an InputStream
// for reading the output of the program.
// <P>
// <B>WARNING:</B> In JDK1.0.2 there is a serious bug in the process
// IO routines, such that reading all the way to the end of a process's
// output will invariably get you an IOException( "read error" ).
// In some cases you will also <B>lose</B> the last bufferload of
// the output. The workaround is to add a " ; sleep 1" to the end of
// your command, and to ignore the "read error" IOException.
public static InputStream popenr( String cmd )
{
try
{
return runCommand( cmd ).getInputStream();
}
catch ( IOException e )
{
return null;
}
}
/// Run a program on the host system, and send it some input.
// <P>
// This routine runs the specified command, and returns an OutputStream
// for writing the program's input.
public static OutputStream popenw( String cmd )
{
try
{
return runCommand( cmd ).getOutputStream();
}
catch ( IOException e )
{
return null;
}
}
/// Run a program on the host system.
// <P>
// This routine runs the specified command, and returns a Process
// object so you can do what you like with it.
// <P>
// <B>WARNING:</B> In JDK1.0.2 there is a serious bug in the process
// IO routines, such that reading all the way to the end of a process's
// output will invariably get you an IOException( "read error" ).
// In some cases you will also <B>lose</B> the last bufferload of
// the output. The workaround is to add a " ; sleep 1" to the end of
// your command, and to ignore the "read error" IOException.
public static Process runCommand( String cmd ) throws IOException
{
Runtime runtime = Runtime.getRuntime();
String[] shCmd = new String[3];
shCmd[0] = "/bin/sh";
shCmd[1] = "-c";
shCmd[2] = cmd;
return runtime.exec( shCmd );
}
/// Copy the input to the output until EOF.
public static void copyStream( InputStream in, OutputStream out ) throws IOException
{
byte[] buf = new byte[4096];
int len;
while ( ( len = in.read( buf ) ) != -1 )
out.write( buf, 0, len );
}
/// Copy the input to the output until EOF.
public static void copyStream( Reader in, Writer out ) throws IOException
{
char[] buf = new char[4096];
int len;
while ( ( len = in.read( buf ) ) != -1 )
out.write( buf, 0, len );
}
/// Copy the input to the output until EOF.
public static void copyStream( InputStream in, Writer out ) throws IOException
{
byte[] buf1 = new byte[4096];
char[] buf2 = new char[4096];
int len, i;
while ( ( len = in.read( buf1 ) ) != -1 )
{
for ( i = 0; i < len; ++i )
buf2[i] = (char) buf1[i];
out.write( buf2, 0, len );
}
}
/// Copy the input to the output until EOF.
public static void copyStream( Reader in, OutputStream out ) throws IOException
{
char[] buf1 = new char[4096];
byte[] buf2 = new byte[4096];
int len, i;
while ( ( len = in.read( buf1 ) ) != -1 )
{
for ( i = 0; i < len; ++i )
buf2[i] = (byte) buf1[i];
out.write( buf2, 0, len );
}
}
/// Dump out the current call stack.
public static void dumpStack( PrintStream p )
{
(new Throwable()).printStackTrace( p );
}
/// Dump out the current call stack onto System.err.
public static void dumpStack()
{
(new Throwable()).printStackTrace();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -