StringUtils.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:21k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.util;
  19. import java.io.PrintWriter;
  20. import java.io.StringWriter;
  21. import java.net.InetAddress;
  22. import java.net.URI;
  23. import java.net.URISyntaxException;
  24. import java.net.UnknownHostException;
  25. import java.text.DateFormat;
  26. import java.text.DecimalFormat;
  27. import java.text.NumberFormat;
  28. import java.util.Locale;
  29. import java.util.ArrayList;
  30. import java.util.Arrays;
  31. import java.util.Date;
  32. import java.util.List;
  33. import java.util.StringTokenizer;
  34. import java.util.Collection;
  35. import org.apache.hadoop.fs.*;
  36. /**
  37.  * General string utils
  38.  */
  39. public class StringUtils {
  40.   private static final DecimalFormat decimalFormat;
  41.   static {
  42.           NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ENGLISH);
  43.           decimalFormat = (DecimalFormat) numberFormat;
  44.           decimalFormat.applyPattern("#.##");
  45.   }
  46.   /**
  47.    * Make a string representation of the exception.
  48.    * @param e The exception to stringify
  49.    * @return A string with exception name and call stack.
  50.    */
  51.   public static String stringifyException(Throwable e) {
  52.     StringWriter stm = new StringWriter();
  53.     PrintWriter wrt = new PrintWriter(stm);
  54.     e.printStackTrace(wrt);
  55.     wrt.close();
  56.     return stm.toString();
  57.   }
  58.   
  59.   /**
  60.    * Given a full hostname, return the word upto the first dot.
  61.    * @param fullHostname the full hostname
  62.    * @return the hostname to the first dot
  63.    */
  64.   public static String simpleHostname(String fullHostname) {
  65.     int offset = fullHostname.indexOf('.');
  66.     if (offset != -1) {
  67.       return fullHostname.substring(0, offset);
  68.     }
  69.     return fullHostname;
  70.   }
  71.   private static DecimalFormat oneDecimal = new DecimalFormat("0.0");
  72.   
  73.   /**
  74.    * Given an integer, return a string that is in an approximate, but human 
  75.    * readable format. 
  76.    * It uses the bases 'k', 'm', and 'g' for 1024, 1024**2, and 1024**3.
  77.    * @param number the number to format
  78.    * @return a human readable form of the integer
  79.    */
  80.   public static String humanReadableInt(long number) {
  81.     long absNumber = Math.abs(number);
  82.     double result = number;
  83.     String suffix = "";
  84.     if (absNumber < 1024) {
  85.       // nothing
  86.     } else if (absNumber < 1024 * 1024) {
  87.       result = number / 1024.0;
  88.       suffix = "k";
  89.     } else if (absNumber < 1024 * 1024 * 1024) {
  90.       result = number / (1024.0 * 1024);
  91.       suffix = "m";
  92.     } else {
  93.       result = number / (1024.0 * 1024 * 1024);
  94.       suffix = "g";
  95.     }
  96.     return oneDecimal.format(result) + suffix;
  97.   }
  98.   
  99.   /**
  100.    * Format a percentage for presentation to the user.
  101.    * @param done the percentage to format (0.0 to 1.0)
  102.    * @param digits the number of digits past the decimal point
  103.    * @return a string representation of the percentage
  104.    */
  105.   public static String formatPercent(double done, int digits) {
  106.     DecimalFormat percentFormat = new DecimalFormat("0.00%");
  107.     double scale = Math.pow(10.0, digits+2);
  108.     double rounded = Math.floor(done * scale);
  109.     percentFormat.setDecimalSeparatorAlwaysShown(false);
  110.     percentFormat.setMinimumFractionDigits(digits);
  111.     percentFormat.setMaximumFractionDigits(digits);
  112.     return percentFormat.format(rounded / scale);
  113.   }
  114.   
  115.   /**
  116.    * Given an array of strings, return a comma-separated list of its elements.
  117.    * @param strs Array of strings
  118.    * @return Empty string if strs.length is 0, comma separated list of strings
  119.    * otherwise
  120.    */
  121.   
  122.   public static String arrayToString(String[] strs) {
  123.     if (strs.length == 0) { return ""; }
  124.     StringBuffer sbuf = new StringBuffer();
  125.     sbuf.append(strs[0]);
  126.     for (int idx = 1; idx < strs.length; idx++) {
  127.       sbuf.append(",");
  128.       sbuf.append(strs[idx]);
  129.     }
  130.     return sbuf.toString();
  131.   }
  132.   /**
  133.    * Given an array of bytes it will convert the bytes to a hex string
  134.    * representation of the bytes
  135.    * @param bytes
  136.    * @param start start index, inclusively
  137.    * @param end end index, exclusively
  138.    * @return hex string representation of the byte array
  139.    */
  140.   public static String byteToHexString(byte[] bytes, int start, int end) {
  141.     if (bytes == null) {
  142.       throw new IllegalArgumentException("bytes == null");
  143.     }
  144.     StringBuilder s = new StringBuilder(); 
  145.     for(int i = start; i < end; i++) {
  146.       s.append(String.format("%02x", bytes[i]));
  147.     }
  148.     return s.toString();
  149.   }
  150.   /** Same as byteToHexString(bytes, 0, bytes.length). */
  151.   public static String byteToHexString(byte bytes[]) {
  152.     return byteToHexString(bytes, 0, bytes.length);
  153.   }
  154.   /**
  155.    * Given a hexstring this will return the byte array corresponding to the
  156.    * string
  157.    * @param hex the hex String array
  158.    * @return a byte array that is a hex string representation of the given
  159.    *         string. The size of the byte array is therefore hex.length/2
  160.    */
  161.   public static byte[] hexStringToByte(String hex) {
  162.     byte[] bts = new byte[hex.length() / 2];
  163.     for (int i = 0; i < bts.length; i++) {
  164.       bts[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
  165.     }
  166.     return bts;
  167.   }
  168.   /**
  169.    * 
  170.    * @param uris
  171.    */
  172.   public static String uriToString(URI[] uris){
  173.     if (uris == null) {
  174.       return null;
  175.     }
  176.     StringBuffer ret = new StringBuffer(uris[0].toString());
  177.     for(int i = 1; i < uris.length;i++){
  178.       ret.append(",");
  179.       ret.append(uris[i].toString());
  180.     }
  181.     return ret.toString();
  182.   }
  183.   
  184.   /**
  185.    * 
  186.    * @param str
  187.    */
  188.   public static URI[] stringToURI(String[] str){
  189.     if (str == null) 
  190.       return null;
  191.     URI[] uris = new URI[str.length];
  192.     for (int i = 0; i < str.length;i++){
  193.       try{
  194.         uris[i] = new URI(str[i]);
  195.       }catch(URISyntaxException ur){
  196.         System.out.println("Exception in specified URI's " + StringUtils.stringifyException(ur));
  197.         //making sure its asssigned to null in case of an error
  198.         uris[i] = null;
  199.       }
  200.     }
  201.     return uris;
  202.   }
  203.   
  204.   /**
  205.    * 
  206.    * @param str
  207.    */
  208.   public static Path[] stringToPath(String[] str){
  209.     if (str == null) {
  210.       return null;
  211.     }
  212.     Path[] p = new Path[str.length];
  213.     for (int i = 0; i < str.length;i++){
  214.       p[i] = new Path(str[i]);
  215.     }
  216.     return p;
  217.   }
  218.   /**
  219.    * 
  220.    * Given a finish and start time in long milliseconds, returns a 
  221.    * String in the format Xhrs, Ymins, Z sec, for the time difference between two times. 
  222.    * If finish time comes before start time then negative valeus of X, Y and Z wil return. 
  223.    * 
  224.    * @param finishTime finish time
  225.    * @param startTime start time
  226.    */
  227.   public static String formatTimeDiff(long finishTime, long startTime){
  228.     long timeDiff = finishTime - startTime; 
  229.     return formatTime(timeDiff); 
  230.   }
  231.   
  232.   /**
  233.    * 
  234.    * Given the time in long milliseconds, returns a 
  235.    * String in the format Xhrs, Ymins, Z sec. 
  236.    * 
  237.    * @param timeDiff The time difference to format
  238.    */
  239.   public static String formatTime(long timeDiff){
  240.     StringBuffer buf = new StringBuffer();
  241.     long hours = timeDiff / (60*60*1000);
  242.     long rem = (timeDiff % (60*60*1000));
  243.     long minutes =  rem / (60*1000);
  244.     rem = rem % (60*1000);
  245.     long seconds = rem / 1000;
  246.     
  247.     if (hours != 0){
  248.       buf.append(hours);
  249.       buf.append("hrs, ");
  250.     }
  251.     if (minutes != 0){
  252.       buf.append(minutes);
  253.       buf.append("mins, ");
  254.     }
  255.     // return "0sec if no difference
  256.     buf.append(seconds);
  257.     buf.append("sec");
  258.     return buf.toString(); 
  259.   }
  260.   /**
  261.    * Formats time in ms and appends difference (finishTime - startTime) 
  262.    * as returned by formatTimeDiff().
  263.    * If finish time is 0, empty string is returned, if start time is 0 
  264.    * then difference is not appended to return value. 
  265.    * @param dateFormat date format to use
  266.    * @param finishTime fnish time
  267.    * @param startTime start time
  268.    * @return formatted value. 
  269.    */
  270.   public static String getFormattedTimeWithDiff(DateFormat dateFormat, 
  271.                                                 long finishTime, long startTime){
  272.     StringBuffer buf = new StringBuffer();
  273.     if (0 != finishTime) {
  274.       buf.append(dateFormat.format(new Date(finishTime)));
  275.       if (0 != startTime){
  276.         buf.append(" (" + formatTimeDiff(finishTime , startTime) + ")");
  277.       }
  278.     }
  279.     return buf.toString();
  280.   }
  281.   
  282.   /**
  283.    * Returns an arraylist of strings.
  284.    * @param str the comma seperated string values
  285.    * @return the arraylist of the comma seperated string values
  286.    */
  287.   public static String[] getStrings(String str){
  288.     Collection<String> values = getStringCollection(str);
  289.     if(values.size() == 0) {
  290.       return null;
  291.     }
  292.     return values.toArray(new String[values.size()]);
  293.   }
  294.   /**
  295.    * Returns a collection of strings.
  296.    * @param str comma seperated string values
  297.    * @return an <code>ArrayList</code> of string values
  298.    */
  299.   public static Collection<String> getStringCollection(String str){
  300.     List<String> values = new ArrayList<String>();
  301.     if (str == null)
  302.       return values;
  303.     StringTokenizer tokenizer = new StringTokenizer (str,",");
  304.     values = new ArrayList<String>();
  305.     while (tokenizer.hasMoreTokens()) {
  306.       values.add(tokenizer.nextToken());
  307.     }
  308.     return values;
  309.   }
  310.   final public static char COMMA = ',';
  311.   final public static String COMMA_STR = ",";
  312.   final public static char ESCAPE_CHAR = '\';
  313.   
  314.   /**
  315.    * Split a string using the default separator
  316.    * @param str a string that may have escaped separator
  317.    * @return an array of strings
  318.    */
  319.   public static String[] split(String str) {
  320.     return split(str, ESCAPE_CHAR, COMMA);
  321.   }
  322.   
  323.   /**
  324.    * Split a string using the given separator
  325.    * @param str a string that may have escaped separator
  326.    * @param escapeChar a char that be used to escape the separator
  327.    * @param separator a separator char
  328.    * @return an array of strings
  329.    */
  330.   public static String[] split(
  331.       String str, char escapeChar, char separator) {
  332.     if (str==null) {
  333.       return null;
  334.     }
  335.     ArrayList<String> strList = new ArrayList<String>();
  336.     StringBuilder split = new StringBuilder();
  337.     int index = 0;
  338.     while ((index = findNext(str, separator, escapeChar, index, split)) >= 0) {
  339.       ++index; // move over the separator for next search
  340.       strList.add(split.toString());
  341.       split.setLength(0); // reset the buffer 
  342.     }
  343.     strList.add(split.toString());
  344.     // remove trailing empty split(s)
  345.     int last = strList.size(); // last split
  346.     while (--last>=0 && "".equals(strList.get(last))) {
  347.       strList.remove(last);
  348.     }
  349.     return strList.toArray(new String[strList.size()]);
  350.   }
  351.   
  352.   /**
  353.    * Finds the first occurrence of the separator character ignoring the escaped
  354.    * separators starting from the index. Note the substring between the index
  355.    * and the position of the separator is passed.
  356.    * @param str the source string
  357.    * @param separator the character to find
  358.    * @param escapeChar character used to escape
  359.    * @param start from where to search
  360.    * @param split used to pass back the extracted string
  361.    */
  362.   public static int findNext(String str, char separator, char escapeChar, 
  363.                              int start, StringBuilder split) {
  364.     int numPreEscapes = 0;
  365.     for (int i = start; i < str.length(); i++) {
  366.       char curChar = str.charAt(i);
  367.       if (numPreEscapes == 0 && curChar == separator) { // separator 
  368.         return i;
  369.       } else {
  370.         split.append(curChar);
  371.         numPreEscapes = (curChar == escapeChar)
  372.                         ? (++numPreEscapes) % 2
  373.                         : 0;
  374.       }
  375.     }
  376.     return -1;
  377.   }
  378.   
  379.   /**
  380.    * Escape commas in the string using the default escape char
  381.    * @param str a string
  382.    * @return an escaped string
  383.    */
  384.   public static String escapeString(String str) {
  385.     return escapeString(str, ESCAPE_CHAR, COMMA);
  386.   }
  387.   
  388.   /**
  389.    * Escape <code>charToEscape</code> in the string 
  390.    * with the escape char <code>escapeChar</code>
  391.    * 
  392.    * @param str string
  393.    * @param escapeChar escape char
  394.    * @param charToEscape the char to be escaped
  395.    * @return an escaped string
  396.    */
  397.   public static String escapeString(
  398.       String str, char escapeChar, char charToEscape) {
  399.     return escapeString(str, escapeChar, new char[] {charToEscape});
  400.   }
  401.   
  402.   // check if the character array has the character 
  403.   private static boolean hasChar(char[] chars, char character) {
  404.     for (char target : chars) {
  405.       if (character == target) {
  406.         return true;
  407.       }
  408.     }
  409.     return false;
  410.   }
  411.   
  412.   /**
  413.    * @param charsToEscape array of characters to be escaped
  414.    */
  415.   public static String escapeString(String str, char escapeChar, 
  416.                                     char[] charsToEscape) {
  417.     if (str == null) {
  418.       return null;
  419.     }
  420.     StringBuilder result = new StringBuilder();
  421.     for (int i=0; i<str.length(); i++) {
  422.       char curChar = str.charAt(i);
  423.       if (curChar == escapeChar || hasChar(charsToEscape, curChar)) {
  424.         // special char
  425.         result.append(escapeChar);
  426.       }
  427.       result.append(curChar);
  428.     }
  429.     return result.toString();
  430.   }
  431.   
  432.   /**
  433.    * Unescape commas in the string using the default escape char
  434.    * @param str a string
  435.    * @return an unescaped string
  436.    */
  437.   public static String unEscapeString(String str) {
  438.     return unEscapeString(str, ESCAPE_CHAR, COMMA);
  439.   }
  440.   
  441.   /**
  442.    * Unescape <code>charToEscape</code> in the string 
  443.    * with the escape char <code>escapeChar</code>
  444.    * 
  445.    * @param str string
  446.    * @param escapeChar escape char
  447.    * @param charToEscape the escaped char
  448.    * @return an unescaped string
  449.    */
  450.   public static String unEscapeString(
  451.       String str, char escapeChar, char charToEscape) {
  452.     return unEscapeString(str, escapeChar, new char[] {charToEscape});
  453.   }
  454.   
  455.   /**
  456.    * @param charsToEscape array of characters to unescape
  457.    */
  458.   public static String unEscapeString(String str, char escapeChar, 
  459.                                       char[] charsToEscape) {
  460.     if (str == null) {
  461.       return null;
  462.     }
  463.     StringBuilder result = new StringBuilder(str.length());
  464.     boolean hasPreEscape = false;
  465.     for (int i=0; i<str.length(); i++) {
  466.       char curChar = str.charAt(i);
  467.       if (hasPreEscape) {
  468.         if (curChar != escapeChar && !hasChar(charsToEscape, curChar)) {
  469.           // no special char
  470.           throw new IllegalArgumentException("Illegal escaped string " + str + 
  471.               " unescaped " + escapeChar + " at " + (i-1));
  472.         } 
  473.         // otherwise discard the escape char
  474.         result.append(curChar);
  475.         hasPreEscape = false;
  476.       } else {
  477.         if (hasChar(charsToEscape, curChar)) {
  478.           throw new IllegalArgumentException("Illegal escaped string " + str + 
  479.               " unescaped " + curChar + " at " + i);
  480.         } else if (curChar == escapeChar) {
  481.           hasPreEscape = true;
  482.         } else {
  483.           result.append(curChar);
  484.         }
  485.       }
  486.     }
  487.     if (hasPreEscape ) {
  488.       throw new IllegalArgumentException("Illegal escaped string " + str + 
  489.           ", not expecting " + escapeChar + " in the end." );
  490.     }
  491.     return result.toString();
  492.   }
  493.   
  494.   /**
  495.    * Return hostname without throwing exception.
  496.    * @return hostname
  497.    */
  498.   public static String getHostname() {
  499.     try {return "" + InetAddress.getLocalHost();}
  500.     catch(UnknownHostException uhe) {return "" + uhe;}
  501.   }
  502.   /**
  503.    * Return a message for logging.
  504.    * @param prefix prefix keyword for the message
  505.    * @param msg content of the message
  506.    * @return a message for logging
  507.    */
  508.   private static String toStartupShutdownString(String prefix, String [] msg) {
  509.     StringBuffer b = new StringBuffer(prefix);
  510.     b.append("n/************************************************************");
  511.     for(String s : msg)
  512.       b.append("n" + prefix + s);
  513.     b.append("n************************************************************/");
  514.     return b.toString();
  515.   }
  516.   /**
  517.    * Print a log message for starting up and shutting down
  518.    * @param clazz the class of the server
  519.    * @param args arguments
  520.    * @param LOG the target log object
  521.    */
  522.   public static void startupShutdownMessage(Class<?> clazz, String[] args,
  523.                                      final org.apache.commons.logging.Log LOG) {
  524.     final String hostname = getHostname();
  525.     final String classname = clazz.getSimpleName();
  526.     LOG.info(
  527.         toStartupShutdownString("STARTUP_MSG: ", new String[] {
  528.             "Starting " + classname,
  529.             "  host = " + hostname,
  530.             "  args = " + Arrays.asList(args),
  531.             "  version = " + VersionInfo.getVersion(),
  532.             "  build = " + VersionInfo.getUrl() + " -r "
  533.                          + VersionInfo.getRevision()  
  534.                          + "; compiled by '" + VersionInfo.getUser()
  535.                          + "' on " + VersionInfo.getDate()}
  536.         )
  537.       );
  538.     Runtime.getRuntime().addShutdownHook(new Thread() {
  539.       public void run() {
  540.         LOG.info(toStartupShutdownString("SHUTDOWN_MSG: ", new String[]{
  541.           "Shutting down " + classname + " at " + hostname}));
  542.       }
  543.     });
  544.   }
  545.   /**
  546.    * The traditional binary prefixes, kilo, mega, ..., exa,
  547.    * which can be represented by a 64-bit integer.
  548.    * TraditionalBinaryPrefix symbol are case insensitive. 
  549.    */
  550.   public static enum TraditionalBinaryPrefix {
  551.     KILO(1024),
  552.     MEGA(KILO.value << 10),
  553.     GIGA(MEGA.value << 10),
  554.     TERA(GIGA.value << 10),
  555.     PETA(TERA.value << 10),
  556.     EXA(PETA.value << 10);
  557.     public final long value;
  558.     public final char symbol;
  559.     TraditionalBinaryPrefix(long value) {
  560.       this.value = value;
  561.       this.symbol = toString().charAt(0);
  562.     }
  563.     /**
  564.      * @return The TraditionalBinaryPrefix object corresponding to the symbol.
  565.      */
  566.     public static TraditionalBinaryPrefix valueOf(char symbol) {
  567.       symbol = Character.toUpperCase(symbol);
  568.       for(TraditionalBinaryPrefix prefix : TraditionalBinaryPrefix.values()) {
  569.         if (symbol == prefix.symbol) {
  570.           return prefix;
  571.         }
  572.       }
  573.       throw new IllegalArgumentException("Unknown symbol '" + symbol + "'");
  574.     }
  575.     /**
  576.      * Convert a string to long.
  577.      * The input string is first be trimmed
  578.      * and then it is parsed with traditional binary prefix.
  579.      *
  580.      * For example,
  581.      * "-1230k" will be converted to -1230 * 1024 = -1259520;
  582.      * "891g" will be converted to 891 * 1024^3 = 956703965184;
  583.      *
  584.      * @param s input string
  585.      * @return a long value represented by the input string.
  586.      */
  587.     public static long string2long(String s) {
  588.       s = s.trim();
  589.       final int lastpos = s.length() - 1;
  590.       final char lastchar = s.charAt(lastpos);
  591.       if (Character.isDigit(lastchar))
  592.         return Long.parseLong(s);
  593.       else {
  594.         long prefix = TraditionalBinaryPrefix.valueOf(lastchar).value;
  595.         long num = Long.parseLong(s.substring(0, lastpos));
  596.         if (num > (Long.MAX_VALUE/prefix) || num < (Long.MIN_VALUE/prefix)) {
  597.           throw new IllegalArgumentException(s + " does not fit in a Long");
  598.         }
  599.         return num * prefix;
  600.       }
  601.     }
  602.   }
  603.   
  604.     /**
  605.      * Escapes HTML Special characters present in the string.
  606.      * @param string
  607.      * @return HTML Escaped String representation
  608.      */
  609.     public static String escapeHTML(String string) {
  610.       if(string == null) {
  611.         return null;
  612.       }
  613.       StringBuffer sb = new StringBuffer();
  614.       boolean lastCharacterWasSpace = false;
  615.       char[] chars = string.toCharArray();
  616.       for(char c : chars) {
  617.         if(c == ' ') {
  618.           if(lastCharacterWasSpace){
  619.             lastCharacterWasSpace = false;
  620.             sb.append("&nbsp;");
  621.           }else {
  622.             lastCharacterWasSpace=true;
  623.             sb.append(" ");
  624.           }
  625.         }else {
  626.           lastCharacterWasSpace = false;
  627.           switch(c) {
  628.           case '<': sb.append("&lt;"); break;
  629.           case '>': sb.append("&gt;"); break;
  630.           case '&': sb.append("&amp;"); break;
  631.           case '"': sb.append("&quot;"); break;
  632.           default : sb.append(c);break;
  633.           }
  634.         }
  635.       }
  636.       
  637.       return sb.toString();
  638.     }
  639.   /**
  640.    * Return an abbreviated English-language desc of the byte length
  641.    */
  642.   public static String byteDesc(long len) {
  643.     double val = 0.0;
  644.     String ending = "";
  645.     if (len < 1024 * 1024) {
  646.       val = (1.0 * len) / 1024;
  647.       ending = " KB";
  648.     } else if (len < 1024 * 1024 * 1024) {
  649.       val = (1.0 * len) / (1024 * 1024);
  650.       ending = " MB";
  651.     } else if (len < 1024L * 1024 * 1024 * 1024) {
  652.       val = (1.0 * len) / (1024 * 1024 * 1024);
  653.       ending = " GB";
  654.     } else if (len < 1024L * 1024 * 1024 * 1024 * 1024) {
  655.       val = (1.0 * len) / (1024L * 1024 * 1024 * 1024);
  656.       ending = " TB";
  657.     } else {
  658.       val = (1.0 * len) / (1024L * 1024 * 1024 * 1024 * 1024);
  659.       ending = " PB";
  660.     }
  661.     return limitDecimalTo2(val) + ending;
  662.   }
  663.   public static synchronized String limitDecimalTo2(double d) {
  664.     return decimalFormat.format(d);
  665.   }
  666. }