java-FTPClient-ftp 上传文件、创建目录(支持中文目录、文件名)

java-ftp 上传、删除文件(支持中文目录、文件名)


一、问题
描述:Java中FTPClient上传中文目录、中文文件名乱码问题解决方法
原因:FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码。
解决方案:name=new String(name.getBytes("GBK"),"iso-8859-1"); 使用这个转码


二、ftp 文件上传帮助类
package me.grass.net;


import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.function.Function;


import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;


import me.grass.coder.Debug;
import me.grass.extend.PathExtend;
import me.grass.extend.StringExtend;


/**
 *
 * @author xxj
 */
public class FtpHelper implements Closeable {
	private FTPClient ftp = null;
	boolean _isLogin = false;
	public static FtpHelper getInstance() {
		return new FtpHelper();
	}
	
	/**
	 * 
	 * ftp 匿名登录
	 * @param ip ftp服务地址
	 * @param port 端口号
	 * @param uname 用户名
	 * @param pass 密码
	 */
	public boolean login(String ip,int port){
		//如果没有设置ftp用户可将username设为anonymous,密码为任意字符串
		return login(ip, port,"anonymous","");
	} 
	/**
	 * 
	 * ftp登录
	 * @param ip ftp服务地址
	 * @param port 端口号
	 * @param uname 用户名
	 * @param pass 密码
	 * @param workingDir ftp 根目目录
	 */
	public boolean login(String ip,int port, String uname, String pass) {
		ftp = new FTPClient();
//		boolean flag=false;
		try {
			// 连接
			ftp.connect(ip,port);
			_isLogin = ftp.login(uname, pass);
			Debug.printFormat("ftp:{0}",_isLogin?"登录成功":"登录失败");
			// 检测连接是否成功
			int reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				System.err.println("FTP服务器拒绝连接 ");
				return false;
			}
			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
	}
	/**
	 * 上传后触发
	 */
	public Function<FtpFileInfo, Boolean> onUploadFileAfter;
	
	/**
	 * 
	 * ftp上传文件 
	 * @param localFileName 待上传文件
	 * @param ftpDirName ftp 目录名
	 * @param ftpFileName ftp目标文件
	 * @return true||false
	 */
	public boolean uploadFile(String localFileName
			,String ftpDirName
			, String ftpFileName) {
		return uploadFile(localFileName, ftpDirName, ftpFileName,false);
	}
	/**
	 * 
	 * ftp上传文件 
	 * @param localFileName 待上传文件
	 * @param ftpDirName ftp 目录名
	 * @param ftpFileName ftp目标文件
	 * @param deleteLocalFile 是否删除本地文件
	 * @return true||false
	 */
	public boolean uploadFile(String localFileName
			, String ftpDirName
			, String ftpFileName
			, boolean deleteLocalFile) {


		Debug.printFormat("准备上传 [{0}] 到 ftp://{1}/{2}"
				,localFileName
				,ftpDirName
				,ftpFileName);
//		if(StringExtend.isNullOrEmpty(ftpDirName))
//			ftpDirName="/";
		if(StringExtend.isNullOrEmpty(ftpFileName))
			throw new RuntimeException("上传文件必须填写文件名!");
		
		File srcFile = new File(localFileName);
		if(!srcFile.exists())
			throw new RuntimeException("文件不存在:"+localFileName);
		
		try (FileInputStream fis = new FileInputStream(srcFile)) {
			//上传文件
			boolean flag = uploadFile(fis,ftpDirName,ftpFileName);
			//上传前事件
			if(onUploadFileAfter!=null){
				onUploadFileAfter.apply(new FtpFileInfo(localFileName,ftpDirName,ftpFileName));
			}
			//删除文件
			if(deleteLocalFile){
				srcFile.delete();
				Debug.printFormat("ftp删除源文件:{0}",srcFile);
			}
			fis.close();
			return flag;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
		}
	}


