代碼以下:數據庫
/** * m_indexFile \data\appdatas\cat\bucket\dump\20171204\10\cat-10.15.83.181-10.15.83.181.idx * @param block * @throws IOException * @description * 一、獲取block塊內樹的棵數,遍歷每一棵樹 * 二、按照 6B(前4B寫入整個block在dataFile中的其實位置,後2B寫每一棵樹在block內的偏移)寫索引文件 * 三、將block的長度,做爲一個int類型寫入到dataFile * 四、將block的data,接着寫入dataFile */ public synchronized void writeBlock(MessageBlock block) throws IOException { int len = block.getBlockSize();//塊內MessageTree的個數 byte[] data = block.getData();//塊內全部樹的字節 int blockSize = 0; //遍歷塊內每個樹,對應的index,和樹的size(字節) for (int i = 0; i < len; i++) { int seq = block.getIndex(i); int size = block.getSize(i); m_indexFile.seek(seq * 6L);//取6位,前4位是messageId的最後一個字段的index,後面是這個消息對應的size的偏移量 m_indexFile.writeInt(m_blockAddress);//這幾棵數的塊內地址是同樣的,可是,索引地址不同 m_indexFile.writeShort(blockSize);//塊內的偏移量 blockSize += size;//block的總大小,字節數 } m_dataFile.writeInt(data.length);//數據偏移的前面四個字節,是數據長度,接下來纔是消息自己 m_dataFile.write(data); m_blockAddress += data.length + 4;//偏移量+4個字節 }
代碼以下:app
/** * m_dataFile \data\appdatas\cat\bucket\dump\20171204\09\cat-10.15.83.181-10.15.83.181 * @param index * @return * @throws IOException * 讀邏輯: * 一、根據index找到索引文件的起始位置 * 二、讀6B,前4B是數據文件的數據庫的起始位置,後2B是MessageTree塊內的偏移地址 * 三、找到數據文件塊的起始地址,讀取一個int類型數據,這個是整個數據塊的長度 * 四、接着讀取這麼長的數據,即爲整個數據塊,對應MessageBlock * 五、在數據塊內,skip到MessageTree的塊內地址 * 六、讀取一個整型,這個整型即爲MessageTree的長度,接着讀出這棵消息樹 */ public byte[] readMessage(int index) throws IOException { int blockAddress = 0; int blockOffset = 0; byte[] buf; m_indexFile.seek(index * 6L); blockAddress = m_indexFile.readInt(); blockOffset = m_indexFile.readShort() & 0xFFFF; m_dataFile.seek(blockAddress); buf = new byte[m_dataFile.readInt()]; m_dataFile.readFully(buf); ByteArrayInputStream bais = new ByteArrayInputStream(buf); DataInputStream in = new DataInputStream(new GZIPInputStream(bais)); try { in.skip(blockOffset); int len = in.readInt(); byte[] data = new byte[len]; in.readFully(data); return data; } finally { try { in.close(); } catch (Exception e) { // ignore it } } }