成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java IO (三) 讀取其他進(jìn)程數(shù)據(jù),RandomAccessFile,序列化和反序列化

zhangfaliang / 1097人閱讀

摘要:虛擬機(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文件.

RandomAccessFile

RandomAccessFile是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方法,用法和OutputStreamwrite方法完全一樣.此外還包含系列的readXXXwriteXXX方法來完成輸入/輸出.

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

相關(guān)文章

  • Java 輸入/輸出 I/O流 RandomAccessFile

    摘要:當(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...

    Eirunye 評(píng)論0 收藏0
  • Java編程基礎(chǔ)23——IO(其他流)&Properties

    摘要:但它融合了和的功能。支持對(duì)隨機(jī)訪問文件的讀取和寫入。的概述和作為集合的使用了解的概述類表示了一個(gè)持久的屬性集。可保存在流中或從流中加載。屬性列表中每個(gè)鍵及其對(duì)應(yīng)值都是一個(gè)字符串。 1_序列流(了解) 1.什么是序列流 序列流可以把多個(gè)字節(jié)輸入流整合成一個(gè), 從序列流中讀取數(shù)據(jù)時(shí), 將從被整合的第一個(gè)流開始讀, 讀完一個(gè)之后繼續(xù)讀第二個(gè), 以此類推. 2.使用方式 整合兩個(gè): S...

    vvpale 評(píng)論0 收藏0
  • Java 列化和反列化

    摘要:把字節(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) 把...

    jcc 評(píng)論0 收藏0
  • Java 列化與反列化

    摘要:一序列化和反序列化的概念把對(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é)序列永久地保...

    I_Am 評(píng)論0 收藏0
  • Flink 源碼解析 —— 深度解析 Flink 是如何管理好內(nèi)存的?

    摘要:減少垃圾收集壓力因?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ù)集的開源系...

    Edison 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<