	/**
	 * 
	 * ftp上传文件 (使用inputstream)
	 * @param localFileName 待上传文件
	 * @param ftpDirName ftp 目录名
	 * @param ftpFileName ftp目标文件
	 * @return true||false
	 */
	public boolean uploadFile(FileInputStream uploadInputStream
			,String ftpDirName
			, String ftpFileName) {
		Debug.printFormat("准备上传 [流] 到 ftp://{0}/{1}"				
				,ftpDirName
				,ftpFileName);
//		if(StringExtend.isNullOrEmpty(ftpDirName))
//			ftpDirName="/";
		if(StringExtend.isNullOrEmpty(ftpFileName))
			throw new RuntimeException("上传文件必须填写文件名!");
		
		try {
			// 设置上传目录(没有则创建)
			if(!createDir(ftpDirName)){
				throw new RuntimeException("切入FTP目录失败:"+ftpDirName);
			}
			ftp.setBufferSize(1024);
			//解决上传中文 txt 文件乱码
			ftp.setControlEncoding("GBK");
			FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT); 
			conf.setServerLanguageCode("zh");  


			// 设置文件类型(二进制)
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			// 上传
			String fileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
			if(ftp.storeFile(fileName, uploadInputStream)){
				uploadInputStream.close();
				Debug.printFormat("文件上传成功:{0}/{1}"
						,ftpDirName
						,ftpFileName);
				return true;
			}
			
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
		}
	}
	/**
	 * 下载文件
	 * @param ftpDirName ftp目录名
	 * @param ftpFileName ftp文件名
	 * @param localFileFullName 本地文件名
	 * @return
	 *  @author xxj
	 */
	public boolean downloadFile(String ftpDirName,
			String ftpFileName, String localFileFullName) {
		try {
			if("".equals(ftpDirName))
				ftpDirName="/";
			String dir = new String(ftpDirName.getBytes("GBK"),"iso-8859-1");
			if(!ftp.changeWorkingDirectory(dir)){
				System.out.println("切换目录失败:"+ftpDirName);
				return false;
			}
			FTPFile[] fs = ftp.listFiles();
			String fileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
			for (FTPFile ff : fs) {
				if (ff.getName().equals(fileName)) {
					FileOutputStream is = new FileOutputStream(new File(localFileFullName));
					ftp.retrieveFile(ff.getName(), is);
					is.close();
					System.out.println("下载ftp文件已下载:"+localFileFullName);
					return true;
				}
			}
			System.out.println("下载ftp文件失败:"+ftpFileName+";目录:"+ftpDirName);
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} 
	}


	/**
	 * 
	 * 删除ftp上的文件
	 * 
	 * @param ftpFileName
	 * @return true || false
	 */
	public boolean removeFile(String ftpFileName) {
		boolean flag = false;
		Debug.printFormat("待删除文件:{0}"
				,ftpFileName);
		try {
			ftpFileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
			flag = ftp.deleteFile(ftpFileName);
			Debug.printFormat("删除文件:[{0}]"
					,flag?"成功":"失败");
			return flag;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 删除空目录
	 * @param dir
	 * @return
	 */
	public boolean removeDir(String dir){
		if(StringExtend.startWith(dir, "/"))
			dir="/"+dir;
		try {
			String d = new String(dir.toString().getBytes("GBK"),"iso-8859-1");			
			return ftp.removeDirectory(d);			
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	/**
	 * 创建目录(有则切换目录,没有则创建目录)
	 * @param dir
	 * @return
	 */
	public boolean createDir(String dir){
		if(StringExtend.isNullOrEmpty(dir))
			return true;
		String d;
		try {
			//目录编码,解决中文路径问题
			d = new String(dir.toString().getBytes("GBK"),"iso-8859-1");
			//尝试切入目录
			if(ftp.changeWorkingDirectory(d))
				return true;
			dir = StringExtend.trimStart(dir, "/");
			dir = StringExtend.trimEnd(dir, "/");
			String[] arr =  dir.split("/");
			StringBuffer sbfDir=new StringBuffer();
			//循环生成子目录
			for(String s : arr){
				sbfDir.append("/");
				sbfDir.append(s);
				//目录编码,解决中文路径问题
				d = new String(sbfDir.toString().getBytes("GBK"),"iso-8859-1");
				//尝试切入目录
				if(ftp.changeWorkingDirectory(d))
					continue;
				if(!ftp.makeDirectory(d)){
					System.out.println("[失败]ftp创建目录:"+sbfDir.toString());
					return false;
				}
				System.out.println("[成功]创建ftp目录:"+sbfDir.toString());
			}
			//将目录切换至指定路径
			return ftp.changeWorkingDirectory(d);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	


	/**
	 *
	 * 销毁ftp连接
	 *
	 */
	private void closeFtpConnection() {
		_isLogin = false;
		if (ftp != null) {
			if (ftp.isConnected()) {
				try {
					ftp.logout();
					ftp.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}


	/**
	 *
	 * 销毁ftp连接
	 *
	 */
	@Override
	public void close() {
		this.closeFtpConnection();
	}
	
	public static class FtpFileInfo{
		public FtpFileInfo(String srcFile,String ftpDirName,String ftpFileName){
			this.ftpDirName=ftpDirName;
			this.ftpFileName=ftpFileName;
			this.srcFile=srcFile;
		}
		String srcFile;
		String ftpDirName;
		String ftpFileName;
		String ftpFileFullName;
		
		public String getSrcFile() {
			return srcFile;
		}
		public void setSrcFile(String srcFile) {
			this.srcFile = srcFile;
		}
		public String getFtpDirName() {
			return ftpDirName;
		}
		public void setFtpDirName(String ftpDirName) {
			this.ftpDirName = ftpDirName;
		}
		public String getFtpFileName() {
			return ftpFileName;
		}
		public void setFtpFileName(String ftpFileName) {
			this.ftpFileName = ftpFileName;
		}
		/**
		 * 获取ftp上传文件的完整路径名
		 * @return
		 *  @author xxj
		 */
		public String getFtpFileFullName() {
			return PathExtend.Combine("/",ftpDirName,ftpFileName);
		}
		
	}
}




三、ftp 上传单元测试

package me.grass.net;




import static org.junit.Assert.*;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;


import javax.print.attribute.standard.Finishings;


import org.apache.taglibs.standard.lang.jstl.test.beans.PublicInterface2;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


import me.grass.extend.DateExtend;
import me.grass.extend.StringExtend;
import me.grass.net.FtpHelper;


/** 
*
* @author xxj 
*/
public class FtpHelperTest {
	FtpHelper ftp=null;
	@Before
	public void InitBinder(){
		ftp = FtpHelper.getInstance();
		ftp.login("localhost", 21);//匿名登录
	}
	@After
	public void finish(){
		ftp.close();
	}
	@Test
	public void testUplodFileStream() {
		
		try {			
			String localFile="D:/Temp/resource/img.jpg";
			String ftpDir="temp";
			String ftpFile=StringExtend.format("img-{0}.jpg"
					, DateExtend.getDate("yyyyMMddHHmmss"));


			
			FileInputStream fi = new FileInputStream(localFile);
			
			boolean success = ftp.uploadFile(fi,ftpDir, ftpFile);
			assertTrue(success);


			localFile="D:/Temp/resource/文本.txt";
			ftpDir="temp";
			ftpFile=StringExtend.format("文本-{0}.txt"
					, DateExtend.getDate("yyyyMMddHHmmss"));	


			fi = new FileInputStream(localFile);
			success = ftp.uploadFile(fi,ftpDir, ftpFile);	
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}			
	}
	@Test
	public void testOnAfter() {
		String localFile="D:/Temp/resource/img.jpg";
		String ftpDir="/aa/bb";
		String ftpFile=StringExtend.format("img-{0}.jpg"
				, DateExtend.getDate("yyyyMMddHHmmss"));	


		// 上传后事件
		ftp.onUploadFileAfter = (ftpFileInfo) -> {
			try(FileInputStream fstream = new FileInputStream(new File(ftpFileInfo.getSrcFile()))) {
				ByteArrayOutputStream bstream = new ByteArrayOutputStream();
				byte[] buffer = new byte[1000];
				int n = 0;
				while ((n = fstream.read(buffer)) != -1) {
					bstream.write(buffer, 0, n);
				}
				System.out.println("onafter:stream lenth = "+bstream.size());
				bstream.close();
				fstream.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


			return true;
		};
		//上传
		boolean success = ftp.uploadFile(localFile,ftpDir, ftpFile);
		assertTrue(success);
		
	}
	@Test
	public void testUplodaFile() {
		String localFile="D:/Temp/resource/img.jpg";
		String ftpDir="/aa/bb";
		String ftpFile=StringExtend.format("img-{0}.jpg"
				, DateExtend.getDate("yyyyMMddHHmmss"));		
		boolean success = ftp.uploadFile(localFile,ftpDir, ftpFile);
		assertTrue(success);
		
		localFile="D:/Temp/resource/text.txt";
		ftpDir="/aa/bb/c1";
		ftpFile=StringExtend.format("text-{0}.txt"
				, DateExtend.getDate("yyyyMMddHHmmss"));		
		success = ftp.uploadFile(localFile,ftpDir, ftpFile);		
		assertTrue(success);


		localFile="D:/Temp/resource/文本.txt";
		ftpDir="/aa/bb/c2";
		ftpFile=StringExtend.format("文本-{0}.txt"
				, DateExtend.getDate("yyyyMMddHHmmss"));		
		success = ftp.uploadFile(localFile,ftpDir, ftpFile);		
		assertTrue(success);
		
	}
	@Test
	public void testRemove(){
		boolean success = false;
		String file ="/temp/文本-20170509175507.txt";
		success = ftp.removeFile(file);
		
		assertTrue(success);
	}
	@Test
	public void crateDir(){
		String dir="aa/bb";
		boolean success = ftp.createDir(dir);
		System.out.print(success?"成功":"失败");
		System.out.println(dir);
		
		 dir="aa/bb/c1";
		 success = ftp.createDir(dir);
			System.out.print(success?"成功":"失败");
		 System.out.println(dir);


		 dir="aa/bb/c2";
		 success = ftp.createDir(dir);
			System.out.print(success?"成功":"失败");
		 System.out.println(dir);
		
		assertTrue(success);
	}
	@Test
	public void removeDir(){
		String dir="aa/bb";
		boolean success = ftp.removeDir(dir);
		System.out.print(success?"成功":"失败");
		System.out.println(dir);
		
		 dir="aa/bb/c1";
		 success = ftp.removeDir(dir);
			System.out.print(success?"成功":"失败");
		 System.out.println(dir);


		 dir="aa/bb/c2";
		 success = ftp.removeDir(dir);
			System.out.print(success?"成功":"失败");
		 System.out.println(dir);
		
		assertTrue(success);
	}
	@Test
	public void downloadFile(){
		String ftpDirName="/aa/bb";
		String ftpFileName="img-20170606110355.jpg";
		String localFileFullName=StringExtend.format("D:/Temp/pdf/down/down-{0}.jpg"
				,DateExtend.getDate("yyyyMMddHHmmss"));
		boolean result = ftp.downloadFile(ftpDirName, ftpFileName, localFileFullName);
		assertTrue(result);


		ftpDirName="/";
		ftpFileName="文本.txt";
		localFileFullName=StringExtend.format("D:/Temp/pdf/down/down-{0}.txt"
				,DateExtend.getDate("yyyyMMddHHmmss"));
		result = ftp.downloadFile(ftpDirName, ftpFileName, localFileFullName);
		assertTrue(result);
	}
}

三个工具类:StringExtend,PathExtend,Debug工具类

package me.grass.extend;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.regex.Pattern;

import org.apache.taglibs.standard.lang.jstl.test.beans.PublicInterface2;
import org.springframework.beans.NullValueInNestedPathException;

public class StringExtend {
	/**
	 * 获取换行符,区分不同系统
	 * /r Mac;/n Unix/Linux;/r/n Windows
	 * @return
	 *  @author admin
	 */
	public static String getEnterMark(){
		return System.getProperty("line.separator");
	}
	/**
	 * 清除首位空格
	 * @return
	 */
	public static String trim(String msg)
	{
		if(msg==null)
			return null;
		return msg.trim();
	}
	/**
	 * 字符串内容格式化输出,内部使用{0}\{1}\{2}...为参数占位符</br>
	 * 参数格式:ArgumentIndex[,FormatType[,FormatStyle]] </br>
	 * FormatType 取值:number,date,time,choice </br>
	 * FormatType 样式:如:#.## </br>
	 * 注:'{' 可输出左花括号(单写左花括号会报错,而单写右花括号将正常输出)</br>
	 * @param msg 格式化模板
	 * @param args 不固定参数
	 * @return
	 */
	public static String format(String msg, Object... args)
	{
		return java.text.MessageFormat.format(msg, args);
	}
	
	/**
	 * 转换字符串到
	 * @param num
	 * @return
	 *  @author xxj
	 */
	public static Integer getInt(String num){		
		if(num==null || num.trim().isEmpty())
			return 0;
		if(!num.matches("^(\\d|-)\\d{0,9}$"))
			return 0;
		try {
			return Integer.parseInt(num);	
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return 0;
		}
	}
	public static String getString(Object obj){
		return obj == null ? null : obj.toString();
	}
	public static String getString(Integer num){
		return getString(num,"");
	}
	public static String getString(Integer num,String def){
		if(num == null)
			return def;
		return num.toString();
	}
	public static String getString(Date date){
		return DateExtend.getString(date);
	}
	/**
	 * 字符串是否为空
	 * @param str
	 * @return
	 */
	public static boolean isNullOrEmpty(String str){
		return str==null || str.trim().isEmpty();
	}
	/**
	 * 比较两个字符串是否相等,忽略大小写
	 * @param str1
	 * @param str2
	 * @return
	 *  @author xxj
	 */
	public static boolean equalsIgnoreCase(String str1 ,String str2){
		String tmp = str1==null?"":str1;	
		return tmp.equalsIgnoreCase(str2);
	}
	/**
	 * md5 加密
	 * @param str
	 * @return
	 *  @author xxj 2017年4月24日
	 */
	public static String getMd5(String... str){
		if(str==null || str.length==0)
			return "";
		StringBuffer sbr = new StringBuffer();
		for(String item : str){
			sbr.append(item);
		}
        // 生成一个MD5加密计算摘要
        MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
	        // 计算md5函数
	        md.update(sbr.toString().getBytes());
	        // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
	        // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
	        return new BigInteger(1, md.digest()).toString(16);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "";
		}
	}
	/**
	 * 删除起始字符
	 * @param s
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static String trimStart(String str,String trim){
		if(str==null)
			return null;
		return str.replaceAll("^("+trim+")+", "");
	}
	/**
	 * 删除末尾字符
	 * @param s
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static String trimEnd(String str,String trim){
		if(str==null)
			return null;
		return str.replaceAll("("+trim+")+$", "");
	}
	/**
	 * 以字符开头
	 * @param s
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static boolean startWith(String str,String s){
		return str.startsWith(s);
	}
	/**
	 * 以字符末尾
	 * @param s
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static boolean endWith(String str,String s){
		return str.endsWith(s);
	}
	/**
	 * 获取 boolean 值(1=true;True=true;)
	 * @param str
	 * @return
	 *  @author xxj 2017年5月2日
	 */
	public static boolean getBoolean(String str){
		if(isNullOrEmpty(str))
			return false;
		
		Pattern pattern = Pattern.compile("(1)|(true)", Pattern.CASE_INSENSITIVE);
		if(pattern.matcher(str).matches())
			return true;
		
		return false;
	}
	
	/**
	 * 隐藏银行账号后6位
	 * @param str
	 * @return
	 */
	public static String bankAccount(String str) {
		if(isNullOrEmpty(str)){
			return null;
		}
		
		if (str.length()>6) {
			return str.substring(0, str.length()-6)+"xxxxxx";
		}
		return str;
	}
}


package me.grass.extend;

import java.io.File;

/** 
* 路径扩展
* @author xxj 
* @version 创建时间:2017年4月27日 下午2:45:39
*/
public class PathExtend {
	/**
	 * 合并路径
	 * @param args
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static String Combine(String ...args){
		if(args==null || args.length==0)
			return "";
		StringBuffer sbf = new StringBuffer();
		for(String s:args){
//			//纯协议开头不处理,如:http://,d:/,linux首个/不处理
//			if(s.matches("^[a-zA-z]+://$")){
//				sbf.append(s);
//				continue;
//			}
			//首位地址只删除尾部正反斜杠
			if(sbf.length()==0){
				sbf.append(s.replaceAll("/{1,}$|\\{1,}$", ""));
				continue;
			}
				
			if(sbf.length()>0)
				sbf.append("/");
			//去除首尾正反斜杠
			sbf.append(s
					.replaceAll("^/{1,}|^\\{1,}", "")
					.replaceAll("/{1,}$|\\{1,}$", ""));
		}
		
		return sbf.toString();
	}
	/**
	 * 获取应用程序 classpath 路径 
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static String getClassPath(){
		return PathExtend.class.getResource("/").getPath();
	} 
	/**
	 * 将相对路径转为绝对路径(相对与 calsspath 的路径)
	 * @param relativePath
	 * @return
	 *  @author xxj 2017年4月27日
	 */
	public static String getAbsolutePath(String relativePath){
		return Combine(getClassPath(),relativePath);
	}
	/**
	 * 获取路径中的目录部分
	 * @param path
	 * @return
	 *  @author xxj 2017年6月15日
	 */
	public static String getDirectory(String path){
		return path.replaceAll("(/)([^/])+\\.([^/])+$", "");
	} 
	/**
	 * 获取路径中的文件名部分
	 * @param path
	 * @return
	 *  @author xxj 2017年6月15日
	 */
	public static String getFileName(String path){
		return path.replaceAll("^.+(/)", "");
	} 
	/**
	 * 创建目录(存在则不创建)
	 * @return
	 *  @author xxj 2017年6月15日
	 */
	public static boolean createDirectory(String dirName){
		File file=new File(dirName);
		if(file.exists())
			return true;
		return file.mkdirs();
	}
}


package me.grass.coder;


import me.grass.extend.StringExtend;

/** 
*
* @author xxj 
* @version 创建时间:2017年4月26日 上午9:52:27
*/
public class Debug {
	/**
	 * 格式化输出,打印信息到控制台
	 * @param format
	 * @param args
	 *  @author xxj 2017年4月26日
	 */
	public static void printFormat(String format,Object ...args){
		if(args==null){
			System.out.println(format);
		}
		System.out.println(java.text.MessageFormat.format(format, args));
	}
	/**
	 * 格式化输出,打印信息到控制台
	 * @param format
	 * @param args
	 *  @author xxj 2017年4月26日
	 */
	public static void print(Object ...msg){
		if(msg==null){
			return;
		}
		for(Object x:msg){
			System.out.print(x);
//			System.out.print(' ');
		}
		System.out.println();
	}
	/**
	 * 格式化输出,打印信息到控制台
	 * @param format
	 * @param args
	 *  @author xxj 2017年4月26日
	 */
	public static void println(Object ...msg){
		if(msg==null){
			return;
		}
		for(Object x:msg)
			System.out.println(x);
	}
	/**
	 * 打印当前线程的调用堆栈
	 * 
	 *  @author xxj 2017年4月26日
	 */
	public static void printTrack(){
		StackTraceElement[] st = Thread.currentThread().getStackTrace();
		if(st==null){
			System.out.println("无堆栈...");
			return;
		}
		StringBuffer sbf =new StringBuffer();
		sbf.append(StringExtend.format("调用堆栈[{0}]:",StringExtend.getString(new java.util.Date())));		
		for(StackTraceElement e:st){
			sbf.append(StringExtend.format(" {0}.{1}() {2} <- {3}"
					,e.getClassName()
					,e.getMethodName()
					,e.getLineNumber()
					,StringExtend.getEnterMark()));
		}
		System.out.println(sbf.toString());
	}
}




  • 12
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值