第一个:
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.io.*"%>
<%!
// 读取文件
public int load(String path){
int temp = 0 ;
try{
File f = new File(path) ;
BufferedReader buf = new BufferedReader(new InputStreamReader(new FileInputStream(f))) ;
String str = buf.readLine() ;
temp = Integer.parseInt(str) ;
buf.close() ;
}catch(Exception e){}
return temp ;
}
public synchronized void save(int c,String path){ // 需要同步
try{
File f = new File(path) ;
PrintStream ps = new PrintStream(new FileOutputStream(f)) ;
ps.print(c) ;
ps.close() ;
}catch(Exception e){}
}
%>
<%
String path = getServletContext().getRealPath("/") + "count.txt" ;
int count = load(path) ;
%>
<%
if(session.isNew()){ // 如果是第一次访问
save(++count,path) ;
}
%>
<h2>您是第位<%=count%>访问者!!</h2>
第二个:
<%@ page contentType="text/html" pageEncoding="GBK"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<%@ page import="java.math.*"%>
<html>
<head><title> 网站统计 </title></head>
<body>
<%!
BigInteger count = null ;
%>
<%!
public BigInteger load(File file){
BigInteger count = null ; // 接收数据
try{
if(file.exists()){
Scanner scan = new Scanner(new FileInputStream(file)) ;
if(scan.hasNext()){
count = new BigInteger(scan.next()) ;
}
scan.close() ;
} else { // 应该保存一个新的,从0开始
count = new BigInteger("0") ;
save(file,count) ; // 保存一个新的文件
}
}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"; // 这里面保存所有的计数的结果
System.out.println(fileName) ;
File file = new File(fileName) ;
if(session.isNew()){
synchronized(this){
count = load(file) ; // 读取
count = count.add(new BigInteger("1")) ; // 再原本的基础上增加1。
save(file,count) ;
}
}
%>
<h2>您是第<%=count==null?0:count%>位访客!</h2>
</body>
</html>
2个页面都是用application完成的一个网站的计数器操作,每次当有新的用户来的时候,就要求记录的数字加1,在用来第一次来的时候进行计算.在WEB根目录中创建count.txt的文件.
application保存的内容可以让所有人共同访问,getServletContext()方法就是application. getRealPath方法可以取得虚拟目录对应的绝对路径.
application是ServletContext接口的对象,表示的是整个容器的上下文.
通过IO操作,读取count.txt中的数字并保存.两者的save方法基本相似,但在load方法上有所不同,第一个只是简单的读取了count.txt中的内容,而第二个在读取时判断的文件的完整性,而且使用了BigInteger作为返回类型,有利于大流量的访问统计.
1 楼
mfkvfn
2012-03-02
不需要每次写文件。
在服务器启动时从文件读取一次缓存在Java单例中,每次只用读取和修改这个缓存就可以了。服务器停止的时候写回到文件中。
只做一次读取和写入了。其它时候都是操作内存。
在服务器启动时从文件读取一次缓存在Java单例中,每次只用读取和修改这个缓存就可以了。服务器停止的时候写回到文件中。
只做一次读取和写入了。其它时候都是操作内存。
2 楼
bolovesang
2012-03-02
mfkvfn 写道
不需要每次写文件。
在服务器启动时从文件读取一次缓存在Java单例中,每次只用读取和修改这个缓存就可以了。服务器停止的时候写回到文件中。
只做一次读取和写入了。其它时候都是操作内存。
在服务器启动时从文件读取一次缓存在Java单例中,每次只用读取和修改这个缓存就可以了。服务器停止的时候写回到文件中。
只做一次读取和写入了。其它时候都是操作内存。
读取缓存也是种好方法,适用于在日维护或周维护时的流量统计,但对于实时的流量统计,还是要进行文件读取吧?
3 楼
canghailan
2012-03-02
你这么做,性能够呛啊:每次访问,synchronized里还有IO。
第一段代码里的同步貌似还有些问题。
最简单的做法就是bolovesang说的缓存,可以使用static AtomicLong,服务器启动时读取,停止时写回。
第一段代码里的同步貌似还有些问题。
最简单的做法就是bolovesang说的缓存,可以使用static AtomicLong,服务器启动时读取,停止时写回。
4 楼
canghailan
2012-03-02
BigInteger也没什么必要,long完全足够了,100亿人每分钟访问一次都能撑上1000多年的。