网站计数器必须注意以下三个问题:
(1)网站的来访人数可能会很多,有可能超过20位数,所以必须使用大整数累——BigInteger累完成。
(2)用户每次在第一次访问时才需要进行计数的操作,在执行计算之前必须使用isNew()判断。
(3)在进行更改、保存时需要进行同步操作。
<%@ page contentType="text/html" pageEncoding="GBK"%>
<%@ page import="java.io.*"%> <%--由于要使用IO操作,必须导入java.io包--%>
<%@ page import="java.util.*"%> <%--Scanner在java.util包中定义--%>
<%@ page import="java.math.*"%> <%--BigInteger定义在java.math包中--%>
<html>
<head><title>Java</title></head>
<body>
<%!
BigInteger count=null; //定义成全局变量
%>
<%!
public BigInteger load(File file){ //读取计数文件
BigInteger count=null; //接受计数文件
try{
if(file.exists()){ //如果文件存在,则读取
Scanner scan=null; //定义Scanner对象
scan=new Scanner(new FileInputStream(file));//从文件中读取
if(scan.hasNext()){ //存在内容
count=new BigInteger(scan.next());//将内容放到BigInteger类中
}
scan.close(); //关闭输入流
}else{ //文件不惨在则创建新的
count=new BigInteger("0"); //第一次访问
save(file.count); //调用save(),保存新的文件
}
}catch(Exception e){
e.printStackTrace();
}
return count; //返回读取后的数据
}
public void save(File file,BigInteger count){ //保存计数文件
try{
PrintStream ps=null; //定义输出流对象
ps=new PrintStream(new FileOutputStream(file));//打印流对象
ps.println(count);//保存数据
ps.close();//关闭输出流
}catch(Exception e){
e.printStackTrace();
}
}
%>
<%
String fileName=this.getServletContext().getRealPath("/")+"count.txt"; //文件路径
File file =new File(fileName);
if(session.isNew()){
synchronized(this){ //必须进行同步操作
count=load(file);
count=count.add(new BigInteger("1"));//自增操作
save(file,count); //保存修改后的数据
}
}
%>
<h2>您是第<%=count==null?0:count%>位访客!</h2>
</body>
</html>
本程序中,首先定义了一个全局变量BigInteger,这样即使用户刷新页面,BigInteger对象也不会重复声明。程序中为了保存和读取操作的方便,分别定义了save()和load()方法。load()中首先判断文件是否存在,如果存在,则将已有内容读取进来;如果文件不存在,则创建一个新的count.txt文件(此文件默认保存在Web项目的根目录中),并且将其中的内容设置为0.如果用户是第一次访问,则要执行文件的更新操作,在同步代码中首先对内容进行修改(让内容加1,由于使用的BigInteger,所以要使用其中的add()完成操作),然后将新的内容重新保存在文件中。