📄 utils.java
字号:
// Utils - assorted static utility routines
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
import java.util.*;
import java.io.*;
import java.net.*;
/// Assorted static utility routines.
// <P>
// Whenever I come up with a static routine that might be of general use,
// I put it here. So far the class includes:
// <UL>
// <LI> some string routines that were left out of java.lang.String
// <LI> a general array-to-string routine
// <LI> a fixed version of java.io.InputStream's byte-array read routine
// <LI> a bunch of URL-hacking routines
// <LI> some easy-to-use wrappers for Runtime.exec
// <LI> a debugging routine to dump the current call stack
// <LI> a URLDecoder to match java.net.URLEncoder
// </UL>
// and lots more.
// <P>
// <A HREF="/resources/classes/Acme/Utils.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
public class Utils
{
/// Returns a date string formatted in Unix ls style - if it's within
// six months of now, Mmm dd hh:ss, else Mmm dd yyyy.
public static String lsDateStr( Date date )
{
Calendar cal = new GregorianCalendar();
cal.setTime( date );
long dateTime = date.getTime();
if ( dateTime == -1L )
return "------------";
long nowTime = (new Date()).getTime();
String[] months = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
String part1 =
months[cal.get(Calendar.MONTH)] +
Fmt.fmt( cal.get(Calendar.DATE), 3 );
if ( Math.abs( nowTime - dateTime ) < 183L * 24L * 60L * 60L * 1000L )
return part1 + Fmt.fmt( cal.get(Calendar.HOUR_OF_DAY), 3 ) + ":" +
Fmt.fmt( cal.get(Calendar.MINUTE), 2, Fmt.ZF );
else
return part1 + Fmt.fmt( cal.get(Calendar.YEAR), 6 );
}
/// Returns "s" for numbers other than one, and "" for one.
public static String pluralStr( long n )
{
if ( n == 1 )
return "";
else
return "s";
}
// Various interval constants. Some are only approximate.
public static final long INT_SECOND = 1000L;
public static final long INT_MINUTE = INT_SECOND * 60L;
public static final long INT_HOUR = INT_MINUTE * 60L;
public static final long INT_DAY = INT_HOUR * 24L;
public static final long INT_WEEK = INT_DAY * 7L;
public static final long INT_MONTH = INT_DAY * 30L;
public static final long INT_YEAR = INT_DAY * 365L;
public static final long INT_DECADE = INT_DAY * 3652L;
/// Returns a string approximately describing a given time interval.
// @param interval the interval, in milliseconds
public static String intervalStr( long interval )
{
long decades, years, months, weeks, days, hours, minutes, seconds, millis;
decades = interval / INT_DECADE;
interval -= decades * INT_DECADE;
years = interval / INT_YEAR;
interval -= years * INT_YEAR;
months = interval / INT_MONTH;
interval -= months * INT_MONTH;
weeks = interval / INT_WEEK;
interval -= weeks * INT_WEEK;
days = interval / INT_DAY;
interval -= days * INT_DAY;
hours = interval / INT_HOUR;
interval -= hours * INT_HOUR;
minutes = interval / INT_MINUTE;
interval -= minutes * INT_MINUTE;
seconds = interval / INT_SECOND;
interval -= seconds * INT_SECOND;
millis = interval;
if ( decades > 0 )
if ( years == 0 )
return decades + " decade" + pluralStr( decades );
else
return
decades + " decade" + pluralStr( decades ) + ", " +
years + " years" + pluralStr( years );
else if ( years > 0 )
if ( months == 0 )
return years + " year" + pluralStr( years );
else
return
years + " year" + pluralStr( years ) + ", " +
months + " month" + pluralStr( months );
else if ( months > 0 )
if ( weeks == 0 )
return months + " month" + pluralStr( months );
else
return
months + " month" + pluralStr( months ) + ", " +
weeks + " week" + pluralStr( weeks );
else if ( weeks > 0 )
if ( days == 0 )
return weeks + " week" + pluralStr( weeks );
else
return
weeks + " week" + pluralStr( weeks ) + ", " +
days + " day" + pluralStr( days );
else if ( days > 0 )
if ( hours == 0 )
return days + " day" + pluralStr( days );
else
return
days + " day" + pluralStr( days ) + ", " +
hours + " hour" + pluralStr( hours );
else if ( hours > 0 )
if ( minutes == 0 )
return hours + " hour" + pluralStr( hours );
else
return
hours + " hour" + pluralStr( hours ) + ", " +
minutes + " minute" + pluralStr( minutes );
else if ( minutes > 0 )
if ( seconds == 0 )
return minutes + " minute" + pluralStr( minutes );
else
return
minutes + " minute" + pluralStr( minutes ) + ", " +
seconds + " second" + pluralStr( seconds );
else if ( seconds > 0 )
if ( millis == 0 )
return seconds + " second" + pluralStr( seconds );
else
return
seconds + " second" + pluralStr( seconds ) + ", " +
millis + " millisecond" + pluralStr( millis );
else
return millis + " millisecond" + pluralStr( millis );
}
/// Returns the length of the initial segment of str which consists
// entirely of characters from charSet.
public static int strSpan( String str, String charSet )
{
return strSpan( str, charSet, 0 );
}
/// Returns the length of the initial segment of str which consists
// entirely of characters from charSet, starting at the given index.
public static int strSpan( String str, String charSet, int fromIdx )
{
int i;
for ( i = fromIdx; i < str.length(); ++i )
if ( charSet.indexOf( str.charAt( i ) ) == -1 )
break;
return i - fromIdx;
}
/// Returns the length of the initial segment of str which consists
// entirely of characters NOT from charSet.
public static int strCSpan( String str, String charSet )
{
return strCSpan( str, charSet, 0 );
}
/// Returns the length of the initial segment of str which consists
// entirely of characters NOT from charSet, starting at the given index.
public static int strCSpan( String str, String charSet, int fromIdx )
{
int i;
for ( i = fromIdx; i < str.length(); ++i )
if ( charSet.indexOf( str.charAt( i ) ) != -1 )
break;
return i - fromIdx;
}
/// Checks whether a string matches a given wildcard pattern.
// Only does ? and *, and multiple patterns separated by |.
public static boolean match( String pattern, String string )
{
for ( int p = 0; ; ++p )
{
for ( int s = 0; ; ++p, ++s )
{
boolean sEnd = ( s >= string.length() );
boolean pEnd = ( p >= pattern.length() ||
pattern.charAt( p ) == '|' );
if ( sEnd && pEnd )
return true;
if ( sEnd || pEnd )
break;
if ( pattern.charAt( p ) == '?' )
continue;
if ( pattern.charAt( p ) == '*' )
{
int i;
++p;
for ( i = string.length(); i >= s; --i )
if ( match(
pattern.substring( p ),
string.substring( i ) ) ) /* not quite right */
return true;
break;
}
if ( pattern.charAt( p ) != string.charAt( s ) )
break;
}
p = pattern.indexOf( '|', p );
if ( p == -1 )
return false;
}
}
// /// Finds the maximum length of a string that matches a given wildcard
// // pattern. Only does ? and *, and multiple patterns separated by |.
// public static int matchSpan( String pattern, String string )
// {
// // !!!
// return 0;
// }
/// Returns the length of the initial segment of str1 that equals str2.
public static int sameSpan( String str1, String str2 )
{
int i;
for ( i = 0;
i < str1.length() && i < str2.length() &&
str1.charAt( i ) == str2.charAt( i );
++i )
;
return i;
}
/// Returns the number of times the given character appears in the string.
public static int charCount( String str, char c )
{
int n = 0;
for ( int i = 0; i < str.length(); ++i )
if ( str.charAt( i ) == c )
++n;
return n;
}
/// Turns a String into an array of Strings, by using StringTokenizer
// to split it up at whitespace.
public static String[] splitStr( String str )
{
StringTokenizer st = new StringTokenizer( str );
int n = st.countTokens();
String[] strs = new String[n];
for ( int i = 0; i < n; ++i )
strs[i] = st.nextToken();
return strs;
}
/// Turns a String into an array of Strings, by splitting it at
// the specified character. This does not use StringTokenizer,
// and therefore can handle empty fields.
public static String[] splitStr( String str, char delim )
{
int n = 1;
int index = -1;
while ( true )
{
index = str.indexOf( delim, index + 1 );
if ( index == -1 )
break;
++n;
}
String[] strs = new String[n];
index = -1;
for ( int i = 0; i < n - 1; ++i )
{
int nextIndex = str.indexOf( delim, index + 1 );
strs[i] = str.substring( index + 1, nextIndex );
index = nextIndex;
}
strs[n - 1] = str.substring( index + 1 );
return strs;
}
/// Turns an array of Strings into a single String, with the components
// separated by spaces.
public static String flattenStrarr( String[] strs )
{
StringBuffer sb = new StringBuffer();
for ( int i = 0; i < strs.length; ++i )
{
if ( i > 0 )
sb.append( ' ' );
sb.append( strs[i] );
}
return sb.toString();
}
/// Sorts an array of Strings.
// Java currently has no general sort function. Sorting Strings is
// common enough that it's worth making a special case.
public static void sortStrings( String[] strings )
{
// Just does a bubblesort.
for ( int i = 0; i < strings.length - 1; ++i )
{
for ( int j = i + 1; j < strings.length; ++j )
{
if ( strings[i].compareTo( strings[j] ) > 0 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -