• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      Java調(diào)用DLL實(shí)現(xiàn)讀寫磁盤扇區(qū)

      2013-07-03 00:45:06張美玲
      關(guān)鍵詞:磁盤扇區(qū)指針

      張美玲,張 剛

      (太原理工大學(xué) 信息工程學(xué)院,山西 太原 030024)

      0 引 言

      Java是一種面向?qū)ο蟮木幊陶Z(yǔ)言,它雖然具有語(yǔ)法簡(jiǎn)單,面向?qū)ο螅€(wěn)定,可移植性高等優(yōu)點(diǎn),但Java[1]以其跨平臺(tái)的目的,使得它不能像其它語(yǔ)言(如C和匯編)那樣更接近操作系統(tǒng),和本地機(jī)器的各種內(nèi)部聯(lián)系變得很少,也就不能和操作系統(tǒng)的底層打交道了。為了解決Java與底層的交互,本文引入JNI技術(shù),通過(guò)Java對(duì)本地方法的調(diào)用,實(shí)現(xiàn)應(yīng)用層對(duì)磁盤的直接操作。JNI的提出主要有以下幾個(gè)原因[2-3]:第一,當(dāng)標(biāo)準(zhǔn)的java的類庫(kù)不支持程序所需特性時(shí),可以用其它語(yǔ)言實(shí)現(xiàn)的接口。第二,需要用底層語(yǔ)言實(shí)現(xiàn)一個(gè)小型的時(shí)間敏感代碼時(shí),考慮到j(luò)ava運(yùn)行速度要比C/C++慢,需要引入JNI。第三,已經(jīng)有了一個(gè)用其他語(yǔ)言寫成的庫(kù)或程序時(shí),可以用java直接來(lái)調(diào)用,減少工作量。本文是基于java的類庫(kù)不支持程序所需特性的原因,用C++編寫讀寫扇區(qū)本地代碼并生成DLL[4](WINDOWS平臺(tái)下是.DLL 文件,Linux平臺(tái)下是.SO 文件)文件。雖然在DOS環(huán)境下,通過(guò)中斷或IO[5]可以直接對(duì)硬盤進(jìn)行操縱,因?yàn)锽IOS和DOS系統(tǒng)為磁盤操作提供了INT13H 中斷,通過(guò)INT13H的讀寫功能可以實(shí)現(xiàn)磁盤的直接讀寫。但在Windows環(huán)境下,Win32系統(tǒng)禁止應(yīng)用程序?qū)τ脖P直接操縱,禁止使用BIOS 中斷。所以,Windows操作系統(tǒng)下,在應(yīng)用層直接讀取硬盤扇區(qū)變的困難。但并不意味著在windows環(huán)境下無(wú)法訪問(wèn)硬盤。它在采取了“實(shí)保護(hù)”的同時(shí),也提供了一些API函數(shù),本文通過(guò)ReadFile()和WriteFile()函數(shù),以扇區(qū)存取的方式在本地代碼中實(shí)現(xiàn)讀寫扇區(qū),最后通過(guò)JNI方法實(shí)現(xiàn)了java對(duì)磁盤扇區(qū)的讀寫操作。

      1 JNI技術(shù)原理及實(shí)現(xiàn)流程

      1.1 JNI技術(shù)原理

      目前java與dll交互的技術(shù)主要有3種:jni,jawin和jacob。JNI是sun公司提供的java與系統(tǒng)中的原生方法交互的技術(shù)(在windows\linux 系統(tǒng)中,本文是基于windows平臺(tái)),它是JDK的一部分,提供了java與本地非java語(yǔ)言代碼的接口,通過(guò)使用JNI編寫的程序才能夠確保代碼移植到所有的平臺(tái)。該平臺(tái)相關(guān)代碼是通過(guò)JNI函數(shù)來(lái)訪問(wèn)Java虛擬機(jī)功能的,而JNI函數(shù)需要通過(guò)第一個(gè)接口指針JINEnv*[6]獲取。接口指針是指針的指針,它先指向一個(gè)JNI函數(shù)指針數(shù)組,而指針數(shù)組中每個(gè)元素又指向JNI接口函數(shù)。需要注意的是,本地方法將JNI接口指針當(dāng)做參數(shù)來(lái)傳遞,所以在一個(gè)線程中對(duì)本地方法的多次調(diào)用,需要保證接口指針是相同的。但是,如果一個(gè)方法被不同的線程調(diào)用,需要不同的JNI接口指針。以下是JNI原理圖,如圖1所示。

      圖1 JNI原理

      1.2 實(shí)現(xiàn)步驟

      JNI實(shí)現(xiàn)的最終目標(biāo)是要通過(guò)編寫頭文件及本地程序,結(jié)合C/C++文件生成動(dòng)態(tài)庫(kù)文件,最后加載到j(luò)ava程序運(yùn)行成功。具體實(shí)現(xiàn)步驟[7]如圖2所示。

      圖2 JNI實(shí)現(xiàn)步驟

      下面結(jié)合實(shí)例具體分析JNI調(diào)用過(guò)程。

      2 應(yīng)用實(shí)例

      該實(shí)例結(jié)合結(jié)合java對(duì)dll文件調(diào)用方法,在VC++中編寫本地代碼,并編譯生成.dll文件,通過(guò)并java 對(duì).dll文件調(diào)用,實(shí)現(xiàn)了java對(duì)磁盤扇區(qū)的直接讀寫。以下是VC++中實(shí)現(xiàn)讀寫扇區(qū)基本原理以及java實(shí)現(xiàn)讀寫扇區(qū)的基本步驟。

      2.1 VC++讀寫扇區(qū)實(shí)現(xiàn)原理[8]

      首先,使用CreateFile函數(shù)打開(kāi)磁盤驅(qū)動(dòng),指定所要操作磁盤并設(shè)置讀或?qū)懖僮鳎摵瘮?shù)參數(shù)設(shè)置如下:

      打開(kāi)的文件名參數(shù)設(shè)置:對(duì)于讀寫扇區(qū),如果訪問(wèn)的是具體某個(gè)邏輯分區(qū),則文件名格式為“\\.\X”,如果訪問(wèn)的是第一個(gè)邏輯硬盤,則文件名格式為“\\.\PHYSICALDRIVE0”;文件的操作屬性設(shè)置:允許讀設(shè)備操作設(shè)置為GENERIC_READ,允許寫設(shè)備操作設(shè)置為GENERIC_WRITE;文件共享屬性設(shè)置:FILE_SHARE_READ和FILE_SHARE_WRITE分別表示允許對(duì)設(shè)備進(jìn)行讀共享訪問(wèn)和寫共享訪問(wèn);文件操作設(shè)置為OPEN_EXISTING,對(duì)于該設(shè)置文件必須已經(jīng)存在,由設(shè)備提出要求,若該文件不存在,則函數(shù)調(diào)用失敗。

      其次,因?yàn)樗x的是磁盤中某個(gè)扇區(qū),而打開(kāi)的是整個(gè)磁盤,所以要通過(guò)SetFilePointer函數(shù)設(shè)置文件指針到磁盤中所要操作的某個(gè)扇區(qū)位置,CreateFile函數(shù)參數(shù)設(shè)置如下:

      其中文件句柄是CreateFile函數(shù)所返回的句柄,如果該句柄值表示磁盤打開(kāi)成功,則通過(guò)設(shè)置字節(jié)偏移量將指針指定到所要操作扇區(qū),對(duì)于讀寫扇區(qū)操作,將字節(jié)偏移量設(shè)置為指針移動(dòng)的字節(jié)數(shù);文件定位設(shè)置為FILE_BEGIN,即從文件開(kāi)始為參考位置進(jìn)行讀寫。

      接著,就可以利用ReadFile和WriteFile從指定位置讀寫扇區(qū),該函數(shù)由五個(gè)參數(shù)組成,參數(shù)設(shè)置如下:

      第一個(gè)參數(shù)為文件句柄,同上。第二個(gè)參數(shù)為緩沖區(qū),表示用于保存讀/寫入數(shù)據(jù)的一個(gè)緩沖區(qū)。第三個(gè)參數(shù)為要讀或?qū)懭氲淖址麛?shù),此處設(shè)置為從文件中讀或?qū)懭氲臄?shù)據(jù)字節(jié)數(shù)。第四個(gè)參數(shù)為從文件中實(shí)際讀或?qū)懭氲淖止?jié)數(shù)的指針。第五個(gè)參數(shù)設(shè)為NULL。

      最后,完成訪問(wèn)操作后,如果讀或?qū)懮葏^(qū)失敗,顯示錯(cuò)誤信息;如果讀或?qū)懮葏^(qū)成功,則用CloseHandle()函數(shù)關(guān)閉文件句柄,從而完成一次完整的磁盤扇區(qū)讀寫操作訪問(wèn),具體操作流程如圖3所示。

      圖3 流程

      2.2 具體實(shí)現(xiàn)步驟

      以上是在VC++環(huán)境下實(shí)現(xiàn)讀寫扇區(qū)的方法,而要想在應(yīng)用層實(shí)現(xiàn)底層磁盤的操作,需要通過(guò)java來(lái)對(duì)本地方法進(jìn)行調(diào)用,下面以磁盤數(shù)據(jù)讀寫為例,先在磁盤中寫入數(shù)據(jù),再通過(guò)讀扇區(qū)的方式讀取磁盤信息,分析了dll文件的生成以及java對(duì)其的調(diào)用過(guò)程,具體流程如下[9-10]

      (1)建立Java工程writesector和readsector,分別在Writesector.java和Readsector.java中聲明本地方法。

      public native boolean writeSector(long StartSector,int data);

      public native boolean readSector(long StartSector);

      定義了方法writeSector和readSector,參數(shù)StartSector,類型為long,表示所讀或?qū)懮葏^(qū)號(hào),這里是邏輯扇區(qū)號(hào),此參數(shù)用來(lái)在設(shè)置文件指針位置時(shí)指定到所要讀或?qū)懙纳葏^(qū)。data表示寫入扇區(qū)中數(shù)據(jù)。返回參數(shù)類型均為布爾類型。由于Java和C的編碼方式不同,所以JNI技術(shù)最關(guān)鍵部分就是參數(shù)的傳遞,即將本地代碼中的參數(shù)轉(zhuǎn)換為java可調(diào)用的參數(shù)類型,JNI數(shù)據(jù)類型映射見(jiàn)表1。

      表1 JNI數(shù)據(jù)類型映射

      native關(guān)鍵字作用:聲明本地化方法。它告訴Java 編譯器,方法是用Java類之外的本機(jī)代碼實(shí)現(xiàn)的,不需要用Java代碼具體實(shí)現(xiàn),但其聲明卻在Java中。

      (2)加載動(dòng)態(tài)庫(kù)

      Writesector.java和Readsector.java中分別加載write-sector1和readsector1文件。Load關(guān)鍵字:聲明的本地方法沒(méi)有實(shí)現(xiàn),但是我們?cè)谙旅婢椭苯邮褂昧?,所以必須在使用之前?duì)它進(jìn)行初始化。這里一般是以static塊進(jìn)行加載的。其中“writesector1”和“readsector1”是動(dòng)態(tài)庫(kù)的名字,Java通過(guò)調(diào)用這個(gè)中介Dll中的writeSector和readSector方法,間接調(diào)用真正的第三方Dll。

      (3)編譯生成Writesector.class和Readsector.class文件。

      (4)運(yùn)用.class文件生成.h頭文件。

      (5)用VC6.0編寫生成dll文件。下面以讀文件為例分析生成dll文件過(guò)程。

      第1步:在VC++下新建一個(gè)Win32Dynamic-Link Library類型的工程,取名readsector1,其中readsector1就是將來(lái)要生成的dll文件名,這樣命名方便java 對(duì)其直接調(diào)用。

      第2步:將頭文件readsector_Readsector.h、jni.h和jni_md.h 添加到工程中去,其中jni.h和jni_md.h這兩個(gè)文件可以在jdk1.6的include目錄下找到。

      第3步:編寫readsector.cpp實(shí)現(xiàn)readSector函數(shù)。

      JNIEXPORT jboolean JNICALL Java_readsector_Readsector_readSector(JNIEnv*env,jobject obj,jlong StartSector)

      其中JNIEnv* 是一個(gè)指向函數(shù)指針表的指針,這些函數(shù)提供各種用來(lái)在C++中操作Java數(shù)據(jù)的能力。jobject是指向在此Java代碼中實(shí)例化的Java 對(duì)象的一個(gè)句柄。jlong和jboolean分別對(duì)應(yīng)Java 中輸入函數(shù)類型和輸出類型。

      JNIEXPORT和JNICALL 都是JNI的關(guān)鍵字JNIEXPORT 表示函數(shù)的鏈接方式,當(dāng)程序執(zhí)行時(shí)從本地庫(kù)文件中找函數(shù),JNICALL 表示調(diào)用約定,說(shuō)明調(diào)用的是本地方法。

      以下是readSector函數(shù)中的主要部分:

      第4步:使用VC++編譯器編譯.cpp,生成readsector1.dll文件。

      3 代碼測(cè)試及結(jié)果輸出

      (1)在Writesector.java中輸入測(cè)試代碼:

      Writesector sample=new Writesector();

      boolean bool=sample.writeSector(2149033,0xBB);

      System.out.println("writeSector:"+bool);

      為了方便測(cè)試,在邏輯扇區(qū)號(hào)為2149033的扇區(qū)中輸入同一個(gè)數(shù)值0xbb。

      在Readsector.java中輸入測(cè)試代碼:

      Readsector sample=new Readsector();

      boolean bool=sample.readSector(2149033);

      System.out.println("readSector:"+bool);

      為了檢驗(yàn)寫扇區(qū)的正確性,檢驗(yàn)邏輯扇區(qū)號(hào)為2149033的扇區(qū)值是否正確。

      (2)將readsector1.dll拷貝到Readsector.java所在的目錄下,將writesector1.dll拷貝到Writesector.java 所在的目錄下。

      (3)運(yùn)行Writesector.java,實(shí)現(xiàn)寫扇區(qū),輸出結(jié)果如圖4所示。

      圖4 讀扇區(qū)

      再運(yùn)行Readsector.java,讀取所寫入扇區(qū)值。輸出結(jié)果如圖5所示。

      圖5 寫扇區(qū)

      4 Java調(diào)用本地方法準(zhǔn)則及缺點(diǎn)

      4.1 Java調(diào)用本地方法的準(zhǔn)則

      Java所調(diào)用的本地方法是指包含在特定平臺(tái)下的可執(zhí)行文件中,就本文示例而言,本地方法即包含在windows平臺(tái)下的動(dòng)態(tài)鏈接庫(kù)DLL中。在java對(duì)本地方法的實(shí)際調(diào)用過(guò)程中,需考慮一下兩個(gè)準(zhǔn)則:

      (1)當(dāng)本地代碼有多個(gè)方法時(shí),可以將這些本地方法都封裝到單個(gè)類中,這個(gè)類只需要調(diào)用一個(gè)DLL,即可實(shí)現(xiàn)對(duì)本地代碼的調(diào)用。對(duì)于每種目標(biāo)操作系統(tǒng),只需要修改基于該平臺(tái)的本地代碼來(lái)替換DLL,這就將本地代碼的影響減小對(duì)最小,也有助于不同平臺(tái)下的一直問(wèn)題。

      (2)本地方法要簡(jiǎn)單。目的要使第三方運(yùn)行時(shí)對(duì)DLL依賴程度減到最小,從而使本地方法更加獨(dú)立,減小加載DLL和應(yīng)用程序的開(kāi)銷。

      4.2 Java調(diào)用本地方法的缺點(diǎn)

      (1)Java作為一種面向?qū)ο蟮木幊陶Z(yǔ)言,雖然具有跨平臺(tái)等優(yōu)點(diǎn),但JNI方法在實(shí)現(xiàn)java與本地代碼交互的同時(shí)也限制了java語(yǔ)言的一個(gè)優(yōu)點(diǎn):程序的可移植性。java調(diào)用本地方法時(shí),需要本地代碼為其提供動(dòng)態(tài)鏈接庫(kù),而鏈接庫(kù)本身是與平臺(tái)相關(guān)的。

      (2)JNI方法使程序的安全性降低。JVM 給Java代碼提供了完善的安全機(jī)制使得Java代碼不會(huì)導(dǎo)致程序崩潰、濫用數(shù)據(jù)等,一旦使用了JNI,這種安全機(jī)制就無(wú)能力了。

      (3)必須確保本地代碼的穩(wěn)定性,因?yàn)楸镜卮a運(yùn)行時(shí)可能會(huì)造成錯(cuò)誤指針帶來(lái)的間接錯(cuò)誤,這樣本地代碼帶來(lái)的絲毫錯(cuò)誤都可能導(dǎo)致java虛擬機(jī)的崩潰[11]。

      5 結(jié)束語(yǔ)

      本文分析了基于windows平臺(tái)下用VC++實(shí)現(xiàn)磁盤扇區(qū)的讀寫方法之后,通過(guò)JNI技術(shù)實(shí)現(xiàn)了java對(duì)VC++下生成的dll文件的調(diào)用,從而完成應(yīng)用層對(duì)磁盤的直接訪問(wèn),實(shí)現(xiàn)了java對(duì)系統(tǒng)底層的直接操作。由于java標(biāo)準(zhǔn)的類庫(kù)無(wú)法支持與硬件的交互,這就受限了JNI方法的使用。而JNI方法在

      實(shí)現(xiàn)java與本地代碼雙向交互的同時(shí),使得程序本身喪失了跨平臺(tái)的優(yōu)點(diǎn)。所以,在使用JNI方法之前,一定要審查是否有更好的方法結(jié)合到j(luò)ava中。本文是在windows平臺(tái)實(shí)現(xiàn)了對(duì)系統(tǒng)底層的一些操作,如果想要跨平臺(tái)實(shí)現(xiàn),這就要求在不同的操作系統(tǒng)下重新編譯本地代碼,通過(guò)使用JNI技術(shù)可以實(shí)現(xiàn)更為廣泛的應(yīng)用層與底層之間的交互,有待進(jìn)一步研究。

      [1]Eckel.Thinking in java 4[M].Beijing:Publishing House of Electronics Industry,2011(in Chinese).[??藸?java編程思想第四版[M].北京:電子工業(yè)出版社,2011.]

      [2]WANG Jundi,ZHAO Kai.Study of JNI technology applied in software development[J].Journal of Lanzhou Polytechnic College,2009,16(5):15-17(in Chinese).[王軍弟,趙愷.JNI技術(shù)在軟件開(kāi)發(fā)中的應(yīng)用研究[J].蘭州工業(yè)高等??茖W(xué)校學(xué)報(bào),2009,16(5):15-17.]

      [3]GAO Jing,WANG Jianhua.The application of jni technique in the built-in software development[J].Natural Science Journal of Harbin Normal University,2007,23(6):62-65(in Chinese).[高晶,王建華.JNI技術(shù)在嵌入式軟件開(kāi)發(fā)中的應(yīng)用[J].哈爾濱師范大學(xué)自然科學(xué)學(xué)報(bào),2007,23(6):62-65.]

      [4]MA Liyan,ZHANG Chunfang,LI Ruitai,et al.Empoldering database DLL program in the environment of delphi[J].Journal of Hebei Normal University(Natural Science Edition,2007,31(2):173-175(in Chinese).[馬麗艷,張春芳,李瑞臺(tái),等.用Delphi開(kāi)發(fā)數(shù)據(jù)庫(kù)應(yīng)用功能的DLL 程序[J].河北師范大學(xué)學(xué)報(bào)(自然科學(xué)版),2007,31(2):173-175.]

      [5]CHEN Jie,ZHANG Wei,ZHANG Shunsheng.Design and implementation of SATA2.0controller[J].Journal of Computer Applications,2011,31(S1):25-26(in Chinese).[陳杰,張偉,張順生.SATA2.0 控制器的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用,2011,31(S1):25-26.]

      [6]LIU Yingming,LI Ning,ZHANG Ling,et al.Using JNI to establish communication between Java and C++[J].Computer Era,2010,31(6):980-984(in Chinese).[劉英明,李寧,張玲,等.基于JNI技術(shù)C++測(cè)井應(yīng)用程序集成方法[J].石油學(xué)報(bào),2010,31(6):980-984.]

      [7]AN Baijun,GAO Dong,ZHANG Wei,et al.Java native method calls[J].Microprocessors,2011,2(2):40-44(in Chi-nese).[安百俊,高棟,張偉,等.通過(guò)Java 調(diào)用本地方法[J].微處理機(jī),2011,2(2):40-44.]

      [8]WANG Hong.Read floppy disk sector for Windows[J].Computer Knowledge and Technology,2009,5(24):6791-6793(in Chinese).[汪虹.Windows下直接讀取軟盤扇區(qū)[J].電腦知識(shí)與技術(shù),2009,5(24):6791-6793.]

      [9]GUO Liquan,XIE Weibo.Design and realization of video intercom system based on Andriod[J].Microcomputer &Its Applications,2012,31(5):4-7(in Chinese).[郭利全,謝維波.基于Android平臺(tái)的可視對(duì)講系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].微型機(jī)與應(yīng)用,2012,31(5):4-7.]

      [10]ZHANG Miaomiao,XING Jianchun,YANG Qihang.Method and implementation of call on configuration software database based on jni technology[J].Industrial Control Computer,2011,24(9):3-5(in Chinese).[張淼淼,邢建春,楊啟亮.基于JNI技術(shù)的組態(tài)軟件數(shù)據(jù)庫(kù)訪問(wèn)方法及應(yīng)用[J].工業(yè)控制計(jì)算機(jī),2011,24(9):3-5.]

      [11]HUANG Yanfeng,WANG Jianpin.Comparisons between Java and C++programming language on security[J].Sichuan University of Arts and Science Journal(Natural Science Edition),2007,17(2):53-54(in Chinese).[黃艷峰,王建品.Java與C++在安全性方面的比較[J].四川文理學(xué)院學(xué)報(bào)(自然科學(xué)版),2007,17(2):53-54.]

      猜你喜歡
      磁盤扇區(qū)指針
      分階段調(diào)整增加扇區(qū)通行能力策略
      南北橋(2022年2期)2022-05-31 04:28:07
      解決Windows磁盤簽名沖突
      偷指針的人
      修改磁盤屬性
      U盤故障排除經(jīng)驗(yàn)談
      為什么表的指針都按照順時(shí)針?lè)较蜣D(zhuǎn)動(dòng)
      磁盤組群組及iSCSI Target設(shè)置
      創(chuàng)建VSAN群集
      基于貝葉斯估計(jì)的短時(shí)空域扇區(qū)交通流量預(yù)測(cè)
      重建分區(qū)表與FAT32_DBR研究與實(shí)現(xiàn)
      阆中市| 怀柔区| 当阳市| 全州县| 莫力| 安岳县| 吴忠市| 江华| 高邑县| 武强县| 徐州市| 卢龙县| 洪洞县| 东宁县| 阿城市| 舒兰市| 珲春市| 惠来县| 永定县| 固镇县| 黑河市| 铁岭县| 遵化市| 龙山县| 麻城市| 苍山县| 溧阳市| 克拉玛依市| 从江县| 旌德县| 锡林郭勒盟| 皮山县| 岳阳市| 天祝| 岳阳县| 宜州市| 凉城县| 佛冈县| 平遥县| 许昌市| 剑河县|