最近在開發實戰中,遇到了一個這樣的技術情景:
把log4j生成的日志文件定時刷進MySQL數據庫,比如三個小時刷一次,那么每次刷數據的時候,如何控制文件讀取是從上一次文件讀取結束的地方開始繼續讀取的?並且本次要讀取到文件結尾處。在網上各種搜索提問后,找到了一個叫RandomAccessFile Java類解決了問題。
static int size=1;//主要是為了控制循環的次數,因為是定時刷,每次刷的文件行數可能不一樣 static long chars=0;//chars指的是字符數 /** * 讀取文件內容 * @param fileName */ public Map readANDwrite(String fileName) { //大集合,以sessionid為鍵,以一次session的所有訪問記錄list為值進行存儲 Map<String,Map> bigMap = new HashMap(); //一次session的訪問記錄集合 File file = new File(fileName); //java提供的一個可以分頁讀取文件的類,此類的實例支持對隨機訪問文件的讀取和寫入 RandomAccessFile rf = null; String tempString = null; try { //初始化RandomAccessFile,參數一個為文件路徑,一個為權限設置,這點與Linux類似,r為讀,w為寫 rf = new RandomAccessFile(fileName, "rw"); //設置到此文件開頭測量到的文件指針偏移量,在該位置發生下一個讀取或寫入操作 rf.seek(chars); //獲取文件的行數 int fileSize = getTotalLines(file); for (int i = size-1; i < fileSize; i++) {//從上一次讀取結束時的文件行數到本次讀取文件時的總行數中間的這個差數就是循環次數 //一行一行讀取 tempString = rf.readLine(); //文件中文亂碼處理 tempString = tempString.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); tempString = tempString.replaceAll("\\+", "%2B"); tempString = java.net.URLDecoder.decode(tempString, "GB2312"); //將字符串JSON轉換為實體JSON,以便能通過key取value JSONObject json = JSONObject.fromObject(tempString); String refPage = json.get("refPage").toString(); System.out.println(refPage); Map tmap = new HashMap(); if (bigMap.containsKey(refPage)) tmap = (Map) bigMap.get(refPage); else { tmap = new HashMap(); } // 計數 String tCount = "count"; int pvCount = 1; if (tmap.containsKey(tCount)) { pvCount = (Integer) tmap.get(tCount); } pvCount++; tmap.put(tCount, pvCount); bigMap.put(refPage, tmap); } //返回此文件中的當前偏移量。 chars = rf.getFilePointer(); size=fileSize; } catch (IOException e) { e.printStackTrace(); }catch(JSONException j){ } finally { if (rf != null) { try { rf.close(); } catch (IOException e1) { } } } return bigMap; } //獲取文件的行數 static int getTotalLines(File file) throws IOException { FileReader in = new FileReader(file); LineNumberReader reader = new LineNumberReader(in); String s = reader.readLine(); int lines = 0; while (s != null) { lines++; s = reader.readLine(); } reader.close(); in.close(); return lines; }
