大部分情況下,我們面對(duì)在兩個(gè)java進(jìn)程只見傳遞數(shù)據(jù)的問(wèn)題時(shí),第一個(gè)想到的就是開server,然后通過(guò)socket收發(fā)消息。這方面有大量的框架可用,就不細(xì)說(shuō)了。
但如果兩個(gè)進(jìn)程是在一臺(tái)機(jī)器上,那么還可以使用另一種方式來(lái)傳遞數(shù)據(jù),那就是使用RandomAccessFile的文件映射模式。
RandomAccessFile的map方法把文件映射到內(nèi)存中進(jìn)行快速讀寫。因此可以通過(guò)把消息包寫入到文件中,然后另一個(gè)進(jìn)程讀取出來(lái)的方式來(lái)完成數(shù)據(jù)傳遞。
在這個(gè)過(guò)程中,重點(diǎn)是要考慮什么時(shí)候?qū)懭胪瓿?,只有寫入完成后,讀取進(jìn)程才可以去讀數(shù)據(jù),否則就是錯(cuò)誤的數(shù)據(jù)。具體方案如下:
保留文件的首個(gè)byte作為標(biāo)志位,1表示A進(jìn)程寫入完畢,0表示B進(jìn)程讀取完畢。
步驟1:A進(jìn)程開始寫入時(shí),先跳過(guò)首字節(jié),然后將數(shù)據(jù)長(zhǎng)度,數(shù)據(jù)內(nèi)容寫入到文件。寫入完畢后,將文件的首字節(jié)置為1
步驟2:B進(jìn)程定時(shí)刷新文件到內(nèi)存中,讀取首字節(jié),如果是0則跳出,等待下次刷新。如果是1表示有新數(shù)據(jù),則加載。加載完畢后設(shè)置首字節(jié)為0.表示已經(jīng)讀取完畢。
步驟3:A進(jìn)程定時(shí)刷新文件到內(nèi)存,讀取首字節(jié),如果是0,表示可以寫入,繼續(xù)步驟1的流程。如果是1,則表示數(shù)據(jù)還沒(méi)被讀取,不可寫入。等待下次刷新。
經(jīng)過(guò)以上3個(gè)步驟,完成數(shù)據(jù)的進(jìn)程間傳遞。此模式也可以用于將數(shù)據(jù)傳遞到非java進(jìn)程。
代碼如下:
public class TestRandomAccessFile { private static String FileName="aa.a"; private static volatile Linux1 lx1; private static volatile Linux2 lx2; private static long from; private static void close(Closeable c){ try{ c.close(); }catch(IOException ie){ ie.printStackTrace(); } } public static class Linux1{ MappedByteBuffer buf; RandomAccessFile raf; public Linux1