public static String limitControls(String procdefId,String activityId,String url)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
String value="";
try {
st = con.createStatement();
String iSql = "";
///
if(activityId!=null&&!"null".equals(activityId)){
iSql = "select distinct a.controltype,a.controlname,a.viewtype,c.formname from activitycontrollimits a,activitycontrol c,ASSIGNMENTEVENTAUDITS b where a.limitno=c.limitno and c.actdefid=b.activitydefinitionid and b.ACTIVITYID='"+activityId+"' and url='"+url+"'" ;
}
///进去发起页面 activityid is null
else
iSql = "select distinct a.controltype,a.controlname,a.viewtype,c.formname from activitycontrollimits a,activitycontrol c where a.limitno=c.limitno and procdefid='"+procdefId+"' and actdefid='null' and url='"+url+"'" ;
System.out.println(iSql);
ResultSet rs = st.executeQuery(iSql);
while (rs.next()) {
int cType = rs.getInt(3);
switch(cType){
case 0:value = value+"document.all['"+rs.getString(2)+"'].disabled=true;";
break;
case 1:
if(rs.getInt(1)==3)
value = value="self.location='commons/noallow.jsp'";
else
value = value+"document.all['"+rs.getString(2)+"'].style.display='none';";
break;
//case 2:value= value+"document.all['"+rs.getString(2)+"'].style.display='block';";
// break;
default:
value = value+"document.all['"+rs.getString(2)+"'].disabled=false;";
break;
}
}
// if(value.trim().length()==0)
// value="self.location='/commons/noallow.jsp'";
} catch (Exception e) {
e.printStackTrace();
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"生成校验串失败!",
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
value= "<script language='javascript'>"+value;
value = value+"</script>";
return value;
}
package com.augur.wf.shark.common.util;
import javax.naming.InitialContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.dbcp.BasicDataSource;
import com.augur.wf.shark.common.Exception.*;
import java.util.List;
import java.util.ArrayList;
import com.augur.wf.shark.common.Db.DbConnectionManager;
import com.augur.wf.shark.SharkProviderImpl;
import com.augurit.pysz.login.po.Usertable;
import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
import java.io.RandomAccessFile;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.Connection;
/**
*
* @author Administrator
*
*/
public class CodeFormula {
public CodeFormula() {
try {
jbInit();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static final String poolName = "idb";
public static final int apply_code = 1;
public static final int get_code = 2;
public static final int putback_code =3 ;
public static final int refuse_code =4;
public static final int abort_code =5;
private static List getBeforeCode(String procId,String activityId,int codeType)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
List codes = new ArrayList();
try {
st = con.createStatement();
String iSql = "select code from activitycode a,ASSIGNMENTEVENTAUDITS b where a.FIRETYPE=0 and a.procdefid=b.PROCESSDEFINITIONID and a.actdefid=ACTIVITYDEFINITIONID and b.PROCESSID='"+procId+"' and b.ACTIVITYID='"+activityId+"' and codetype='"+codeType+"'";
System.out.println(iSql);
ResultSet rs = st.executeQuery(iSql);
if (rs.next()) {
codes.add(rs.getString(1));
}
} catch (Exception e) {
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"获取节点代码失败!"+activityId,
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
return codes;
}
private static List getAfterCode(String procId,String activityId,int codeType)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
List codes = new ArrayList();
try {
st = con.createStatement();
String iSql = "select distinct code from activitycode a,ASSIGNMENTEVENTAUDITS b where a.FIRETYPE=1 and a.procdefid=b.PROCESSDEFINITIONID and a.actdefid=ACTIVITYDEFINITIONID and b.PROCESSID='"+procId+"' and b.ACTIVITYID='"+activityId+"' and codetype='"+codeType+"'";
System.out.println(iSql);
ResultSet rs = st.executeQuery(iSql);
if (rs.next()) {
codes.add(rs.getString(1));
}
} catch (Exception e) {
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"获取节点代码失败!"+activityId,
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
return codes;
}
private static void updValue(String formId,String tableName,String fieldName,String value)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
try {
st = con.createStatement();
String iSql = "update "+tableName+" set "+fieldName+"='"+value+"' where formid='"+formId+"'";
System.out.println(iSql);
st.execute(iSql);
} catch (Exception e) {
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"更新代码失败!",
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
}
private static String getValue(String formId,String tableName,String fieldName)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
String value = null;
try {
st = con.createStatement();
String iSql = "select "+fieldName+" from "+tableName+" where applyid='"+formId+"'";
ResultSet rs = st.executeQuery(iSql);
if (rs.next()) {
value = rs.getString(1);
}
} catch (Exception e) {
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"获取值失败!",
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
return value;
}
//private static void get
private static void parseCode(String procId,String activityId,String code,HttpServletRequest request) throws WfException{
try{
String funName = code.substring(0, 6);
///设置流程变量代码解释 setVal opinion view.opinion or setVal opinion db.table1.opinion
if ("setVal".equals(funName)) {
String[] strs = code.split(" ");
String valName = strs[1].trim(); //代码前部分-流程变量名
String valValue = strs[2].trim(); //代码后部分
String[] valueDefs = valValue.split("\\."); //解释代码后部分
String dataDefType =valueDefs[0]; //数据来源类型 view为页面,data 为数据库
String defFieldName = null;
String value = null;
//从页面获取数据才设置变量 格式: setVal
if ("view".equals(dataDefType)) {
defFieldName = valueDefs[1];
value = request.getParameter(
defFieldName);
}
//从数据库中获取数据才设置变量����ȡ
else if ("data".equals(dataDefType)) {
String tableName = valueDefs[1];
defFieldName = valueDefs[2];
String formId = ExProcessManager.getExprocessRelaDataId(
procId);
value = getValue(formId,tableName,defFieldName);
}
else if("cons".equals(dataDefType)){
value = valueDefs[1];
}
Usertable user =(Usertable) request.getSession().getAttribute("login_user");
SharkProviderImpl.variableSet(SharkProviderImpl.connect(user.getUserid(),user.getPasswd()), activityId, valName,
value);
}
if("updFld".equals(funName)){ //updFld tablea.jiaofei data.tableb.jiaofei
String[] strs = code.split(" ");
String valName = strs[1].trim(); //代码前部分-流程变量名
String valValue = strs[2].trim(); //代码后部分
String[] fldDef = valName.split("\\.");
String[] valueDefs = valValue.split("\\."); //解释代码后部分
String dataDefType =valueDefs[0]; //数据来源类型 view为页面,data 为数据库
String defFieldName = null;
String value = null;
String formId = ExProcessManager.getExprocessRelaDataId(
procId);
//从页面获取数据才设置变量 格式: setVal
if ("view".equals(dataDefType)) {
defFieldName = valueDefs[1];
value = request.getParameter(
defFieldName);
}
//从数据库中获取数据才设置变量����ȡ
else if ("data".equals(dataDefType)) {
String tableName = valueDefs[1];
defFieldName = valueDefs[2];
value = getValue(formId,tableName,defFieldName);
}
else if("cons".equals(dataDefType)){
value = valueDefs[1];
}
updValue(formId,fldDef[0],fldDef[1],value);
}
}
catch(Exception e){
e.printStackTrace();
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"解释代码失败!"+code,
ErrorInfo.getTrace(e, e.getStackTrace()));
}
}
public static void parseBeforeCode(String procId,String activityId,int codeType,HttpServletRequest request)throws WfException{
try{
List codes = getBeforeCode(procId,activityId,codeType);
for(int i=0;i<codes.size();i++){
parseCode(procId,activityId,codes.get(i).toString(),request);
}
}
catch(WfException e){
throw e;
}
catch(Exception e1){
throw new WfException();
}
}
public static void parseAfterCode(String procId,String activityId,int codeType,HttpServletRequest request)throws WfException{
try{
List codes = getAfterCode(procId,activityId,codeType);
for(int i=0;i<codes.size();i++){
parseCode(procId,activityId,codes.get(i).toString(),request);
}
}
catch(WfException e){
throw e;
}
catch(Exception e1){
throw new WfException();
}
}
public static String limitControls(String procdefId,String activityId,String url)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
String value="";
try {
st = con.createStatement();
String iSql = "";
///
if(activityId!=null&&!"null".equals(activityId)){
iSql = "select distinct a.controltype,a.controlname,a.viewtype,c.formname from activitycontrollimits a,activitycontrol c,ASSIGNMENTEVENTAUDITS b where a.limitno=c.limitno and c.actdefid=b.activitydefinitionid and b.ACTIVITYID='"+activityId+"' and url='"+url+"'" ;
}
///进去发起页面 activityid is null
else
iSql = "select distinct a.controltype,a.controlname,a.viewtype,c.formname from activitycontrollimits a,activitycontrol c where a.limitno=c.limitno and procdefid='"+procdefId+"' and actdefid='null' and url='"+url+"'" ;
System.out.println(iSql);
ResultSet rs = st.executeQuery(iSql);
while (rs.next()) {
int cType = rs.getInt(3);
switch(cType){
case 0:value = value+"document.all['"+rs.getString(2)+"'].disabled=true;";
break;
case 1:
if(rs.getInt(1)==3)
value = value="self.location='commons/noallow.jsp'";
else
value = value+"document.all['"+rs.getString(2)+"'].style.display='none';";
break;
//case 2:value= value+"document.all['"+rs.getString(2)+"'].style.display='block';";
// break;
default:
value = value+"document.all['"+rs.getString(2)+"'].disabled=false;";
break;
}
}
// if(value.trim().length()==0)
// value="self.location='/commons/noallow.jsp'";
} catch (Exception e) {
e.printStackTrace();
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"生成校验串失败!",
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
value= "<script language='javascript'>"+value;
value = value+"</script>";
return value;
}
public static String parseClientControl(String activityId) throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
String value= "";
try {
st = con.createStatement();
String iSql = "select distinct a.procdefid,a.actdefid,a.controltype,a.name,a.value,a.label,a.todefid from activitycodecontrol a,ASSIGNMENTEVENTAUDITS b where a.actdefid=b.activitydefinitionid and b.ACTIVITYID='"+activityId+"'" ;
System.out.println(iSql);
ResultSet rs = st.executeQuery(iSql);
while (rs.next()) {
int cType = rs.getInt(3);
switch(cType){
case 0:value = value+"<input type='checkbox' name='"+rs.getString(4)+"' value='"+rs.getString(5)+"'>"+rs.getString(6);
break;
case 1:value = value+rs.getString(6)+"<input type='text' name='"+rs.getString(4)+"' value='"+rs.getString(5)+"'>";
break;
case 2:value= value+"<input type='radio' onclick=getUsers('"+rs.getString(7)+"') touserid='"+rs.getString(7)+"' name='"+rs.getString(4)+"' value='"+rs.getString(5)+"'>"+rs.getString(6);
break;
default:
value = value+"<input type='checkbox' onclick=getUsers('"+rs.getString(7)+"') touserid='"+rs.getString(7)+"' name='"+rs.getString(4)+"' value='"+rs.getString(5)+"'>"+rs.getString(5);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"解释客户端变量失败!",
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
return value;
}
public static void main(String[] args){
try{
// CodeFormula.parseCode(null,null,"setVal laid data.tablea.filed", null);
try{
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("org.gjt.mm.mysql.Driver");
ds.setUrl("jdbc:mysql://localhost/sample");
ds.setUsername("root");
ds.setPassword("dddd");
ds.setInitialSize(2);
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial","org.apache.naming.java.javaURLContextFactory");
InitialContext ctx=new InitialContext();
ctx.bind("tomcatDS",ds);
ds = (BasicDataSource)ctx.lookup("tomcatDS");
Connection con = ds.getConnection();
Statement stmt = con.createStatement();
String strSql = "select * from user";
ResultSet rs = stmt.executeQuery(strSql);
while(rs.next()){
System.out.println("id="+rs.getString(1));
}
rs.close();
stmt.close();
con.close();
}
catch(Exception ex){
ex.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
}
private void jbInit() throws Exception {
}
}
解析数据库表上的Code字段的值样式:
updFld exprocess.BUSSSTATE cons.12001
setVal outopin cont.test
formId查询的条件字段,tableName是表名,fieldName要查询的字段
private static String getValue(String formId,String tableName,String fieldName)throws WfException{
Connection con = DbConnectionManager.getInstance().getConnection(
poolName);
Statement st = null;
String value = null;
try {
st = con.createStatement();
String iSql = "select "+fieldName+" from "+tableName+" where applyid='"+formId+"'";
ResultSet rs = st.executeQuery(iSql);
if (rs.next()) {
value = rs.getString(1);
}
} catch (Exception e) {
throw new WfException(ErrorInfo.EXT_PROC_MANAGER_ERROR,"获取值失败!",
ErrorInfo.getTrace(e, e.getStackTrace()));
} finally {
DbConnectionManager.getInstance().freeConnection(poolName, con);
}
return value;
}
<html>
<head>
<script language="javascript" type="text/javascript">
</script><script language="javascript" type="text/javascript">
function MakeExcel(){
var i,j;
try {
var xls = new ActiveXObject ( "Excel.Application" );
}
catch(e) {
alert( "要打印该表,您必须安装Excel电子表格软件,同时浏览器须使用“ActiveX 控件”,您的浏览器须允许执行控件。 请点击【帮助】了解浏览器设置方法!");
return "";
}
xls.visible =true; //设置excel为可见
var xlBook = xls.Workbooks.Add;
var xlsheet = xlBook.Worksheets(1);
<!--合并-->
xlsheet.Range(xlsheet.Cells(1,1),xlsheet.Cells(1,7)).mergecells=true;
xlsheet.Range(xlsheet.Cells(1,1),xlsheet.Cells(1,7)).value="发卡记录";
// xlsheet.Range(xlsheet.Cells(1,1),xlsheet.Cells(1,6)).Interior.ColorIndex=5;//设置底色为蓝色
// xlsheet.Range(xlsheet.Cells(1,1),xlsheet.Cells(1,6)).Font.ColorIndex=4;//设置字体色
// xlsheet.Rows(1). Interior .ColorIndex = 5 ;//设置底色为蓝色 设置背景色 Rows(1).Font.ColorIndex=4
<!--设置行高-->
xlsheet.Rows(1).RowHeight = 25;
<!--设置字体 ws.Range(ws.Cells(i0+1,j0), ws.Cells(i0+1,j1)).Font.Size = 13 -->
xlsheet.Rows(1).Font.Size=14;
<!--设置字体 设置选定区的字体 xlsheet.Range(xlsheet.Cells(i0,j0), ws.Cells(i0,j0)).Font.Name = "黑体" -->
xlsheet.Rows(1).Font.Name="黑体";
<!--设置列宽 xlsheet.Columns(2)=14;-->
xlsheet.Columns("A:D").ColumnWidth =18;
<!--设置显示字符而不是数字-->
xlsheet.Columns(2).NumberFormatLocal="@";
xlsheet.Columns(7).NumberFormatLocal="@";
//设置单元格内容自动换行 range.WrapText = true ;
//设置单元格内容水平对齐方式 range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;//设置单元格内容竖直堆砌方式
//range.VerticalAlignment=Excel.XlVAlign.xlVAlignCenter
//range.WrapText = true; xlsheet.Rows(3).WrapText=true 自动换行
//设置标题栏
xlsheet.Cells(2,1).Value="卡号";
xlsheet.Cells(2,2).Value="密码";
xlsheet.Cells(2,3).Value="计费方式";
xlsheet.Cells(2,4).Value="有效天数";
xlsheet.Cells(2,5).Value="金额";
xlsheet.Cells(2,6).Value="所属服务项目";
xlsheet.Cells(2,7).Value="发卡时间";
var oTable=document.all['fors:data'];
var rowNum=oTable.rows.length;
for(i=2;i<=rowNum;i++){
for (j=1;j<=7;j++){
//html table类容写到excel
xlsheet.Cells(i+1,j).Value=oTable.rows(i-1).cells(j-1).innerHTML;
}
}
<!-- xlsheet.Range(xls.Cells(i+4,2),xls.Cells(rowNum,4)).Merge; -->
// xlsheet.Range(xlsheet.Cells(i, 4), xlsheet.Cells(i-1, 6)).BorderAround , 4
// for(mn=1,mn<=6;mn++) . xlsheet.Range(xlsheet.Cells(1, mn), xlsheet.Cells(i1, j)).Columns.AutoFit;
xlsheet.Columns.AutoFit;
xlsheet.Range( xlsheet.Cells(1,1),xlsheet.Cells(rowNum+1,7)).HorizontalAlignment =-4108;//居中
xlsheet.Range( xlsheet.Cells(1,1),xlsheet.Cells(1,7)).VerticalAlignment =-4108;
xlsheet.Range( xlsheet.Cells(2,1),xlsheet.Cells(rowNum+1,7)).Font.Size=10;
xlsheet.Range( xlsheet.Cells(2,1),xlsheet.Cells(rowNum+1,7)).Borders(3).Weight = 2; //设置左边距
xlsheet.Range( xlsheet.Cells(2,1),xlsheet.Cells(rowNum+1,7)).Borders(4).Weight = 2;//设置右边距
xlsheet.Range( xlsheet.Cells(2,1),xlsheet.Cells(rowNum+1,7)).Borders(1).Weight = 2;//设置顶边距
xlsheet.Range( xlsheet.Cells(2,1),xlsheet.Cells(rowNum+1,7)).Borders(2).Weight = 2;//设置底边距
xls.UserControl = true; //很重要,不能省略,不然会出问题 意思是excel交由用户控制
xls=null;
xlBook=null;
xlsheet=null;
}
</script> <link href="css/styles3.css" rel="stylesheet" type="text/css"/>
<title>ziyuanweihu</title>
</head>
<body>
<form id="fors" method="post" action="/WebModule/admins/card/showcard.faces" enctype="application/x-www-form-urlencoded">
<table id="fors:top" border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td class="left"><img src="images/jiao1.gif" alt="" /></td>
<td class="topMiddle"></td>
<td class="right"><img src="images/jiao2.gif" alt="" /></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td class="middleLeft"></td>
<td class="btstyle"><table id="fors:sort" border="0" cellpadding="0" cellspacing="0" style="valign:center" width="100%">
<tbody>
<tr>
<td class="btstyle"><input type="button" name="fors:_id7" value="生成excel文件" onclick="MakeExcel()" /><input type="submit" name="fors:_id8" value="返回" /></td>
</tr>
</tbody>
</table>
<table id="fors:data" border="1" cellpadding="0" cellspacing="1" width="100%">
<thead>
<tr>
<th scope="col"><span id="fors:data:headerText1">卡号</span></th>
<th scope="col"><span id="fors:data:headerText2">密码</span></th>
<th scope="col"><span id="fors:data:headerText3">计费方式</span></th>
<th scope="col"><span id="fors:data:headerText4">有效天数</span></th>
<th scope="col">金额</th>
<th scope="col"><span id="fors:data:headerText6">所属服务项目</span></th>
<th scope="col"><span id="fors:data:headerText7">发卡时间</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>h000010010</td>
<td>543860</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010011</td>
<td>683352</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010012</td>
<td>433215</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010013</td>
<td>393899</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010014</td>
<td>031736</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010015</td>
<td>188600</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010016</td>
<td>363407</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010017</td>
<td>175315</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010018</td>
<td>354437</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
<tr>
<td>h000010019</td>
<td>234750</td>
<td>计点</td>
<td></td>
<td>2.0</td>
<td>测试项目</td>
<td>2006-06-23 10:14:40.843</td>
</tr>
</tbody>
</table>
</td>
<td class="middleRight"></td>
</tr>
</tbody>
</table>
<table id="fors:bottom" border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td class="left">
<img src="images/jiao3.gif" alt=""/>
</td>
<td class="bottomMiddle"> </td>
<td class="right">
<img src="images/jiao4.gif" alt=""/>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="fors" value="fors" /></form>
</body>
</html>
欢迎加入QQ群:30406099
/**
* Replace all occurence of forReplace with replaceWith in input string.
*
* @param input
* represents input string
* @param forReplace
* represents substring for replace
* @param replaceWith
* represents replaced string value
* @return new string with replaced values
*/
private static String replaceAll(String input, String forReplace,
String replaceWith) {
if (input == null)
return null;
StringBuffer result = new StringBuffer();
boolean hasMore = true;
while (hasMore) {
int start = input.indexOf(forReplace);
int end = start + forReplace.length();
if (start != -1) {
result.append(input.substring(0, start) + replaceWith);
input = input.substring(end);
} else {
hasMore = false;
result.append(input);
}
}
if (result.toString().equals(""))
return input; // nothing is changed
else
return result.toString();
}
Java中文&编码问题小结
笨笨
Java字符编码转换过程说明
常见问题
JVM
JVM启动后,JVM会设置一些系统属性以表明JVM的缺省区域。
user.language,user.region,file.encoding等。 可以使用System.getProperties()详细查看所有的系统属性。
如在英文操作系统(如UNIX)下,可以使用如下属性定义强制指定JVM为中文环境 -Dclient.encoding.override=GBK -Dfile.encoding=GBK -Duser.language=zh -Duser.region=CN
.java-->.class编译
说明:一般javac根据当前os区域设置,自动决定源文件的编码.可以通过-encoding强制指定.
错误可能:
1 gbk编码源文件在英文环境下编译,javac不能正确转换.曾见于java/jsp在英文unix下. 检测方法:写\u4e00格式的汉字,绕开javac编码,再在jvm中,将汉字作为int打印,看值是否相等;或直接以UTF-8编码打开.class文件,看看常量字符串是否正确保存汉字。
文件读写
外部数据如文件经过读写和转换两个步骤,转为jvm所使用字符。InputStream/OutputStream用于读写原始外部数据,Reader/Writer执行读写和转换两个步骤。
1 文件读写转换由java.io.Reader/Writer执行;输入输出流 InputStream/OutputStream 处理汉字不合适,应该首选使用Reader/Writer,如 FileReader/FileWriter。
2 FileReader/FileWriter使用JVM当前编码读写文件.如果有其它编码格式,使用InputStreamReader/OutputStreamWriter
3 PrintStream有点特殊,它自动使用jvm缺省编码进行转换。
读取.properties文件
.propeties文件由Properties类以iso8859-1编码读取,因此不能在其中直接写汉字,需要使用JDK 的native2ascii工具转换汉字为\uXXXX格式。命令行:native2ascii –encoding GBK inputfile outputfile
读取XML文件
1 XML文件读写同于文件读写,但应注意确保XML头中声明如<? xml version=”1.0” encoding=”gb2312” ?>与文件编码保持一致。
2 javax.xml.SAXParser类接受InputStream作为输入参数,对于Reader,需要用org.xml.sax.InputSource包装一下,再给SAXParser。
3 对于UTF-8编码 XML,注意防止编辑器自动加上\uFFFE BOM头, xml parser会报告content is not allowed in prolog。
字节数组
1 使用 new String(byteArray,encoding) 和 String.getBytes(encoding) 在字节数组和字符串之间进行转换
也可以用ByteArrayInputStream/ByteArrayOutputStream转为流后再用InputStreamReader/OutputStreamWriter转换。
错误编码的字符串(iso8859-1转码gbk)
如果我们得到的字符串是由错误的转码方式产生的,例如:对于gbk中文,由iso8859-1方式转换,此时如果用调试器看到的字符串一般是 的样子,长度一般为文本的字节长度,而非汉字个数。
可以采用如下方式转为正确的中文:
text = new String( text.getBytes(“iso8859-1”),”gbk”);
JDBC
转换过程由JDBC Driver执行,取决于各JDBC数据库实现。对此经验尚积累不够。
1 对于ORACLE数据库,需要数据库创建时指定编码方式为gbk,否则会出现汉字转码错误
2 对于 SQL Server 2000 ,最好以nvarchar/nchar类型存放文本,即不存在中文/编码转换问题。
3 连接 Mysql,将 connectionString 设置成 encoding 为 gb2312:
String connectionString = "jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=gb2312";
WEB/Servlet/JSP
1 对于JSP,确定头部加上 <%@ page contentType="text/html;charset=gb2312"%>这样的标签。
2 对于Servlet,确定 设置setContentType (“text/html; charset=gb2312”),以上两条用于使得输出汉字没有问题。
3 为输出HTML head中加一个 <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> ,让浏览器正确确定HTML编码。
4 为Web应用加一个Filter,确保每个Request明确调用setCharacterEncoding方法,让输入汉字能够正确解析。
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
/**
* Example filter that sets the character encoding to be used in parsing the
* incoming request
*/
public class SetCharacterEncodingFilter
implements Filter {
public SetCharacterEncodingFilter()
{}
protected boolean debug = false;
protected String encoding = null;
protected FilterConfig filterConfig = null;
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// if (request.getCharacterEncoding() == null)
// {
// String encoding = getEncoding();
// if (encoding != null)
// request.setCharacterEncoding(encoding);
//
// }
request.setCharacterEncoding(encoding);
if ( debug ){
System.out.println( ((HttpServletRequest)request).getRequestURI()+"setted to "+encoding );
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
this.debug = "true".equalsIgnoreCase( filterConfig.getInitParameter("debug") );
}
protected String getEncoding() {
return (this.encoding);
}
}
web.xml中加入:
<filter>
<filter-name>LocalEncodingFilter</filter-name>
<display-name>LocalEncodingFilter</display-name>
<filter-class>com.ccb.ectipmanager.request.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>gb2312</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LocalEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5 用于Weblogic(vedor-specific):
其一:在web.xml里加上如下脚本:
<context-param>
<param-name>weblogic.httpd.inputCharset./*</param-name>
<param-value>GBK</param-value>
</context-param>
其二(可选)在weblogic.xml里加上如下脚本:
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>GBK</java-charset-name>
</input-charset>
</charset-params>
SWING/AWT/SWT
对于SWING/AWT,Java会有些缺省字体如Dialog/San Serif,这些字体到系统真实字体的映射在$JRE_HOME/lib/font.properties.XXX文件中指定。排除字体显示问题时,首先需要确定JVM的区域为zh_CN,这样font.properties.zh_CN文件才会发生作用。对于 font.properties.zh_CN , 需要检查是否映射缺省字体到中文字体如宋体。
在Swing中,Java自行解释TTF字体,渲染显示;对于AWT,SWT显示部分交由操作系统。首先需要确定系统装有中文字体。
1 汉字显示为”□”,一般为显示字体没有使用中文字体,因为Java对于当前字体显示不了的字符,不会像Windows一样再采用缺省字体显示。
2 部分不常见汉字不能显示,一般为显示字库中汉字不全,可以换另外的中文字体试试。
3 对于AWT/SWT,首先确定JVM运行环境的区域设置为中文,因为此处设计JVM与操作系统api调用的转换问题,再检查其它问题。
JNI
JNI中jstring以UTF-8编码给我们,需要我们自行转为本地编码。对于Windows,可以采用WideCharToMultiByte/MultiByteToWideChar函数进行转换,对于Unix,可以采用iconv库。
这里从SUN jdk 1.4 源代码中找到一段使用jvm String 对象的getBytes的转换方式,相对简单和跨平台,不需要第三方库,但速度稍慢。函数原型如下:
/* Convert between Java strings and i18n C strings */
JNIEXPORT jstring
NewStringPlatform(JNIEnv *env, const char *str);
JNIEXPORT const char *
GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str);
JNIEXPORT const char * JNICALL
JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
JNIEXPORT void JNICALL
JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str);
附件jni_util.h,jni_util.c
TUXEDO/JOLT
JOLT对于传递的字符串需要用如下进行转码
new String(ls_tt.getBytes("GBK"),"iso8859-1")
对于返回的字符串
new String(error_message.getBytes("iso8859-1"),"GBK");
jolt 的系统属性 bea.jolt.encoding不应该设置,如果设置,JSH会报告说错误的协议.
JDK1.4/1.5新增部分
字符集相关类(Charset/CharsetEncoder/CharsetDecoder)
jdk1.4开始,对字符集的支持在java.nio.charset包中实现。
常用功能:
1 列出jvm所支持字符集:Charset.availableCharsets()
2 能否对看某个Unicode字符编码,CharsetEncoder.canEncode()
Unicode Surrogate/CJK EXT B
Unicode 范围一般所用为\U0000-\UFFFF范围,jvm使用1个char就可以表示,对于CJK EXT B区汉字,范围大于\U20000,则需要采用2个char方能表示,此即Unicode Surrogate。这2个char的值范围 落在Character.SURROGATE 区域内,用Character.getType()来判断。
jdk 1.4尚不能在Swing中正确处理surrogate区的Unicode字符,jdk1.5可以。对于CJK EXT B区汉字,目前可以使用的字库为”宋体-方正超大字符集”,随Office安装。
常见问题
在JVM下,用System.out.println不能正确打印中文,显示为???
System.out.println是PrintStream,它采用jvm缺省字符集进行转码工作,如果jvm的缺省字符集为iso8859-1,则中文显示会有问题。此问题常见于Unix下,jvm的区域没有明确指定的情况。
在英文UNIX环境下,用System.out.println能够正确打印汉字,但是内部处理错误
可能是汉字在输入转换时,就没有正确转码:
即gbk文本à(iso8859-1转码)àjvm char(iso8859-1编码汉字)à (iso8859-1转码)à输出。
gbk汉字经过两次错误转码,原封不动的被传递到输出,但是在jvm中,并未以正确的unicode编码表示,而是以一个汉字字节一个char的方式表示,从而导致此类错误。
GB2312-80,GBK,GB18030-2000 汉字字符集
GB2312-80 是在国内计算机汉字信息技术发展初始阶段制定的,其中包含了大部分常用的一、二级汉字,和 9 区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是 0xa1-0xfe;汉字从 0xb0a1 开始,结束于 0xf7fe;
GBK 是 GB2312-80 的扩展,是向上兼容的。它包含了 20902 个汉字,其编码范围是 0x8140-0xfefe,剔除高位 0x80 的字位。其所有字符都可以一对一映射到 Unicode 2.0,也就是说 JAVA 实际上提供了 GBK 字符集的支持。这是现阶段 Windows 和其它一些中文操作系统的缺省字符集,但并不是所有的国际化软件都支持该字符集,感觉是他们并不完全知道 GBK 是怎么回事。值得注意的是它不是国家标准,而只是规范。随着 GB18030-2000国标的发布,它将在不久的将来完成它的历史使命。
GB18030-2000(GBK2K) 在 GBK 的基础上进一步扩展了汉字,增加了藏、蒙等少数民族的字形。GBK2K 从根本上解决了字位不够,字形不足的问题。它有几个特点,
它并没有确定所有的字形,只是规定了编码范围,留待以后扩充。
编码是变长的,其二字节部分与 GBK 兼容;四字节部分是扩充的字形、字位,其编码范围是首字节 0x81-0xfe、二字节0x30-0x39、三字节 0x81-0xfe、四字节0x30-0x39。
UTF-8/UTF-16/UTF-32
UTF,即Unicode Transformer Format,是Unicode代码点(code point)的实际表示方式,按其基本长度所用位数分为UTF-8/16/32。它也可以认为是一种特殊的外部数据编码,但能够与Unicode代码点做一一对应。
UTF-8是变长编码,每个Unicode代码点按照不同范围,可以有1-3字节的不同长度。
UTF-16长度相对固定,只要不处理大于\U200000范围的字符,每个Unicode代码点使用16位即2字节表示,超出部分使用两个UTF-16即4字节表示。按照高低位字节顺序,又分为UTF-16BE/UTF-16LE。
UTF-32长度始终固定,每个Unicode代码点使用32位即4字节表示。按照高低位字节顺序,又分为UTF-32BE/UTF-32LE。
UTF编码有个优点,即尽管编码字节数不等,但是不像gb2312/gbk编码一样,需要从文本开始寻找,才能正确对汉字进行定位。在UTF编码下,根据相对固定的算法,从当前位置就能够知道当前字节是否是一个代码点的开始还是结束,从而相对简单的进行字符定位。不过定位问题最简单的还是UTF-32,它根本不需要进行字符定位,但是相对的大小也增加不少。
关于GCJ JVM
GCJ并未完全依照sun jdk的做法,对于区域和编码问题考虑尚不够周全。GCJ启动时,区域始终设为en_US,编码也缺省为iso8859-1。但是可以用Reader/Writer做正确编码转换。
关于Java文件路径问题
1.如何获得当前文件路径
常用:
字符串类型:System.getProperty("user.dir");
综合:
package com.zcjl.test.base;
import java.io.File;
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(
Thread.currentThread().getContextClassLoader().getResource(""));
System.out.println(Test.class.getClassLoader().getResource(""));
System.out.println(ClassLoader.getSystemResource(""));
System.out.println(Test.class.getResource(""));
System.out.println(Test.class.getResource("/"));
System.out.println(new File("").getAbsolutePath());
System.out.println(System.getProperty("user.dir"));
}
}
2.Web服务中
(1).Weblogic
WebApplication的系统文件根目录是你的weblogic安装所在根目录。
例如:如果你的weblogic安装在c:\bea\weblogic700.....
那么,你的文件根路径就是c:\.
所以,有两种方式能够让你访问你的服务器端的文件:
a.使用绝对路径:
比如将你的参数文件放在c:\yourconfig\yourconf.properties,
直接使用 new FileInputStream("yourconfig/yourconf.properties");
b.使用相对路径:
相对路径的根目录就是你的webapplication的根路径,即WEB-INF的上一级目录,将你的参数文件放在yourwebapp\yourconfig\yourconf.properties,
这样使用:
new FileInputStream("./yourconfig/yourconf.properties");
这两种方式均可,自己选择。
(2).Tomcat
在类中输出System.getProperty("user.dir");显示的是%Tomcat_Home%/bin
(3).Resin
不是你的JSP放的相对路径,是JSP引擎执行这个JSP编译成SERVLET
的路径为根.比如用新建文件法测试File f = new File("a.htm");
这个a.htm在resin的安装目录下
(4).如何读相对路径哪?
在Java文件中getResource或getResourceAsStream均可
例:getClass().getResourceAsStream(filePath);//filePath可以是"/filename",这里的/代表web发布根路径下WEB-INF/classes
(5).获得文件真实路径
string file_real_path=request.getRealPath("mypath/filename");
通常使用request.getRealPath("/");
3.文件操作的类
import java.io.*;
import java.net.*;
import java.util.*;
//import javax.swing.filechooser.*;
//import org.jr.swing.filter.*;
/**
* 此类中封装一些常用的文件操作。
* 所有方法都是静态方法,不需要生成此类的实例,
* 为避免生成此类的实例,构造方法被申明为private类型的。
* @since 0.1
*/
public class FileUtil {
/**
* 私有构造方法,防止类的实例化,因为工具类不需要实例化。
*/
private FileUtil() {
}
/**
* 修改文件的最后访问时间。
* 如果文件不存在则创建该文件。
* <b>目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考
虑中。</b>
* @param file 需要修改最后访问时间的文件。
* @since 0.1
*/
public static void touch(File file) {
long currentTime = System.currentTimeMillis();
if (!file.exists()) {
System.err.println("file not found:" + file.getName());
System.err.println("Create a new file:" + file.getName());
try {
if (file.createNewFile()) {
// System.out.println("Succeeded!");
}
else {
// System.err.println("Create file failed!");
}
}
catch (IOException e) {
// System.err.println("Create file failed!");
e.printStackTrace();
}
}
boolean result = file.setLastModified(currentTime);
if (!result) {
// System.err.println("touch failed: " + file.getName());
}
}
/**
* 修改文件的最后访问时间。
* 如果文件不存在则创建该文件。
* <b>目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考
虑中。</b>
* @param fileName 需要修改最后访问时间的文件的文件名。
* @since 0.1
*/
public static void touch(String fileName) {
File file = new File(fileName);
touch(file);
}
/**
* 修改文件的最后访问时间。
* 如果文件不存在则创建该文件。
* <b>目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考
虑中。</b>
* @param files 需要修改最后访问时间的文件数组。
* @since 0.1
*/
public static void touch(File[] files) {
for (int i = 0; i < files.length; i++) {
touch(files);
}
}
/**
* 修改文件的最后访问时间。
* 如果文件不存在则创建该文件。
* <b>目前这个方法的行为方式还不稳定,主要是方法有些信息输出,这些信息输出是否保留还在考
虑中。</b>
* @param fileNames 需要修改最后访问时间的文件名数组。
* @since 0.1
*/
public static void touch(String[] fileNames) {
File[] files = new File[fileNames.length];
for (int i = 0; i < fileNames.length; i++) {
files = new File(fileNames);
}
touch(files);
}
/**
* 判断指定的文件是否存在。
* @param fileName 要判断的文件的文件名
* @return 存在时返回true,否则返回false。
* @since 0.1
*/
public static boolean isFileExist(String fileName) {
return new File(fileName).isFile();
}
/**
* 创建指定的目录。
* 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。
* <b>注意:可能会在返回false的时候创建部分父目录。</b>
* @param file 要创建的目录
* @return 完全创建成功时返回true,否则返回false。
* @since 0.1
*/
public static boolean makeDirectory(File file) {
File parent = file.getParentFile();
if (parent != null) {
return parent.mkdirs();
}
return false;
}
/**
* 创建指定的目录。
* 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。
* <b>注意:可能会在返回false的时候创建部分父目录。</b>
* @param fileName 要创建的目录的目录名
* @return 完全创建成功时返回true,否则返回false。
* @since 0.1
*/
public static boolean makeDirectory(String fileName) {
File file = new File(fileName);
return makeDirectory(file);
}
/**
* 清空指定目录中的文件。
* 这个方法将尽可能删除所有的文件,但是只要有一个文件没有被删除都会返回false。
* 另外这个方法不会迭代删除,即不会删除子目录及其内容。
* @param directory 要清空的目录
* @return 目录下的所有文件都被成功删除时返回true,否则返回false.
* @since 0.1
*/
public static boolean emptyDirectory(File directory) {
boolean result = false;
File[] entries = directory.listFiles();
for (int i = 0; i < entries.length; i++) {
if (!entries.delete()) {
result = false;
}
}
return true;
}
/**
* 清空指定目录中的文件。
* 这个方法将尽可能删除所有的文件,但是只要有一个文件没有被删除都会返回false。
* 另外这个方法不会迭代删除,即不会删除子目录及其内容。
* @param directoryName 要清空的目录的目录名
* @return 目录下的所有文件都被成功删除时返回true,否则返回false。
* @since 0.1
*/
public static boolean emptyDirectory(String directoryName) {
File dir = new File(directoryName);
return emptyDirectory(dir);
}
/**
* 删除指定目录及其中的所有内容。
* @param dirName 要删除的目录的目录名
* @return 删除成功时返回true,否则返回false。
* @since 0.1
*/
public static boolean deleteDirectory(String dirName) {
return deleteDirectory(new File(dirName));
}
/**
* 删除指定目录及其中的所有内容。
* @param dir 要删除的目录
* @return 删除成功时返回true,否则返回false。
* @since 0.1
*/
public static boolean deleteDirectory(File dir) {
if ( (dir == null) || !dir.isDirectory()) {
throw new IllegalArgumentException("Argument " + dir +
" is not a directory. ");
}
File[] entries = dir.listFiles();
int sz = entries.length;
for (int i = 0; i < sz; i++) {
if (entries.isDirectory()) {
if (!deleteDirectory(entries)) {
return false;
}
}
else {
if (!entries.delete()) {
return false;
}
}
}
if (!dir.delete()) {
return false;
}
return true;
}
/**
* 返回文件的URL地址。
* @param file 文件
* @return 文件对应的的URL地址
* @throws MalformedURLException
* @since 0.4
* @deprecated 在实现的时候没有注意到File类本身带一个toURL方法将文件路径转换为URL。
* 请使用File.toURL方法。
*/
public static URL getURL(File file) throws MalformedURLException {
String fileURL = "file:/" + file.getAbsolutePath();
URL url = new URL(fileURL);
return url;
}
/**
* 从文件路径得到文件名。
* @param filePath 文件的路径,可以是相对路径也可以是绝对路径
* @return 对应的文件名
* @since 0.4
*/
public static String getFileName(String filePath) {
File file = new File(filePath);
return file.getName();
}
/**
* 从文件名得到文件绝对路径。
* @param fileName 文件名
* @return 对应的文件路径
* @since 0.4
*/
public static String getFilePath(String fileName) {
File file = new File(fileName);
return file.getAbsolutePath();
}
/**
* 将DOS/Windows格式的路径转换为UNIX/Linux格式的路径。
* 其实就是将路径中的"\"全部换为"/",因为在某些情况下我们转换为这种方式比较方便,
* 某中程度上说"/"比"\"更适合作为路径分隔符,而且DOS/Windows也将它当作路径分隔符。
* @param filePath 转换前的路径
* @return 转换后的路径
* @since 0.4
*/
public static String toUNIXpath(String filePath) {
return filePath.replace('\\', '/');
}
/**
* 从文件名得到UNIX风格的文件绝对路径。
* @param fileName 文件名
* @return 对应的UNIX风格的文件路径
* @since 0.4
* @see #toUNIXpath(String filePath) toUNIXpath
*/
public static String getUNIXfilePath(String fileName) {
File file = new File(fileName);
return toUNIXpath(file.getAbsolutePath());
}
/**
* 得到文件的类型。
* 实际上就是得到文件名中最后一个“.”后面的部分。
* @param fileName 文件名
* @return 文件名中的类型部分
* @since 0.5
*/
public static String getTypePart(String fileName) {
int point = fileName.lastIndexOf('.');
int length = fileName.length();
if (point == -1 || point == length - 1) {
return "";
}
else {
return fileName.substring(point + 1, length);
}
}
/**
* 得到文件的类型。
* 实际上就是得到文件名中最后一个“.”后面的部分。
* @param file 文件
* @return 文件名中的类型部分
* @since 0.5
*/
public static String getFileType(File file) {
return getTypePart(file.getName());
}
/**
* 得到文件的名字部分。
* 实际上就是路径中的最后一个路径分隔符后的部分。
* @param fileName 文件名
* @return 文件名中的名字部分
* @since 0.5
*/
public static String getNamePart(String fileName) {
int point = getPathLsatIndex(fileName);
int length = fileName.length();
if (point == -1) {
return fileName;
}
else if (point == length - 1) {
int secondPoint = getPathLsatIndex(fileName, point - 1);
if (secondPoint == -1) {
if (length == 1) {
return fileName;
}
else {
return fileName.substring(0, point);
}
}
else {
return fileName.substring(secondPoint + 1, point);
}
}
else {
return fileName.substring(point + 1);
}
}
/**
* 得到文件名中的父路径部分。
* 对两种路径分隔符都有效。
* 不存在时返回""。
* 如果文件名是以路径分隔符结尾的则不考虑该分隔符,例如"/path/"返回""。
* @param fileName 文件名
* @return 父路径,不存在或者已经是父目录时返回""
* @since 0.5
*/
public static String getPathPart(String fileName) {
int point = getPathLsatIndex(fileName);
int length = fileName.length();
if (point == -1) {
return "";
}
else if (point == length - 1) {
int secondPoint = getPathLsatIndex(fileName, point - 1);
if (secondPoint == -1) {
return "";
}
else {
return fileName.substring(0, secondPoint);
}
}
else {
return fileName.substring(0, point);
}
}
/**
* 得到路径分隔符在文件路径中首次出现的位置。
* 对于DOS或者UNIX风格的分隔符都可以。
* @param fileName 文件路径
* @return 路径分隔符在路径中首次出现的位置,没有出现时返回-1。
* @since 0.5
*/
public static int getPathIndex(String fileName) {
int point = fileName.indexOf('/');
if (point == -1) {
point = fileName.indexOf('\\');
}
return point;
}
/**
* 得到路径分隔符在文件路径中指定位置后首次出现的位置。
* 对于DOS或者UNIX风格的分隔符都可以。
* @param fileName 文件路径
* @param fromIndex 开始查找的位置
* @return 路径分隔符在路径中指定位置后首次出现的位置,没有出现时返回-1。
* @since 0.5
*/
public static int getPathIndex(String fileName, int fromIndex) {
int point = fileName.indexOf('/', fromIndex);
if (point == -1) {
point = fileName.indexOf('\\', fromIndex);
}
return point;
}
/**
* 得到路径分隔符在文件路径中最后出现的位置。
* 对于DOS或者UNIX风格的分隔符都可以。
* @param fileName 文件路径
* @return 路径分隔符在路径中最后出现的位置,没有出现时返回-1。
* @since 0.5
*/
public static int getPathLsatIndex(String fileName) {
int point = fileName.lastIndexOf('/');
if (point == -1) {
point = fileName.lastIndexOf('\\');
}
return point;
}
/**
* 得到路径分隔符在文件路径中指定位置前最后出现的位置。
* 对于DOS或者UNIX风格的分隔符都可以。
* @param fileName 文件路径
* @param fromIndex 开始查找的位置
* @return 路径分隔符在路径中指定位置前最后出现的位置,没有出现时返回-1。
* @since 0.5
*/
public static int getPathLsatIndex(String fileName, int fromIndex) {
int point = fileName.lastIndexOf('/', fromIndex);
if (point == -1) {
point = fileName.lastIndexOf('\\', fromIndex);
}
return point;
}
/**
* 将文件名中的类型部分去掉。
* @param filename 文件名
* @return 去掉类型部分的结果
* @since 0.5
*/
public static String trimType(String filename) {
int index = filename.lastIndexOf(".");
if (index != -1) {
return filename.substring(0, index);
}
else {
return filename;
}
}
/**
* 得到相对路径。
* 文件名不是目录名的子节点时返回文件名。
* @param pathName 目录名
* @param fileName 文件名
* @return 得到文件名相对于目录名的相对路径,目录下不存在该文件时返回文件名
* @since 0.5
*/
public static String getSubpath(String pathName,String fileName) {
int index = fileName.indexOf(pathName);
if (index != -1) {
return fileName.substring(index + pathName.length() + 1);
}
else {
return fileName;
}
}
}
4.遗留问题
目前new FileInputStream()只会使用绝对路径,相对没用过,因为要相对于web服务器地址,比较麻烦
还不如写个配置文件来的快哪
5.按Java文件类型分类读取配置文件
配置文件是应用系统中不可缺少的,可以增加程序的灵活性。java.util.Properties是从jdk1.2就有的类,一直到现在都支持load ()方法,jdk1.4以后save(output,string) ->store(output,string)。如果只是单纯的读,根本不存在烦恼的问题。web层可以通过 Thread.currentThread().getContextClassLoader().
getResourceAsStream("xx.properties") 获取;Application可以通过new FileInputStream("xx.properties");直接在classes一级获取。关键是有时我们需要通过web修改配置文件,我们不能将路径写死了。经过测试觉得有以下心得:
1.servlet中读写。如果运用Struts 或者Servlet可以直接在初始化参数中配置,调用时根据servlet的getRealPath("/")获取真实路径,再根据String file = this.servlet.getInitParameter("abc");获取相对的WEB-INF的相对路径。
例:
InputStream input = Thread.currentThread().getContextClassLoader().
getResourceAsStream("abc.properties");
Properties prop = new Properties();
prop.load(input);
input.close();
OutputStream out = new FileOutputStream(path);
prop.setProperty("abc", “test");
prop.store(out, “–test–");
out.close();
2.直接在jsp中操作,通过jsp内置对象获取可操作的绝对地址。
例:
// jsp页面
String path = pageContext.getServletContext().getRealPath("/");
String realPath = path+"/WEB-INF/classes/abc.properties";
//java 程序
InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties"); // abc.properties放在webroot/WEB-INF/classes/目录下
prop.load(in);
in.close();
OutputStream out = new FileOutputStream(path); // path为通过页面传入的路径
prop.setProperty("abc", “abcccccc");
prop.store(out, “–test–");
out.close();
3.只通过Java程序操作资源文件
InputStream in = new FileInputStream("abc.properties"); // 放在classes同级
OutputStream out = new FileOutputStream("abc.properties");
名称 解释 格式
a (Assemble) 逐行汇编 a [address]
c (Compare) 比较两内存块 c range address
d (Dump) 内存16进制显示 d [address]或 d [range]
e (Enter) 修改内存字节 e address [list]
f (fin) 预置一段内存 f range list
g (Go) 执行程序 g [=address][address...]
h (Hexavithmetic) 制算术运算 h value value
i (Input) 从指定端口地址输入 i pataddress
l (Load) 读盘 l [address [driver seetor>
m (Move) 内存块传送 m range address
n (Name) 置文件名 n filespec [filespec...]
o (Output) 从指定端口地址输出 o portadress byte
q (Quit) 结束 q
r (Register) 显示和修改寄存器 r [register name]
s (Search) 查找字节串 s range list
t (Trace) 跟踪执行 t [=address] [value]
u (Unassemble) 反汇编 u [address ]或range
w (Write) 存盘 w [address[driver sector secnum>
? 联机帮助 ?
debug小汇编a命令
debug小汇编a命令是一个很有用的功能,许多的小程序都要他来做。
编一些小程序比汇编要来得方便,快洁。
在Debug中,中断是非常有用的,首先,让我们先了解一下中断。
所谓中断,其实,就是,当你做某事时,有人过来找你有其他事,你先放下手中的事(计算机中,称为保护现场)
,再去与叫你的那个人办事去,等完了,你又回,接着做刚才的事。这是个很通俗的讲法。
计算机在运行时,也会出现这种情况,我们叫之中断。
下面是他的一些常用中断向量的入口值详解:(记住哦,很用的...呵呵)
IBM PC 中断 int10
ooH 屏幕方式设置
入口:AH=0,AL=显示方式代码(0--6)
0:40*25 黑白
1:40*25 彩色
2:80*25 黑白
3:80*25 彩色文本
4:320*200 彩色
5:320*200 黑白
6:640*200 黑白图形模式
7:80*25 单色字符(单色显示器)
0BH 色彩设置
入口:AH=0B,BL=0 设背景色,BH=0--15 BL=1 设调色码,BH=0--1
0CH 写图形点
入口:AH=0C,CX:DX=列号:行号,AL=颜色
ODH 读图形点
入口:AH=0D,CX:DX=列号:行号
返回:AL=颜色
0EH 在当前页、当前光标处写字符
入口:AH=0E,AL=字符的ASCII码,BL=前景色
OFH 显示器状态
入口:AH=0F
返回:AL=当前显示器方式,AH=屏幕列数,BH=当前页号
01H 光标设置
入口:AH=1,CH=光标起始行号(00--0C),CL=光标结束行号(00--0C)
注:CH > CL
02H 光标定位
入口:AH=2,BH=页号,DH:DL=起始行:列
03H 读光标位置
入口:AH=3,BH=页号。
返回:DH:DL=起始行:列
06H 窗口上卷
入品:AH=6,AL=窗口上卷行数,CH:CL-DH:DL 窗口坐标
注:AL=0 卷动整个窗口
07H 窗口下卷
入口:AH=7,AL=窗口下卷行数,CH:CL-DH:DL 窗口坐标
08H 读当前光标处字符和属性
入口:AH=8,BH=页号。
返回:AH:AL=字符的颜色:字符的ASCII码
注:颜色代码见下对照表
09H:在当前光标处写字符和属性
注:光标不下移
入口:AH=9,BH=页号,BL:AL=字符的颜色:字符的ASCII码,CX=重复次数
1 2 3 4 5 6 7 8
BL R G B I R G B
闪烁 字符底色 加亮 字符颜色
中断向量号表
中断号 解释 中断号 解释
0 除数为0错 19 引导装入程序
1 音步中断 1A 日时调用
2 不可屏蔽中断NMI 1B 键盘阻断时得到控制权
3 断电中断(CCH) 1C 时钟中断时得到控制权
4 溢出中断 1D 指向CRT初始参数表
5 屏幕打印中断 1E 指向盒带参数表
6-7 保留 1F 1KB图形模式
8 计时器中断(18.2秒) 20 结束DOS程序
9 键盘中断 21 DOS功能调用
A-D 保留 22 结束地址(建义用EXEC)
E 软盘机中断 23 DOS Crtl-Break退出地址
F 保留 24 DOS致命错向量
10 屏幕I/O调用 25 DOS绝对磁盘读
11 设备检查调用 26 DOS绝对磁盘写
12 存储器检查调用 27 结束程序并驻留(建义用31h)
13 软盘机I/O调用 28-3F DOS保留
14 RS-233I/O调用 40-7F 未用
15 盒带机I/O调用 80-85 BASIC保留
16 键盘I/O调用 86-F0 BASIC解释程序用
17 打印机I/O调用 F1-FF 未用
18 ROM-BASIC入口
指令名详解
call 指令(过程调用)(控制指令-长转移)
详解:
段内直接调用
段内间接调用(寄存器)
段内间接调用(存储器)
段间直接调用
段间间接调用
指令名
jmp 指令(无条件转移指令)(控制指令-长转移)
详解:
段内直接跳转
短段内直接跳转
段内间接跳转(寄存器)
段内间接跳转(存储器)
段间直接跳转
段间间接跳转
指令名
ret 指令(过程返回)(控制指令-长转移)
详解:
段内返回
段内返回立即数加于sp
段间返回
段间返回立即数加于sp
na/jnbe 指令(控制指令-短转移) 不小于或不等于时转移
jae/jnb 指令 (控制指令-短转移) 大于或等于时转移
jb/jnae 指令 (控制指令-短转移) 小于转移
jbe/jna 指令 (控制指令-短转移) 小于或等 于转移
jg/jnle 指令(控制指令-短转移) 大于转移
jge/jnl 指令 (控制指令-短转移) 大于或等于转移
jl/jnge 指令 (控制指令-短转移) 小于转移
jle/jng 指令 (控制指令-短转移) 小于或等 于转移
je/jz 指令 (控制指令-短转移) 等于转移
jne/jnz 指令 (控制指令-短转移) 不等于转移
jc 指令 (控制指令-短转移) 有进位时转移
jnc 指令 (控制指令-短转移) 列进位时转移
jno 指令 (控制指令-短转移) 不溢出时转移
jnp/jpo 指令 (控制指令-短转移) 奇偶性为奇数时转移
jns 指令 (控制指令-短转移) 符号位为"0"转移
jo 指令 (控制指令-短转移) 溢出转移
jp/jpe 指令 (控制指令-短转移) 奇偶性为偶数时转移
js 指令 (控制指令-短转移) 符号位为"1"时转移
loop 指令 (循环控制指令-短转移) cx 不为0时循环
loope/loopz 指令 (循环控制指令-短转移) cx 不为0且标志 z=1 时循环
loopne/loopnz 指令 (循环控制指令-短转移) cx 不为0且标志 z=0 时循环
jcxz 指令 (循环控制指令-短转移) cx 为0时转移
★int 指令 (中断指令) 中断指令(后详解)
into 指令 (中断指令) 溢出中断
iret 指令 (中断指令) 中断返回
指令名
shl 指令(逻辑左移)
sal 指令(算术左移)
shr 指令(逻辑右移)
sar 指令(算术右移) 寄存器,1
rol 指令(循环左移) 寄存器,cl
ror 指令(循环右移) 存储器,1
rcl 指令(通过进位的循环左移)存储器,cl
rcr 指令(通过进位的循环右移)(逻辑运算)
not 指令(取反运算)寄存器求反
(逻辑运算)存储器求反
and 指令(与运算) (逻辑运算)
寄存器 and 寄存器 寄存器
寄存器 and 存储器 寄存器
存储器 and 寄存器 存储器
立即数 and 存储器 存储器
立即数 and 累加器 累加器
or 指令(或运算)(逻辑运算)
寄存器 or 寄存器 寄存器
寄存器 or 存储器 寄存器
存储器 or 寄存器 存储器
立即数 or 存储器 存储器
立即数 or 累加器 累加器
test 指令(测试) (逻辑运算)
寄存器 test 寄存器
寄存器 test 存储器
寄存器 test 立即数
存储器 test 立即数
累加器 test 立即数
movs 指令(串传送)(字符串操作指令)
单个传送
重复传送
cmps 指令(串比较) (字符串操作指令)
单个比较
重复比较
scas 指令(串扫描)(字符串操作指令)
单个搜索
重复搜索
lods 指令(装入串)
(字符串操作指令)
单个装载
重复装载
stos 指令(保存串) (字符串操作指令)
单个存储
重复存储
mov 指令(传送字或字节)(数据传送命令)
寄存器与寄存器间传送
存储器与寄存器间传送
立即数传送给存储器
立即数传送给寄存器
存储器传送给累加器
累加器传送存储器
寄存器传送给段寄存器
存储器传送给段寄存器
段寄存器传送给寄存器
段寄存器传送给存储存器
pop 指令(把字弹出堆栈) (数据传送命令)
push 指令(把字压入堆栈)
存储器
寄存器
段寄器
xchg 指令(交换字或字节) (数据传送命令)
寄存器与寄存器交换
存储器与寄存器交换
寄存器与累加器交换
in 指令(端口输入) (数据传送命令)
直接输入
间接输入
out 指令(端口输出) (数据传送指令)
直接输出
间接输出
add 指令(加法)(算术指令)
adc 指令(带进位加法)
寄存器+寄存器 寄存器
寄存器+存储器 寄存器
存储器+寄存器 存储器
立即数+存储器 存储器
立即数+累加器 累加器
inc 指令(加1)(算术指令)
存储器增量
寄存器增量
sub 指令(减法) (算术指令)
sbb 指令(带借位减法)
寄存器-寄存器 寄存器
寄存器-存储器 寄存器
存储器-寄存器 存储器
立即数-存储器 存储器
立即数-累加器 累加器
dec 指令(减1)(算术指令)
存储器减量
寄存器减量
nec 指令(求反,以0减之)
寄存器求补
存储器求补
cmp 指令(比较)(算术指令)
寄存器与寄存器比较
寄存器与存储器比较
寄存器与立即数比较
存储器与立即数比较
累加器与立即数比较
mul 指令(无符号乘法) (算术指令)
imul 指令(整数乘法)
与8位寄存器相乘
与16位寄存器相乘
与8位存储单元相乘
与16位存储单元相乘
div 指令(无符号除法)(算术指令)
idiv 指令(整数除法)
被8位寄存器除
被16位寄存器除
被8位存储单元除
被16位存储单元除
Debug实战
1.查看主板的生产日期,版本
D ffff:05
D fe00:0e
2.模拟Rest键功能
A
:100 jmp ffff:0000
:105
g
3.快速格式化软盘
L 100 0 0 * '插入一张己格式化软盘
W 100 0 0 * '放入一张欲格式化软盘
注:* 分别为:720K e |1.2M id |1.44M 21
4.硬盘格式化两种方法
(1)G=c800:05
(2) A 100
mov ax,0703
mov cx,0001
mov dx,0080
int 13
int 3
g 100
5.加速键盘
A
mov ax,0305
mov bx,0000
int 16
int 20
rcx
10
n fast.com
w
q
6.关闭显示器(恢复时,按任意键)
A
mov ax,1201
mov bl,36
int 10
mov ah,0
int 16
mov ax,1200
int 10
rcx
10
n crt-of.com
w
q
7.硬盘DOS引导记录的修复
在软驱中放入一张己格式化软盘
debug
-l 100 2 0 1
-w 100 0 50 1
把软盘放入故障机软驱中
debug
-l 100 0 50 1
-w 100 2 0 1
-q
8.清coms中setup口令
debug
-a
mov bx,0038
mov cx,0000
mov ax,bx
out 70,al
inc cx
cmp cx,0006
jnz 0106
int 20
-rcx
:20
-nclearpassword.com
-w
-q
注:以上适合super与dtk机,对于ast机,因为他的口令放在coms的4ch-51h地址处,只要将:mov bx,0038 改为: mov
bx,004c即可
9.取消coms的密码(将coms数据清为初始化)
-o 70,10
-o 71,10
-g
-q
10.将硬盘主引导记录保存到文件中
debug
-a
mov ax,0201
mov bx,0200
mov cx,0001
mov dx,0080
mov int 13
int 3
-rcx
:200
-nboot.dat
-w
-q
11.调用中断实现重启计算机(可以成文件)
debug
-a
int 19
int 20
-rcx
:2
-nreset.com
-w
-q
DEBUG主要命令
DEBUG是为汇编语言设计的一种高度工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。
一、DEBUG程序的调用
在DOS的提示符下,可键入命令:
C:\DEBUG [D:][PATH][FILENAME[.EXT>[PARM1][PARM2]
其中,文件名是被调试文件的名字。如用户键入文件,则DEBUG将指定的文件装入存储器中,用户可对其进行调试。如果未键入文件名,则用户可以用当前存储器的内容工作,或者用DEBUG命令N和L把需要的文件装入存储器后再进行调试。命令中的D指定驱动器PATH为路径,PARM1和PARM2则为运行被调试文件时所需要的命令参数。
在DEBUG程序调入后,将出现提示符,此时就可用DEBUG命令来调试程序。
二、DEBUG的主要命令
1、显示存储单元的命令D(DUMP),格式为:
_D[address]或_D[range]
例如,按指定范围显示存储单元内容的方法为:
-d100 120
18E4:0100 c7 06 04 02 38 01 c7 06-06 02 00 02 c7 06 08 02 G...8.G.....G...
18E$:0110 02 02 bb 04 02 e8 02 00-CD 20 50 51 56 57 8B 37 ..;..h..M PQVW.
7
18E4:0120 8B
其中0100至0120是DEBUG显示的单元内容,左边用十六进制表示每个字节,右边用ASCII字符表示每个字节,·表示不可显示的字符。这里没有指定段地址,D命令自动显示DS段的内容。如果只指定首地址,则显示从首地址开始的80个字节的内容。如果完全没有指定地址,则显示上一个D命令显示的最后一个单元后的内容。
2、修改存储单元内容的命令有两种。
·输入命令E(ENTER),有两种格式如下:第一种格式可以用给定的内容表来替代指定范围的存储单元内容。命令格式为:
-E address [list]
例如,-E DS:100 F3'XYZ'8D
其中F3,'X','Y','Z'和各占一个字节,该命令可以用这五个字节来替代存储单元DS:0100到0104的原先的内容
第二种格式则是采用逐个单元相继修改的方法。命令格式为:
-E address
例如,-E DS:100
则可能显示为:
18E4:0100 89.-
如果需要把该单元的内容修改为78,则用户可以直接键入78,再按"空格"键可接着显示下一个单元的内容,如下:
18E4:0100 89.78 1B.-
这样,用户可以不断修改相继单元的内容,直到用ENTER键结束该命令为止。
·填写命令F(FILL),其格式为:
-F range list
例如:-F 4BA:0100 5 F3'XYZ'8D
使04BA:0100~0104单元包含指定的五个字节的内容。如果list中的字节数超过指定的范围,则忽略超过的项;如果list的字节数小于指定的范围,则重复使用list填入,直到填满指定的所有单元为止。
3)检查和修改寄存器内容的命令R(register),它有三种格式如下:
·显示CPU内所有寄存器内容和标志位状态,其格式为:
-R
例如,-r
AX=0000 BX=0000 CX=010A DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=18E4 ES=18E4 SS=18E4 CS=18E4 IP=0100 NV UP DI PL NZ NA PO NC
18E4:0100 C70604023801 MOV WORD PTR [0204],0138 DS:0204=0000
·显示和修改某个寄存器内容,其格式为:
-R register name
例如,键入
-R AX
系统将响应如下:
AX F1F4
:
即AX寄存器的当前内容为F1F4,如不修改则按ENTER键,否则,可键入欲修改的内容,如:
-R bx
BX 0369
:059F
则把BX寄存器的内容修改为059F。
·显示和修改标志位状态,命令格式为:
-RF系统将响应,如:
OV DN EI NG ZR AC PE CY-
此时,如不修改其内容可按ENTER键,否则,可键入欲修改的内容,如:
OV DN EI NG ZR AC PE CY-PONZDINV
即可,可见键入的顺序可以是任意的。
4)运行命令G,其格式为:
-G[=address1][address2[address3…>
其中,地址1指定了运行的起始地址,如不指定则从当前的CS:IP开始运行。后面的地址均为断点地址,当指令执行到断点时,就停止执行并显示当前所有寄存器及标志位的内容,和下一条将要执行的指令。
5)跟踪命令T(Trace),有两种格式:
·逐条指令跟踪
-T [=address]
从指定地址起执行一条指令后停下来,显示所有寄存器内容及标志位的值。如未指定地址则从当前的CS:IP开始执行。
·多条指令跟踪
-T [=address][value]
从指定地址起执行n条指令后停下来,n由value指定。
6)汇编命令A(Assemble),其格式为:
-A[address]
该命令允许键入汇编语言语句,并能把它们汇编成机器代码,相继地存放在从指定地址开始的存储区中。必须注意:DEBUG把键入的数字均看成十六进制数,所以如要键入十进制数,则其后应加以说明,如100D。
7)反汇编命令U(Unassemble)有两种格式。
·从指定地址开始,反汇编32个字节,其格式为:
-U[address]
例如:
-u100
18E4:0100 C70604023801 MOV WORD PTR[0204],0138
18E4:0106 C70606020002 MOV WORD PTR[0206],0200
18E4:010C C70606020202 MOV WORD PTR[0208],0202
18E4:0112 BBO4O2 MOV BX,0204
18E4:0115 E80200 CALL 011A
18E4:0118 CD20 INT 20
18E4:011A 50 PUSH AX
18E4:011B 51 PUSH CX
18E4:011C 56 PUSH SI
18E4:011D 57 PUSH DI
18E4:011E 8B37 MOV SI,[BX]
如果地址被省略,则从上一个U命令的最后一条指令的下一个单元开始显示32个字节。
·对指定范围内的存储单元进行反汇编,格式为:
-U[range]
例如:
-u100 10c
18E4:0100 C70604023801 MOV WORD PTR[0204],0138
18E4:0106 C70606020002 MOV WORD PTR[0206],0200
18E4:010C C70606020202 MOV WORD PTR[0208],0202
或
-u100 112
18E4:0100 C70604023801 MOV WORD PTR[0204],0138
18E4:0106 C70606020002 MOV WORD PTR[0206],0200
18E4:010C C70606020202 MOV WORD PTR[0208],0202
可见这两种格式是等效的。
8)命名命令N(Name),其格式为:
-N filespecs [filespecs]
命令把两个文件标识符格式化在CS:5CH和CS:6CH的两个文件控制块中,以便在其后用L或W命令把文件装入存盘。filespecs的格式可以是:
[d:][path] filename[.ext]
例如,
-N myprog
-L
-
可把文件myprog装入存储器。
9)装入命令(Load),有两种功能。
·把磁盘上指定扇区范围的内容装入到存储器从指定地址开始的区域中。其格式为:
-L[address[drive sector sector]
·装入指定文件,其格式为:
-L[address]
此命令装入已在CS:5CH中格式化了文件控制块所指定的文件。如未指定地址,则装入CS:0100开始的存储区中。
10)写命令W(Write),有两种功能。
·把数据写入磁盘的指定扇区。其格式为:
-W address drive sector sector
·把数据写入指定的文件中。其格式为:
-W[address]
此命令把指定的存储区中的数据写入由CS:5CH处的文件控制块所指定的文件中。如未指定地址则数据从CS:0100开始。要写入文件的字节数应先放入BX和CX中。
11)退出DEBUG命令Q(Quit),其格式为:
-Q
它退出DEBUG,返回DOS。本命令并无存盘功能,如需存盘应先使用W命令。
问题:初学者问一个低级问题,执行debug-a后,如果有一行输入错误,如何更改这一行?
回答:
加入进行如下输入:
D:\PWIN95\Desktop>debug
-a
2129:0100movax,200
2129:0103movbx,200
2129:0106movcx,200
2129:0109
此时,发现movbx,200一句错误,应为movbx,20,可以敲回车返回"-"状态,然后输入:
-a103
2129:0103movbx,20
如果多或者少若干行,不必重新输入,可以用M命令移动后面的程序来去掉或者增加程序空间.
A.程序调用命令
C>DEBUG [D:] [PATH] [FILENAME[.EXT]] [PARM1] [PARM2]
其中,文件名是被调试文件的名字。如未键入文件名。可用DEBUG命令N和L把需要文件装入存储器后再调试。D指定驱动器,PATH为路径,FILENAME为文件名,PARM为命令参数
B.显示存储单元命令
-D [ADDRESS]或 ;ADDRESS 地址
-D [RANGE] ;RANGE 范围
C.修改存储单元内容命令
-E ADDRESS [LIST]
D.检查和修改寄存器内容命令
-R [REGISTER NAME] ;Register name 寄存器名字
E.汇编命令
-A [ADDRESS]
F.跟踪命令
-T [=ADDRESS] [VALUE] ;Value 变量值
G.运行命令
-G [=ADDRESS ] [ADDRESS2 [ADDRESS3]
H.反汇编命令
-U [ADDRESS]
-U [RANGE]
I.命名命令
-N FILESPECS [FILESPECS]
FILESPECS的格式可为[D:][PATH]FILENAME [.EXT]
J.装入命令
-L [ADDRESS[DRIVE SECTOR SECTOR]] ;DRIVE SECTOR 磁盘 扇区
K.写命令
W ADDRESS DRIVE SECTOR
L.退出命令
-Q
通过HREF就可以调用javascript,有两种方法十分简单,如下:
方法1
<A HREF="javascript:myFunction()">
Click here for Javascript action!</A>
注:如果Javascript被浏览器禁用,会有一个错误提示警告读者无法运行Javascript程序。
方法2
<A HREF="nojavascripthere.htm"
onClick="myFunction(); return false">
Click here for Javascript action!
</A>
注:如果Javascript被浏览器禁用,会显示一个页面警告读者无法运行Javascript程序。