当前位置: 代码迷 >> Web前端 >> 两个简略网站计数器的比较
  详细解决方案

两个简略网站计数器的比较

热度:351   发布时间:2013-11-09 17:06:47.0
两个简单网站计数器的比较
第一个:
<%@ 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单例中,每次只用读取和修改这个缓存就可以了。服务器停止的时候写回到文件中。
只做一次读取和写入了。其它时候都是操作内存。
2 楼 bolovesang 2012-03-02  
mfkvfn 写道
不需要每次写文件。
在服务器启动时从文件读取一次缓存在Java单例中,每次只用读取和修改这个缓存就可以了。服务器停止的时候写回到文件中。
只做一次读取和写入了。其它时候都是操作内存。


读取缓存也是种好方法,适用于在日维护或周维护时的流量统计,但对于实时的流量统计,还是要进行文件读取吧?
3 楼 canghailan 2012-03-02  
你这么做,性能够呛啊:每次访问,synchronized里还有IO。
第一段代码里的同步貌似还有些问题。
最简单的做法就是bolovesang说的缓存,可以使用static AtomicLong,服务器启动时读取,停止时写回。
4 楼 canghailan 2012-03-02  
BigInteger也没什么必要,long完全足够了,100亿人每分钟访问一次都能撑上1000多年的。
  相关解决方案