摘要:虛擬機(jī)讀取其他進(jìn)程的數(shù)據(jù)對(duì)象的方法可以運(yùn)行平臺(tái)上的其他程序該方法產(chǎn)生一個(gè)對(duì)象對(duì)象代表由該程序啟動(dòng)啟動(dòng)的子進(jìn)程類提供如下三個(gè)方法用于和其子進(jìn)程通信獲取子進(jìn)程的錯(cuò)誤流獲取子進(jìn)程的輸入流獲取子進(jìn)程的輸出流這里的輸入流輸出流容易混淆從程序的角度思考
Java虛擬機(jī)讀取其他進(jìn)程的數(shù)據(jù)
Runtime對(duì)象的exec方法可以運(yùn)行平臺(tái)上的其他程序,該方法產(chǎn)生一個(gè)Process對(duì)象,Process對(duì)象代表由該Java程序啟動(dòng)啟動(dòng)的子進(jìn)程,Process類提供如下三個(gè)方法,用于和其子進(jìn)程通信:
InputStream getErrorStream() 獲取子進(jìn)程的錯(cuò)誤流
InputStream getInputStream() 獲取子進(jìn)程的輸入流
OutputStream getOutputStream() 獲取子進(jìn)程的輸出流
這里的輸入流輸出流容易混淆.從程序的角度思考,子進(jìn)程讀取程序的數(shù)據(jù),為輸出流.子進(jìn)程讀取數(shù)據(jù),是讓程序把數(shù)據(jù)輸出到子進(jìn)程中.
java//省略代碼 Process p = Runtime.getRuntime().exec("javac"); BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream(),"GBK")); String buff; while ((buff = br.readLine()) != null ) { System.out.println(buff); } //省略代碼
上面程序使用Runtime啟動(dòng)javac,獲取了運(yùn)行該程序相應(yīng)的子進(jìn)程.
javapublic class WriteToProcess { public static void main(String[] args) { PrintStream ps = null; try { //返回運(yùn)行該命令的子進(jìn)程 Process p = Runtime.getRuntime().exec("java ReadStand"); //p進(jìn)程的輸出流創(chuàng)建PrintStream對(duì)象 //對(duì)本程序是輸出流,對(duì)p進(jìn)程則是輸入流 ps = new PrintStream(p.getOutputStream()); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String content; while ((content = br.readLine()) != null) { System.out.println(content); } ps.println("普通字符串"); ps.println(new WriteToProcess()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (null != ps) { ps.close(); } } } } class ReadStand { public static void main(String[] args) { PrintStream ps = null; Scanner sc = new Scanner(System.in); try { ps = new PrintStream("src estout.txt"); sc.useDelimiter(" "); while (sc.hasNext()) { ps.print("鍵盤輸入的內(nèi)容是:" + sc.next()); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { sc.close(); ps.close(); } } }
上面的程序,運(yùn)行結(jié)束產(chǎn)生了一個(gè)out.txt文件,該文件由ReadStand產(chǎn)生,該文件的內(nèi)容由WriteToProcess類寫入到ReadStan進(jìn)程里,并由ReadStand讀取這些數(shù)據(jù),并把數(shù)據(jù)保存在out.txt文件.
RandomAccessFileRandomAccessFile是Java輸入/輸出流中功能最豐富的文件內(nèi)容訪問類,提供了眾多方法來訪問文件,既可以支持讀取內(nèi)容,也可以向文件輸出數(shù)據(jù).與普通的輸入/輸出流不同的是,RandomAccessFile支持"隨機(jī)訪問"的方式,程序可以直接跳轉(zhuǎn)到文件的任意位置來讀寫數(shù)據(jù).
計(jì)算機(jī)中"隨機(jī)訪問"是由Random Access兩個(gè)單詞單詞翻譯而來.Random不僅有隨機(jī)的意思,還有任意的意思.如果
能這樣理解Random,可以更好的理解Random Access:任意訪問,也就是說可以自由訪問任意存儲(chǔ)點(diǎn)的存儲(chǔ)器(與磁盤,
磁帶等需要尋道,倒帶才可訪問存儲(chǔ)點(diǎn)的存儲(chǔ)器區(qū)分);而RandomAccessFile的含義是可以自由訪問文件的任意地方(與
InputStream,Reader依次向后讀取區(qū)分).
RandomAccessFile可以自由訪問文件的任意位置,所以如果只希望訪問文件的部分內(nèi)容,RandomAccessFile是更好的選擇.
RandomAccessFile允許自由定位文件記錄指針,所以RandomAccessFile不用從開始地方輸出,所以可以向已存在的文件后追加內(nèi)容.
RandomAccessFile對(duì)象包含了一個(gè)記錄指針,用以標(biāo)識(shí)當(dāng)前讀寫處的位置,當(dāng)程序創(chuàng)建一個(gè)新的RandomAccessFile對(duì)象時(shí),該對(duì)象的的文件記錄指針位于文件頭(0處),讀寫了n個(gè)字節(jié)后文件記錄指針將會(huì)移動(dòng)n個(gè)字節(jié),除此之外,RandomAccessFile可以自由移動(dòng)記錄指針,可以向前/向后移動(dòng).包含兩個(gè)方法來操作文件記錄指針:
void getFilepointer() 返回文件記錄指針的當(dāng)前位置
void seek(long pos) 將文件記錄指針定位到pos位置
RandomAccessFile既可以讀文件又能寫文件,包含了類似于InputStream的三個(gè)Read方法,用法和InputStream的三個(gè)read方法完全一樣.也包含了OutputStream的三個(gè)write方法,用法和OutputStream的write方法完全一樣.此外還包含系列的readXXX和writeXXX方法來完成輸入/輸出.
RandomAccessFile類有兩個(gè)構(gòu)造器,基本相同,區(qū)別在于指定的文件形式不同.一個(gè)使用String來制定文件名,一個(gè)使用File參數(shù)來制定文件本身,之外創(chuàng)建RandomAccessFile對(duì)象還需要制定一個(gè)mode參數(shù),該參數(shù)指定RandomAccessFile的訪問模式,有如下四個(gè)值:
"r" 以只讀的方式打開指定文件.如試圖對(duì)該RandomAccessFile指定寫入操作會(huì)拋出IOException.
"rw" 以讀取,寫入的方式打開指定文件.如果該文件不存在,則嘗試創(chuàng)建該文件.
"rws" 以讀取,寫入的方式打開指定文件.相對(duì)于"rw"模式,還要求對(duì)文件的元數(shù)據(jù)或內(nèi)容的每個(gè)更新都同步到底層存儲(chǔ)設(shè)備.
"rwd" 以讀取,寫入的方式打開指定文件,對(duì)于"rw",還要求對(duì)文件內(nèi)容的每個(gè)更新都同步寫入底層存儲(chǔ)設(shè)備.
//省略代碼 RandomAccessFile raf = null; //省略代碼 try { raf = new RandomAccessFile("out.txt","rw"); raf.seek(raf.length()); raf.write("追加內(nèi)容 ".getBytes()); }
使用RandomAccessFile對(duì)指定文件指定位置插入內(nèi)容:
javapublic static void insert(String fileName,long pos,String insertContent) { RandomAccessFile raf = null; try { raf = new RandomAccessFile(fileName, "rw"); File tmpFile = File.createTempFile("temp", null); tmpFile.deleteOnExit(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpFile))); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(tmpFile))); //設(shè)置文件指針位置 raf.seek(pos); String content; /** * 將插入點(diǎn)內(nèi)容保存在臨時(shí)文件中 * 讀取插入點(diǎn)后所有文件內(nèi)容 */ while ((content = raf.readLine()) != null) { //將數(shù)據(jù)寫入臨時(shí)文件 bw.write(content); } bw.flush(); bw.close(); //重新設(shè)置指針位置 raf.seek(pos); //插入內(nèi)容 raf.write(insertContent.getBytes()); //追加臨時(shí)文件中內(nèi)容 while ((content = br.readLine()) != null) { raf.write(content.getBytes()); } br.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { raf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }對(duì)象的序列化和反序列化
對(duì)象序列化是將對(duì)象保存在磁盤中,或允許在網(wǎng)絡(luò)中直接傳輸對(duì)象,對(duì)象序列化機(jī)制允許把內(nèi)存中的Java對(duì)象轉(zhuǎn)換平臺(tái)無關(guān)的二進(jìn)制流,從而允許把這種二進(jìn)制流持久保存在磁盤上,通過網(wǎng)絡(luò)將這種二進(jìn)制流傳輸?shù)搅硪粋€(gè)網(wǎng)絡(luò)節(jié)點(diǎn).其他程序獲得了這種二進(jìn)制流,都可以將這種二進(jìn)制流恢復(fù)成原來的Java對(duì)象.
序列化的含義和意義序列化機(jī)制允許將實(shí)現(xiàn)序列化的Java對(duì)象轉(zhuǎn)換為字節(jié)序列,這些字節(jié)序列可以被保存在磁盤上,或通過網(wǎng)絡(luò)傳輸,以備以后重新恢復(fù)成原來的對(duì)象,序列化機(jī)制使得對(duì)象可以脫離程序的運(yùn)行獨(dú)立存在.
對(duì)象的序列化(Serialize)指將一個(gè)Java對(duì)象寫入IO流中,于此對(duì)應(yīng)的是,對(duì)象的反序列化(Deserialize)指從IO流中恢復(fù)該Java對(duì)象.
如果要讓某個(gè)對(duì)象可以支持序列化機(jī)制,必須它的類是可序列化的(Serialize).為了讓某個(gè)類可序列化,必須實(shí)現(xiàn)如下兩個(gè)接口之一:
Serializable
Externalizable
Serializable是一個(gè)標(biāo)記接口,該接口無需實(shí)現(xiàn)任何方法,只是表明該類是可序列化的.所有可能在網(wǎng)絡(luò)上傳輸?shù)膶?duì)象的類都應(yīng)該是可序列化的,否則程序?qū)?huì)出現(xiàn)異常.比如RMI(Remote Method Invoke,遠(yuǎn)程方法調(diào)用)過程中的參數(shù)和返回值;所有需要保存到磁盤的對(duì)象的類都必須是可序列化.如Web中需要保存到HttpSession和ServletContext屬性的Java對(duì)象.
通常建議,程序創(chuàng)建的每個(gè)JavaBean都實(shí)現(xiàn)Serializable接口.
序列化對(duì)象實(shí)例:
javapublic class ObjectOutputStreamTest { public static void main(String[] args) { ObjectOutputStream oos = null; try { //創(chuàng)建一個(gè)ObjectOutputStream輸出流 oos = new ObjectOutputStream(new FileOutputStream("src//io//person.txt")); Person p1 = new Person("swk", 20); //把對(duì)象寫入輸出流 oos.writeObject(p1); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if (null != oos) { oos.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public Person(String name,int age) { // TODO Auto-generated constructor stub System.out.println("Person 構(gòu)造函數(shù)"); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
從二進(jìn)制流中恢復(fù)Java對(duì)象:
java//省略代碼 ObjectInputStream ois = null; try { //創(chuàng)建ObjectInputStream輸入流 ois = new ObjectInputStream(new FileInputStream("src//io//person.txt")); //從流中讀取對(duì)象,并強(qiáng)制轉(zhuǎn)換為Person類型 Person p = (Person)ois.readObject(); System.out.println("Age:" + p.getAge() + ",name:" + p.getName()); } //省略代碼
反序列化讀取的只是Java對(duì)象的數(shù)據(jù),而不是Java類,因此采用反序列化恢復(fù)Java對(duì)象時(shí),必須提供Java對(duì)象所屬的class文件,否則引發(fā)ClassNotFoundException.
Person類只有一個(gè)有參數(shù)構(gòu)造器,并沒有無參數(shù)構(gòu)造器,而且構(gòu)造函數(shù)內(nèi)有打印語句.當(dāng)反序列化讀取Java對(duì)象時(shí),沒有看到程序調(diào)用該構(gòu)造器,這表明反序列化機(jī)制無需通過構(gòu)造器來初始化Java對(duì)象.
如果向文件中使用序列化多個(gè)Java對(duì)象,使用反序列化機(jī)制恢復(fù)時(shí),必須按實(shí)際寫入順序讀取.
程序創(chuàng)建子類實(shí)例時(shí),系統(tǒng)會(huì)隱式創(chuàng)建為它所有的父類都創(chuàng)建實(shí)例.反序列化某個(gè)子類的實(shí)例時(shí),反序列化機(jī)制需要恢復(fù)其關(guān)聯(lián)的父類實(shí)例,恢復(fù)這些父類實(shí)例有;兩種方式:
使用反序列化機(jī)制
使用父類無參數(shù)構(gòu)造器
在上面兩種方式中,反序列化機(jī)制優(yōu)先采用第一種機(jī)制.如果某個(gè)父類既不可序列化,則不能使用第一種機(jī)制;又沒有提供無參數(shù)構(gòu)造器,則不可采用第二種機(jī)制,反序列化該子類實(shí)例將拋出異常.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64414.html
摘要:當(dāng)使用節(jié)點(diǎn)流進(jìn)行輸入輸出時(shí),程序直接連接到實(shí)際的數(shù)據(jù)源,和時(shí)間的輸入輸出節(jié)點(diǎn)連接處理流則用于對(duì)一個(gè)已存在的流進(jìn)行連接或封裝,通過封裝后的流來實(shí)現(xiàn)數(shù)據(jù)讀寫功能,處理流也被稱為高級(jí)流。 文件的編碼 文本文件就是字節(jié)序列,可以是任意編碼形式。在中文操作系統(tǒng)上直接創(chuàng)建文本文件,則該文本文件只能識(shí)別ANSI編碼,其他編碼方式會(huì)產(chǎn)生亂碼 package imooc.io; import java...
摘要:但它融合了和的功能。支持對(duì)隨機(jī)訪問文件的讀取和寫入。的概述和作為集合的使用了解的概述類表示了一個(gè)持久的屬性集。可保存在流中或從流中加載。屬性列表中每個(gè)鍵及其對(duì)應(yīng)值都是一個(gè)字符串。 1_序列流(了解) 1.什么是序列流 序列流可以把多個(gè)字節(jié)輸入流整合成一個(gè), 從序列流中讀取數(shù)據(jù)時(shí), 將從被整合的第一個(gè)流開始讀, 讀完一個(gè)之后繼續(xù)讀第二個(gè), 以此類推. 2.使用方式 整合兩個(gè): S...
摘要:把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。代表對(duì)象輸入流,它的方法從一個(gè)源輸入流中讀取字節(jié)序列,再把它們反序列化為一個(gè)對(duì)象,并將其返回。接口繼承自接口,實(shí)現(xiàn)接口的類完全由自身來控制序列化的行為,而僅實(shí)現(xiàn)接口的類可以采用默認(rèn)的序列化方式。 把對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化。把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。 對(duì)象的序列化主要有兩種用途: 1) 把...
摘要:一序列化和反序列化的概念把對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。代表對(duì)象輸入流,它的方法從一個(gè)源輸入流中讀取字節(jié)序列,再把它們反序列化為一個(gè)對(duì)象,并將其返回。 一、序列化和反序列化的概念 把對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化;把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。 對(duì)象的序列化主要有兩種用途: 1) 把對(duì)象的字節(jié)序列永久地保...
摘要:減少垃圾收集壓力因?yàn)樗虚L(zhǎng)生命周期的數(shù)據(jù)都是在的管理內(nèi)存中以二進(jìn)制表示的,所以所有數(shù)據(jù)對(duì)象都是短暫的,甚至是可變的,并且可以重用。當(dāng)然,并不是唯一一個(gè)基于且對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行操作的數(shù)據(jù)處理系統(tǒng)。 showImg(https://segmentfault.com/img/remote/1460000020044119?w=1280&h=853); 前言 如今,許多用于分析大型數(shù)據(jù)集的開源系...
閱讀 2742·2021-11-22 13:54
閱讀 1082·2021-10-14 09:48
閱讀 2305·2021-09-08 09:35
閱讀 1569·2019-08-30 15:53
閱讀 1180·2019-08-30 13:14
閱讀 619·2019-08-30 13:09
閱讀 2533·2019-08-30 10:57
閱讀 3345·2019-08-29 13:18