62,615
社区成员
发帖
与我相关
我的任务
分享
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.tarena.bo.LogData;
import com.tarena.bo.LogRec;
/**
* DMS客户端
* @author Administrator
*
*/
public class DMSClient {
/*
* 第一步,将wtmpx文件日志内容批量解析后
* 存入另一个文件中需要的属性。
*/
//wtmpx日志文件
private File logFile;
//保存解析后的日志的文件
private File textLogFile;
//一次从wtmpx文件中解析日志的条目数
private int batch;
/*
* 记录上次批量读取wtmpx文件后的字节位置
* 以便下次读取时从这里继续解析
*/
private File lastPositionFile;
/*
* 第二步中用到的属性
*/
//保存配对日志的文件
private File logRecFile;
//保存没有配对成功的日志的文件
private File loginLogFile;
/*
* 第三步中用到的属性
*/
//服务端的地址
private String serverHost;
//服务端的端口
private int serverPort;
/**
* 构造方法,用于初始化客户端的属性
* @throws Exception
*/
public DMSClient() throws Exception{
try{
//1:解析config.xml文件,获取配置项
Map<String,String> config
= loadConfig();
//打桩
System.out.println(config);
//2:根据配置项来初始化对应属性
init(config);
}catch(Exception e){
throw e;
}
}
/**
* 根据配置信息初始化客户端属性
* @param config
* @throws Exception
*/
private void init(Map<String,String> config)
throws Exception{
try {
logFile
= new File(
config.get("logfile")
);
textLogFile
= new File(
config.get("textlogfile")
);
lastPositionFile
= new File(
config.get("lastpositionfile")
);
batch = Integer.parseInt(
config.get("batch")
);
logRecFile = new File(
config.get("logrecfile")
);
loginLogFile = new File(
config.get("loginlogfile")
);
serverHost = config.get("serverhost");
serverPort = Integer.parseInt(
config.get("serverport")
);
} catch (Exception e) {
throw e;
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* DMS服务端
* @author Administrator
*
*/
public class DMSServer {
private ServerSocket server;
private ExecutorService threadPool;
/*
* Server端保存所有客户端发送过来的日志
* 的文件
*/
private File serverLogFile;
/*
* 消息队列,用于保存所有客户端发送过来的
* 配对日志
*/
private BlockingQueue<String> messageQueue;
/**
* 构造方法用于初始化服务端
* @throws Exception
*/
public DMSServer() throws Exception{
try {
server = new ServerSocket(8088);
threadPool = Executors.newFixedThreadPool(30);
serverLogFile = new File("server_logs.txt");
messageQueue = new LinkedBlockingQueue<String>();
} catch (Exception e) {
throw e;
}
}
/**
* 服务端开始工作的方法
*/
public void start(){
try {
/*
* 启动用于保存客户端发送过来的配对
* 日志的线程
*/
SaveLogHandler saveHandler
= new SaveLogHandler();
Thread t = new Thread(saveHandler);
t.start();
while(true){
Socket socket
= server.accept();
//启动一个线程,来完成交互
ClientHandler clientHandler
= new ClientHandler(socket);
//将任务交给线程池分配线程启动
threadPool.execute(clientHandler);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args){
DMSServer server;
try {
server = new DMSServer();
server.start();
} catch (Exception e) {
System.out.println("服务端启动失败!");
e.printStackTrace();
}
}
/**
* 该线程用来处理给定的客户端的消息
* 主要作用:
* 读取客户端发送过来的每一条配对日志
* 并保存至文件中
* @author Administrator
*
*/
class ClientHandler implements Runnable{
//当前线程要处理的客户端的Socket
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run(){
PrintWriter pw = null;
try {
pw = new PrintWriter(
new OutputStreamWriter(
socket.getOutputStream(),
"UTF-8"
)
);
/*
* 通过开客户端的Socket获取
* 输入流,循环按行读取每一条
* 客户端发送过来的配对日志,
* 然后将其写入本地文件中。
* 当保存后,回复客户端“OK”
* 若出现异常,回复客户端"ERROR"
*/
BufferedReader br
= new BufferedReader(
new InputStreamReader(
socket.getInputStream()
,
"UTF-8"
)
);
/*
* 循环读取客户端发送过来的每一个字符串
*/
String log = null;
while((log = br.readLine())!=null){
// System.out.println(log);
if("OVER".equals(log)){
break;
}
//将该字符串存入消息队列
messageQueue.offer(log);
}
//响应客户端操作成功!
pw.println("OK");
pw.flush();
} catch (Exception e) {
//响应客户端操作失败!
pw.println("ERROR");
pw.flush();
} finally{
/*
* 当客户端与服务端断开后,同样
* 这里也和客户端断开,释放资源
*/
if(socket != null){
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}
/**
* 该线程的作用是循环从消息队列中
* 取出每一条日志,然后将其写入本地
* 文件保存
* @author Administrator
*
*/
class SaveLogHandler implements Runnable{
public void run(){
PrintWriter pw = null;
try {
pw = new PrintWriter(serverLogFile);
/*
* 循环从队列中取出每一条日志,写入
* 文件,若队列中没有日志了,就等待
* 一会。
*/
while(true){
if(messageQueue.size()>0){
String log = messageQueue.poll();
pw.println(log);
}else{
//先将缓存中的全部写入文件
pw.flush();
//休息半秒钟
Thread.sleep(500);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(pw != null){
pw.close();
}
}
}
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.tarena.bo.LogData;
/**
* 该类用于处理客户端相关的IO操作。
* 该类是一个工具类,所以定义的方法都是静态的。
* @author Administrator
*
*/
public class IOUtil {
/**
* 该方法用于从给定的文件中读取第一行字符串
* 并将其转换为long值返回。若读取过程中出现
* 异常,会将其抛出给调用者。
* @param file
* @return
* @throws Exception
*/
public static long readLong(File file)
throws Exception{
BufferedReader br = null;
try {
br = new BufferedReader(
new InputStreamReader(
new FileInputStream(
file
)
)
);
String line = br.readLine().trim();
return Long.parseLong(line);
} catch (Exception e) {
throw e;
} finally{
if(br != null){
br.close();
}
}
}
/**
* 从给定的RandomAccessFile当前位置开始
* 连续读取给定长度的字节量,并将其转换为
* 字符串返回
* @param raf
* @param length
* @return
* @throws Exception
*/
public static String readString(
RandomAccessFile raf,int length)
throws Exception{
try {
byte[] buf = new byte[length];
raf.read(buf);
return new String(buf,"iso8859-1");
} catch (Exception e) {
throw e;
}
}
/**
* 将给定的集合中的每一个元素的toString返回的
* 字符串以行为单位写入给定的文件中
* @param file
* @param c
* @throws Exception
*/
public static void saveCollection(
File file,Collection c)
throws Exception{
PrintWriter pw = null;
try {
pw = new PrintWriter(file);
for(Object o : c){
pw.println(o.toString());
}
} catch (Exception e) {
throw e;
} finally{
if(pw != null){
pw.close();
}
}
}
/**
* 将给定的long值以行为单位用字符串的形式
* 写入给定文件中
* @param file
* @param l
* @throws Exception
*/
public static void saveLong(
File file,long l)
throws Exception{
PrintWriter pw = null;
try {
pw = new PrintWriter(file);
pw.println(l);//不是"1"!
} catch (Exception e) {
throw e;
} finally{
if(pw != null){
pw.close();
}
}
}
/**
* 该方法用于从给定的文件中读取每一行字符串
* 然后将其转换为若干个LogData实例并存入
* 集合后返回该集合
* @param file
* @return
* @throws Exception
*/
public static List<LogData>
readLogData(File file)
throws Exception{
BufferedReader br = null;
try {
br = new BufferedReader(
new InputStreamReader(
new FileInputStream(
file
)
)
);
List<LogData> list
= new ArrayList<LogData>();
String line = null;
while((line=br.readLine())!=null){
LogData log = new LogData(line);
list.add(log);
}
return list;
} catch (Exception e) {
throw e;
} finally{
if(br != null){
try{
br.close();
}catch(Exception e){
}
}
}
}
/**
* 将给定文件中的每一行字符串(配对日志)
* 读取出来并存入集合,然后将该集合返回
* @param file
* @return
* @throws Exception
*/
public static List<String>
readLogRec(File file)
throws Exception{
BufferedReader br = null;
try {
br = new BufferedReader(
new InputStreamReader(
new FileInputStream(
file
)
)
);
List<String> list
= new ArrayList<String>();
String line = null;
while((line = br.readLine())!=null){
list.add(line);
}
return list;
} catch (Exception e) {
throw e;
} finally{
if(br != null){
try {
br.close();
} catch (IOException e) {
}
}
}
}
}
三个类~ 具体思路我忘了。 你自己看吧