IO流(操作文件內(nèi)容): 轉(zhuǎn)換流, 輸出/輸入字符流, 對(duì)象的序列化, 序列流, Properties, 打印流, 操作數(shù)組/基本數(shù)據(jù)類型的流對(duì)象

轉(zhuǎn)換流

  • 輸入字節(jié)流的轉(zhuǎn)換流:InputStreamReader 是字節(jié)流通向字符流的橋InputStreamReader
  • 輸出字節(jié)流的轉(zhuǎn)換流:OutputStreamWriter 可以把輸出字節(jié)流轉(zhuǎn)換成輸出字符流
  • 轉(zhuǎn)換流的作用:
    1. 如果目前所 獲取到的是一個(gè)字節(jié)流需要轉(zhuǎn)換字符流使用么伯,這時(shí)候就可以使用轉(zhuǎn)換流瓢省。 字節(jié)流----> 字符流
    2. 使用轉(zhuǎn)換流可以指定編碼表進(jìn)行讀寫文件线梗。
public class Demo{
    public static void main(String[] args) throws IOException {
//      readTest();
//      writeTest();'
        
//      writeTest2();
        readTest2();
      }
    
    //使用輸入字節(jié)流的轉(zhuǎn)換流指定碼表進(jìn)行讀取文件數(shù)據(jù)
    public static void readTest2() throws IOException{
        File file = new File("F:\\a.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        //創(chuàng)建字節(jié)流的轉(zhuǎn)換流并且指定碼表進(jìn)行讀取
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
        char[] buf = new char[1024];
        int length = 0;
        while((length = inputStreamReader.read(buf))!=-1){
            System.out.println(new String(buf,0,length));
        }   
    }
    
    //使用輸出字節(jié)流的轉(zhuǎn)換流指定碼表寫出數(shù)據(jù)
    public static void writeTest2() throws IOException{
        File file = new File("F:\\a.txt");
        //建立數(shù)據(jù)的輸出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //把輸出字節(jié)流轉(zhuǎn)換成字符流并且指定編碼表。
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "utf-8");
        outputStreamWriter.write("新中國(guó)好啊");
        //關(guān)閉資源
        outputStreamWriter.close(); 
    }
    
    public static void writeTest() throws IOException{
        File file = new File("F:\\a.txt");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //把輸出字節(jié)流轉(zhuǎn)換成輸出字符流淘菩。
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
        
        outputStreamWriter.write("大家好");
        outputStreamWriter.close();
    }
    
    
    public static void readTest() throws IOException{
        InputStream in = System.in; //獲取了標(biāo)準(zhǔn)的輸入流。
//      System.out.println("讀到 的字符:"+ (char)in.read());  //read()一次只能讀取一個(gè)字節(jié)削罩。
        //需要把字節(jié)流轉(zhuǎn)換成字符流瞄勾。
        InputStreamReader inputStreamReader = new InputStreamReader(in);
        //使用字符流的緩沖類
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = null;
        while((line = bufferedReader.readLine())!=null){
            System.out.println("內(nèi)容:"+ line);
        }
    }
}

輸入字符流

  • Reader 輸入字符流的基類抽象類

    • FileReader 讀取文件的輸入字符流
  • FileReader的用法:

    1. 找到目標(biāo)文件
    2. 建立數(shù)據(jù)的輸入通道
    3. 讀取數(shù)據(jù)
    4. 關(guān)閉資源
public class Demo {

   public static void main(String[] args) throws IOException {
       readTest2();
   }
   
   //使用緩沖字符數(shù)組讀取文件。
   public static void readTest2() throws IOException{
       //找到目標(biāo)文件
       File file = new File("F:\\my.java");
       // 建立數(shù)據(jù)的輸入通道
       FileReader fileReader = new FileReader(file);
       //建立緩沖字符數(shù)組讀取文件數(shù)據(jù)
       char[] buf = new char[1024];
       int length = 0 ; 
       while((length = fileReader.read(buf))!=-1){
           System.out.print(new String(buf,0,length));
       }
   }
   
   public static void readTest1() throws IOException{
       //找到目標(biāo)文件
       File file = new File("my.java");
       //建立數(shù)據(jù)的輸入通道
       FileReader fileReader = new FileReader(file);
       int content = 0 ;
       while((content = fileReader.read())!=-1){ //每次只會(huì)讀取一個(gè)字符弥激,效率低进陡。
           System.out.print((char)content);
       }
       //關(guān)閉資源
       fileReader.close();
   }
}

輸出字符流

  • Writer 輸出字符流的基類 (抽象類)

    • FileWriter 向文件數(shù)據(jù)數(shù)據(jù)的輸出字符流
  • FileWriter的使用步驟:

    1. 找到目標(biāo)文件
    2. 建立數(shù)據(jù)輸出通道
    3. 寫出數(shù)據(jù)
    4. 關(guān)閉資源
  • FileWriter要注意的事項(xiàng):

    1. 使用FileWriter寫數(shù)據(jù)的時(shí)候,F(xiàn)ileWriter內(nèi)部是維護(hù)了一個(gè)1024個(gè)字符數(shù)組的微服,寫數(shù)據(jù)的時(shí)候會(huì)先寫入到它內(nèi)部維護(hù)的字符數(shù)組中趾疚,如果需要把數(shù)據(jù)真正寫到硬盤上,需要調(diào)用flush或者是close方法或者是填滿了內(nèi)部的字符數(shù)組以蕴。
    2. 使用FileWriter的時(shí)候糙麦,如果目標(biāo)文件不存在,那么會(huì)自動(dòng)創(chuàng)建目標(biāo)文件丛肮。
      3.使用FileWriter的時(shí)候赡磅, 如果目標(biāo)文件已經(jīng)存在了,那么默認(rèn)情況會(huì)先情況文件中的數(shù)據(jù)宝与,然后再寫入數(shù)據(jù) 焚廊, 如果需要在原來(lái)的基礎(chǔ)上追加數(shù)據(jù),需要使用“new FileWriter(File , boolean)”的構(gòu)造方法习劫,第二參數(shù)為true
  • 練習(xí): 使用字符流拷貝一個(gè)文本文件(java文件)接著使用字符流拷貝一個(gè)圖片(觀察圖片的大小變化咆瘟,思考為什么會(huì)這樣子?)

public class Demo {

    public static void main(String[] args) throws IOException {
        writeTest1();
    }
    
    public static void  writeTest1() throws IOException{
        //找到目標(biāo)文件
        File file = new File("F:\\a.txt");
        //建立數(shù)據(jù)輸出通道
        FileWriter fileWriter = new FileWriter(file,true);
        //準(zhǔn)備數(shù)據(jù),把數(shù)據(jù)寫出
        String data = "今天天氣非常好7汤铩袒餐!";
        fileWriter.write(data);  //字符流具備解碼的功能。
        //刷新字符流
//      fileWriter.flush();
        //關(guān)閉資源
        fileWriter.close();
    }
}

對(duì)象的序列化

  • 當(dāng)創(chuàng)建對(duì)象時(shí), 程序運(yùn)行時(shí)它就會(huì)存在, 但是程序停止時(shí), 對(duì)象也就消失了. 但是如果希望對(duì)象在程序不運(yùn)行的情況下仍能存在并保存其信息,將會(huì)非常有用灸眼,對(duì)象將被重建并且擁有與程序上次運(yùn)行時(shí)擁有的信息相同卧檐。可以使用對(duì)象的序列化

    • 對(duì)象的序列化 : 將內(nèi)存中的對(duì)象直接寫入到文件設(shè)備中
    • 對(duì)象的反序列化 : 將文件設(shè)備中持久化的數(shù)據(jù)轉(zhuǎn)換為內(nèi)存對(duì)象
  • 基本的序列化由兩個(gè)方法產(chǎn)生 : 一個(gè)方法用于序列化對(duì)象并將它們寫入一個(gè)流幢炸,另一個(gè)方法用于讀取流并反序列化對(duì)象

    • ObjectOutput - writeObject(Object obj) : 將對(duì)象寫入底層存儲(chǔ)或流
    • ObjectInput - readObject() : 讀取并返回對(duì)象
  • ObjectOutputStream(對(duì)象的輸出流) / ObjectInputStream(對(duì)象的輸入流)

    • 對(duì)象的輸入輸出流 : 對(duì)象的輸入輸出流主要的作用是用于寫對(duì)象的信息與讀取對(duì)象的信息, 對(duì)象信息一旦寫到文件上那么對(duì)象的信息就可以做到持久化了
    • ObjectOutputStream的使用步驟:(對(duì)象輸入輸出流要注意的細(xì)節(jié))
      1. 如果對(duì)象需要被寫出到文件上泄隔,那么對(duì)象所屬的類必須要實(shí)現(xiàn)Serializable接口Serializable接口沒(méi)有任何的方法,是一個(gè)標(biāo)識(shí)接口而已
      2. 對(duì)象的反序列化創(chuàng)建對(duì)象的時(shí)候并不會(huì)調(diào)用到構(gòu)造方法的宛徊、
      3. serialVersionUID 是用于記錄class文件的版本信息的佛嬉,serialVersionUID這個(gè)數(shù)字是通過(guò)一個(gè)類的類名、成員闸天、包名暖呕、工程名算出的一個(gè)數(shù)字
      4. 使用ObjectInputStream反序列化的時(shí)候,ObjeectInputStream會(huì)先讀取文件中的serialVersionUID苞氮,然后與本地的class文件的serialVersionUID進(jìn)行對(duì)比湾揽,如果這兩個(gè)id不一致,那么反序列化就失敗了
      5. 如果序列化與反序列化的時(shí)候可能會(huì)修改類的成員笼吟,那么最好一開始就給這個(gè)類指定一個(gè)serialVersionUID库物,如果一類已經(jīng)指定的serialVersionUID,然后在序列化與反序列化的時(shí)候贷帮,jvm都不會(huì)再自己算這個(gè) class的serialVersionUID了
      6. 如果一個(gè)對(duì)象某個(gè)數(shù)據(jù)不想被序列化到硬盤上戚揭,可以使用關(guān)鍵字transient修飾
      7. 如果一個(gè)類維護(hù)了另外一個(gè)類的引用,那么另外一個(gè)類也需要實(shí)現(xiàn)Serializable接口
    • 案例: 序列化和反序列化Cat對(duì)象
public class Demo3 {
      public static void main(String[] args) throws IOException,
            ClassNotFoundException {
                Cat cat = new Cat("tom", 3);
        FileOutputStream fos = new FileOutputStream(new File("c:\\Cat.txt"));
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(cat);
        System.out.println(cat);
        oos.close();
        // 反序列化
        FileInputStream fis = new FileInputStream(new File("c:\\Cat.txt"));
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object readObject = ois.readObject();
        Cat cat2 = (Cat) readObject;
        System.out.println(cat2);
        fis.close();
  }
class Cat implements Serializable {
    public String name;
    public int age;

    public Cat() {
    }
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age + "]";
    }
}
- 例子關(guān)鍵點(diǎn):
  1. 聲明Cat類實(shí)現(xiàn)了Serializable接口撵枢。是一個(gè)標(biāo)示器民晒,沒(méi)有要實(shí)現(xiàn)的方法
  2. 新建Cat對(duì)象
  3. 新建字節(jié)流對(duì)象(FileOutputStream)進(jìn)序列化對(duì)象保存在本地文件中
  4. 新建ObjectOutputStream對(duì)象,調(diào)用writeObject方法序列化Cat對(duì)象
  5. writeObject方法會(huì)執(zhí)行兩個(gè)工作:序列化對(duì)象锄禽,然后將序列化的對(duì)象寫入文件中
  6. 反序列化就是調(diào)用ObjectInputStream的readObject()方法
  7. 異常處理和流的關(guān)閉動(dòng)作要執(zhí)行
  • Serializable
    • 類通過(guò)實(shí)現(xiàn) java.io.Serializable 接口以啟用其序列化功能潜必。未實(shí)現(xiàn)此接口的類將無(wú)法使其任何狀態(tài)序列化或反序列化∥值可序列化類的所有子類型本身都是可序列化的磁滚。序列化接口沒(méi)有方法或字段,僅用于標(biāo)識(shí)可序列化的語(yǔ)義宵晚。所以需要被序列化的類必須是實(shí)現(xiàn)Serializable接口恨旱,該接口中沒(méi)有描述任何的屬性和方法,稱之為標(biāo)記接口坝疼。如果對(duì)象沒(méi)有實(shí)現(xiàn)接口Serializable,在進(jìn)行序列化時(shí)會(huì)拋出:NotSerializableException 異常

    • 注意:保存一個(gè)對(duì)象的真正含義是什么谆沃?如果對(duì)象的實(shí)例變量都是基本數(shù)據(jù)類型钝凶,那么就非常簡(jiǎn)單。但是如果實(shí)例變量是包含對(duì)象的引用,會(huì)怎么樣耕陷?保存的會(huì)是什么掂名?很顯然在Java中保存引用變量的實(shí)際值沒(méi)有任何意義,因?yàn)镴ava引用的值是通過(guò)JVM的單一實(shí)例的上下文中才有意義哟沫。通過(guò)序列化后饺蔑,嘗試在JVM的另一個(gè)實(shí)例中恢復(fù)對(duì)象,是沒(méi)有用處的

    • 如下:

      • 首先建立一個(gè)Dog對(duì)象嗜诀,也建立了一個(gè)Collar對(duì)象猾警。Dog中包含了一個(gè)Collar(項(xiàng)圈)現(xiàn)在想要保存Dog對(duì)象,但是Dog中有一個(gè)Collar隆敢,意味著保存Dog時(shí)也應(yīng)該保存Collar发皿。假如Collar也包含了其他對(duì)象的引用,那么會(huì)發(fā)生什么拂蝎?意味著保存一個(gè)Dog對(duì)象需要清楚的知道Dog對(duì)象的內(nèi)部結(jié)構(gòu)穴墅。會(huì)是一件很麻煩的事情。
      • Java的序列化機(jī)制可以解決該類問(wèn)題温自,當(dāng)序列化一個(gè)對(duì)象時(shí)玄货,Java的序列化機(jī)制會(huì)負(fù)責(zé)保存對(duì)象的所有關(guān)聯(lián)的對(duì)象(就是對(duì)象圖),反序列化時(shí)悼泌,也會(huì)恢復(fù)所有的相關(guān)內(nèi)容松捉。本例中:如果序列化Dog會(huì)自動(dòng)序列化Collar。但是券躁,只有實(shí)現(xiàn)了Serializable接口的類才可以序列化惩坑。如果只是Dog實(shí)現(xiàn)了該接口,而Collar沒(méi)有實(shí)現(xiàn)該接口也拜。會(huì)發(fā)生什么以舒?
    • Dog類和Collar類

import java.io.Serializable;
public class Dog implements Serializable {
    private Collar collar;
    private String name;

    public Dog(Collar collar, String name) {

        this.collar = collar;
        this.name = name;
    }

    public Collar getCollar() {
        return collar;
    }
}
class Collar {
      private int size;

      public int getSize() {
        return size;
      }
      public Collar(int size) {
        this.size = size;
      }
}
  • 序列化
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Demo4 {
    public static void main(String[] args) throws IOException {
        Collar coll = new Collar(10);
        Dog dog = new Dog(coll, "旺財(cái)");
        FileOutputStream fis = new FileOutputStream(new File("c:\\dog.txt"));
        ObjectOutputStream os = new ObjectOutputStream(fis);
        os.writeObject(dog);
    }
}
  • 執(zhí)行程序,出現(xiàn)了運(yùn)行時(shí)異常: Exception in thread "main" java.io.NotSerializableException: Collar
  • 所以我們也必須將Dog中使用的Collar序列化慢哈。但是如果我們無(wú)法訪問(wèn)Collar的源代碼蔓钟,或者無(wú)法使Collar可序列化,如何處理卵贱?
    • 兩種解決方法:
      1. 繼承Collar類, 使子類可序列化, 但是如果Collar是final類, 就無(wú)法繼承了. 并且, 如果Collar引用了其他非序列化對(duì)象, 也無(wú)法解決該問(wèn)題
      2. transient : 此時(shí)就可以使用transient修飾符, 可以將Dog類中的成員變量標(biāo)識(shí)為transient, 那么在序列化Dog對(duì)象時(shí), 序列化就會(huì)跳過(guò)Collar
public class Demo4 {
            public static void main(String[] args) throws IOException,
            ClassNotFoundException {
                    Collar coll = new Collar(10);
                    Dog dog = new Dog(coll, "旺財(cái)");
                    System.out.println(dog.getCollar().getSize());

                    FileOutputStream fis = new FileOutputStream(new File("c:\\d         og.txt"));
                    ObjectOutputStream os = new ObjectOutputStream(fis);
        os.writeObject(dog);

                    // 反序列化
                    FileInputStream fos = new FileInputStream(new File("c:\\dog.txt"));
                    ObjectInputStream ois = new ObjectInputStream(fos);
                    Object readObject = ois.readObject();
                    Dog dog2 = (Dog) readObject;
                    // Collar未序列化
                    dog2.getCollar().getSize();
            }
}
- 這樣我們具有一個(gè)序列化的Dog和非序列化的Collar滥沫。此時(shí)反序列化Dog后,訪問(wèn)Collar键俱,就會(huì)出現(xiàn)運(yùn)行時(shí)異常 `` Exception in thread "main" java.lang.NullPointerException ``
- 注意:序列化不適用于靜態(tài)變量兰绣,因?yàn)殪o態(tài)變量并不屬于對(duì)象的實(shí)例變量的一部分。靜態(tài)變量隨著類的加載而加載编振,是類變量缀辩。由于序列化只適用于對(duì)象。
  • 基本數(shù)據(jù)類型可以被序列化
public class Demo5 {
      public static void main(String[] args) throws IOException {
        // 創(chuàng)建序列化流對(duì)象
        FileOutputStream fis = new FileOutputStream(new File("c:\\basic.txt"));
        ObjectOutputStream os = new ObjectOutputStream(fis);
        // 序列化基本數(shù)據(jù)類型
        os.writeDouble(3.14);
        os.writeBoolean(true);
        os.writeInt(100);
        os.writeInt(200);

        // 關(guān)閉流
        os.close();

        // 反序列化
        FileInputStream fos = new FileInputStream(new File("c:\\basic.txt"));
        ObjectInputStream ois = new ObjectInputStream(fos);

        System.out.println(ois.readDouble());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readInt());
        System.out.println(ois.readInt());

        fos.close();
      }
}
  • serialVersionUID : 用于給類指定一個(gè)UID。該UID是通過(guò)類中的可序列化成員的數(shù)字簽名運(yùn)算出來(lái)的一個(gè)long型的值臀玄。只要是這些成員沒(méi)有變化瓢阴,那么該值每次運(yùn)算都一樣。該值用于判斷被序列化的對(duì)象和類文件是否兼容健无。如果被序列化的對(duì)象需要被不同的類版本所兼容荣恐。可以在類中自定義UID累贤。

    • 定義方式:static final long serialVersionUID = 42L;
  • 對(duì)象序列化示例:

class Address implements Serializable{
    String country;
    String city;
    public Address(String country,String city){
        this.country = country;
        this.city = city;
    }   
}
class User implements Serializable{
    
    private static final long serialVersionUID = 1L;
    String userName ;
    String password;
    transient int age;  // transient 透明
    Address address ;
    
    public User(String userName , String passwrod) {
        this.userName = userName;
        this.password = passwrod;
    }

    public User(String userName , String passwrod,int age,Address address) {
        this.userName = userName;
        this.password = passwrod;
        this.age = age;
        this.address = address;
    }
    
    @Override
    public String toString() {
        return "用戶名:"+this.userName+ " 密碼:"+ this.password+" 年齡:"+this.age+" 地址:"+this.address.city;
    }
}
public class Demo {
    
    public static void main(String[] args) throws IOException, Exception {
        writeObj();
//      readObj();
    }
    
    //把文件中的對(duì)象信息讀取出來(lái)-------->對(duì)象的反序列化
    public static void readObj() throws  IOException, ClassNotFoundException{
        //找到目標(biāo)文件
        File file = new File("F:\\obj.txt");
        //建立數(shù)據(jù)的輸入通道
        FileInputStream fileInputStream = new FileInputStream(file);
        //建立對(duì)象的輸入流對(duì)象
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        //讀取對(duì)象信息
        User user = (User) objectInputStream.readObject(); //創(chuàng)建對(duì)象肯定要依賴對(duì)象所屬 的class文件叠穆。
        System.out.println("對(duì)象的信息:"+ user);
    }

    //定義方法把對(duì)象的信息寫到硬盤上------>對(duì)象的序列化。
    public static void writeObj() throws IOException{
        //把user對(duì)象的信息持久化存儲(chǔ)畦浓。
        Address address = new Address("中國(guó)","廣州");
        User user = new User("admin","123",15,address);
        //找到目標(biāo)文件
        File file = new File("F:\\obj.txt");
        //建立數(shù)據(jù)輸出流對(duì)象
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //建立對(duì)象的輸出流對(duì)象
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        //把對(duì)象寫出
        objectOutputStream.writeObject(user);
        //關(guān)閉資源
        objectOutputStream.close();
    }
}

序列流 : SequenceInputStream

  • 序列流痹束,對(duì)多個(gè)流進(jìn)行合并。SequenceInputStream 表示其他輸入流的邏輯串聯(lián)讶请。它從輸入流的有序集合開始祷嘶,并從第一個(gè)輸入流開始讀取,直到到達(dá)文件末尾夺溢,接著從第二個(gè)輸入流讀取论巍,依次類推,直到到達(dá)包含的最后一個(gè)輸入流的文件末尾為止风响。

  • 合并兩個(gè)流 : 使用構(gòu)造函數(shù) SequenceInputStream(InputStream s1, InputStream s2)

private static void testSequenceInputStream() throws IOException {
        FileInputStream fis1 = new FileInputStream("c:\\a.txt");
        FileInputStream fis2 = new FileInputStream("c:\\b.txt");

        SequenceInputStream s1 = new SequenceInputStream(fis1, fis2);
        int len = 0;
        byte[] byt = new byte[1024];

        FileOutputStream fos = new FileOutputStream("c:\\z.txt");

        while ((len = s1.read(byt)) != -1) {
            fos.write(byt, 0, len);
        }
        s1.close();
    }
  • 合并多個(gè)流:
public static void testSequenceInputStream() throws Exception {
        InputStream in1 = new FileInputStream("c:/a.txt");
        InputStream in2 = new FileInputStream("c:/b.txt");
        InputStream in3 = new FileInputStream("c:/c.txt");

        LinkedHashSet<InputStream> set = new LinkedHashSet<InputStream>();
        set.add(in1);
        set.add(in2);
        set.add(in3);
        final Iterator<InputStream> iter = set.iterator();

        SequenceInputStream sin = new SequenceInputStream(
                new Enumeration<InputStream>() {
                    @Override
                    public boolean hasMoreElements() {
                        return iter.hasNext();
                    }

                    @Override
                    public InputStream nextElement() {
                        return iter.next();
                    }
                });

        FileOutputStream out = new FileOutputStream("c:/z.txt");

        for (int b = -1; (b = sin.read()) != -1;) {
            out.write(b);
        }
        sin.close();
        out.close();
    }
  • 案例:將map3歌曲文件進(jìn)行切割拷貝,并合并.
public class Demo2 {
    public static void main(String[] args) throws IOException {
        
        split(new File("c:\\a.mp3"), 10, new File("c:\\"));
        System.out.println("切割完畢");

        LinkedHashSet<InputStream> hs = new LinkedHashSet<InputStream>();   
        hs.add(new FileInputStream(new File("c:\\part.1.mp3")));
        hs.add(new FileInputStream(new File("c:\\part.2.mp3")));
        hs.add(new FileInputStream(new File("c:\\part.3.mp3")));
        hs.add(new FileInputStream(new File("c:\\part.4.mp3")));
        merage(hs, new File("c:\\merage.mp3"));
        System.out.println("合并完畢");
    }

    private static void merage(LinkedHashSet<InputStream> hs, File dest)
            throws IOException {

        final Iterator<InputStream> it = hs.iterator();
        FileOutputStream fos = new FileOutputStream(dest);
        SequenceInputStream seq = new SequenceInputStream(
                new Enumeration<InputStream>() {

                    @Override
                    public boolean hasMoreElements() {

                        return it.hasNext();
                    }

                    @Override
                    public InputStream nextElement() {
                        return it.next();
                    }
                });
        byte[] byt = new byte[1024 * 1024];
        int len = 0;
        while ((len = seq.read(byt)) != -1) {
            fos.write(byt, 0, len);
        }
        seq.close();
        fos.close();
    }

    // 1. 切割文件
    /*
     * 切割文件,切割份數(shù), 切割后保存路徑
     */
    private static void split(File src, int count, File dir) throws IOException {
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = null;
        byte[] byt = new byte[1024 * 1024];
        int len = 0;
        for (int i = 1; i <= count; i++) {
            len = fis.read(byt);
            if (len != -1) {
                fos = new FileOutputStream(dir + "part." + i + ".mp3");
                fos.write(byt, 0, len);
            }

            // fos.close();

        }
        fis.close();

    }
}
  • 合并文件
public class Demo {
    public static void main(String[] args) throws IOException {
        merge3();
    }
    // 把三個(gè)文件合并成一個(gè)文件
    public static void merge3() throws IOException{
        //找到目標(biāo)文件
        File file1 = new File("F:\\a.txt");
        File file2 = new File("F:\\b.txt");
        File file3 = new File("F:\\c.txt");
        File file4 = new File("F:\\d.txt");

        //建立對(duì)應(yīng) 的輸入輸出流對(duì)象
        FileOutputStream fileOutputStream = new FileOutputStream(file4);
        FileInputStream fileInputStream1 = new FileInputStream(file1);
        FileInputStream fileInputStream2 = new FileInputStream(file2);
        FileInputStream fileInputStream3 = new FileInputStream(file3);

        //創(chuàng)建序列流對(duì)象
        Vector<FileInputStream> vector = new Vector<FileInputStream>();
        vector.add(fileInputStream1);
        vector.add(fileInputStream2);
        vector.add(fileInputStream3);
        Enumeration<FileInputStream> e = vector.elements();

        SequenceInputStream sequenceInputStream = new SequenceInputStream(e);
        
        //讀取文件數(shù)據(jù)
        byte[] buf = new byte[1024];
        int length = 0; 
        
        while((length = sequenceInputStream.read(buf))!=-1){
            fileOutputStream.write(buf,0,length);
        }
        
        //關(guān)閉資源
        sequenceInputStream.close();
        fileOutputStream.close();
    }
    
          //使用SequenceInputStream合并文件
    public static void merge2() throws IOException{
        //找到目標(biāo)文件
        File inFile1 = new File("F:\\a.txt");
        File inFile2 = new File("F:\\b.txt");
        File outFile = new File("F:\\c.txt");
        //建立數(shù)據(jù)的輸入輸出通道
        FileOutputStream fileOutputStream = new FileOutputStream(outFile);
        
        FileInputStream fileInputStream1 = new FileInputStream(inFile1);
        FileInputStream fileInputStream2 = new FileInputStream(inFile2);
        //建立序列流對(duì)象
        SequenceInputStream inputStream = new SequenceInputStream(fileInputStream1,fileInputStream2);
        byte[] buf = new byte[1024];
        int length = 0 ; 
        
        while((length = inputStream.read(buf))!=-1){
            fileOutputStream.write(buf,0,length);
        }
        //關(guān)閉資源
        inputStream.close();
        fileOutputStream.close();
    }
    
    //需求:把a(bǔ).txt與b.txt 文件的內(nèi)容合并嘉汰。
    public static void merge1() throws IOException{
        //找到目標(biāo)文件
        File inFile1 = new File("F:\\a.txt");
        File inFile2 = new File("F:\\b.txt");
        File outFile = new File("F:\\c.txt");
        //建立數(shù)據(jù)的輸入輸出通道
        FileOutputStream fileOutputStream = new FileOutputStream(outFile);
        FileInputStream fileInputStream1 = new FileInputStream(inFile1);
        FileInputStream fileInputStream2 = new FileInputStream(inFile2);
        
        //把輸入流存儲(chǔ)到集合中,然后再?gòu)募现凶x取
        ArrayList<FileInputStream> list = new ArrayList<FileInputStream>();
        list.add(fileInputStream1);
        list.add(fileInputStream2);
        
        // 準(zhǔn)備一個(gè)緩沖數(shù)組
        byte[] buf = new byte[1024];
        int length = 0 ; 
        
        for(int i = 0 ; i< list.size() ; i++){
            FileInputStream fileInputStream = list.get(i);
            while((length = fileInputStream.read(buf))!=-1){
                fileOutputStream.write(buf,0,length);
            }
            //關(guān)閉資源
            fileInputStream.close();
        }
        fileOutputStream.close();
    }
}

Properties

  • 可以和流相關(guān)聯(lián)的集合對(duì)象Properties状勤。Map的子類: Hashtable & Properties
  • Properties:該集合不需要泛型鞋怀,因?yàn)樵摷现械逆I值對(duì)都是String類型
    1. 存入鍵值對(duì) : setProperty(key,value);
    2. 獲取指定鍵對(duì)應(yīng)的值 : value getProperty(key);
    3. 獲取集合中所有鍵元素 : Enumeration propertyNames(); 在jdk1.6版本給該類提供一個(gè)新的方法 : Set<String> stringPropertyNames();
    4. 列出該集合中的所有鍵值對(duì),可以通過(guò)參數(shù)打印流指定列出到的目的地持搜。list(PrintStream); list(PrintWriter);
    • 例:
      list(System.out) : 將集合中的鍵值對(duì)打印到控制臺(tái)
      list(new PrintStream("prop.txt")) : 將集合中的鍵值對(duì)存儲(chǔ)到prop.txt文件中
    1. 可以將流中的規(guī)則數(shù)據(jù)加載進(jìn)行集合密似,并稱為鍵值對(duì)。load(InputStream): jdk1.6版本提供了新的方法 - load(Reader):
    • 注意:流中的數(shù)據(jù)要是"鍵=值" 的規(guī)則數(shù)據(jù)
    1. 可以將集合中的數(shù)據(jù)進(jìn)行指定目的的存儲(chǔ)葫盼。store(OutputStram,String comment) , jdk1.6版本提供了新的方法 - store(Writer ,String comment):
      使用該方法存儲(chǔ)時(shí)残腌,會(huì)帶著當(dāng)時(shí)存儲(chǔ)的時(shí)間
  • 注意:Properties只加載key=value這樣的鍵值對(duì),與文件名無(wú)關(guān)贫导,注釋使用#
public static void sysPropList() throws IOException {
        Properties prop = System.getProperties();
        // prop.list(System.out);// 目的是控制臺(tái)抛猫。
        // 需求是:將jvm的屬性信息存儲(chǔ)到一個(gè)文件中。
        prop.list(new PrintStream("java.txt"));
    }

    public static void sysProp() {
        Properties prop = System.getProperties();

        Set<String> keys = prop.stringPropertyNames();

        for (String key : keys) {
            System.out.println(key + ":" + prop.getProperty(key));
        }
    }
  • Properties類與配置文件
    • Properties類是一個(gè)Map集合孩灯,該集合中的鍵值對(duì)都是字符串闺金。該集合通常用于對(duì)鍵值對(duì)形式的配置文件進(jìn)行操作, 提供了可以快速操作配置文件的方法
    • 配置文件:將軟件中可變的部分?jǐn)?shù)據(jù)可以定義到一個(gè)文件中,方便以后更改峰档,該文件稱之為配置文件
    • 優(yōu)勢(shì): Properties類提高代碼的維護(hù)性
    • Properties類的基本方法
      • load() : 將文件設(shè)備數(shù)據(jù)裝載為Map集合數(shù)據(jù)
      • get(key) : 獲取Map中的數(shù)據(jù)
      • getProperty() : 獲取Map中的數(shù)據(jù)特有方法
    • 案例 : 將配置文件中的數(shù)據(jù)通過(guò)流加載到集合中
  public static void loadFile() throws IOException {
        // 1,創(chuàng)建Properties(Map)對(duì)象
        Properties prop = new Properties();

        // 2.使用流加載配置文件掖看。
        FileInputStream fis = new FileInputStream("c:\\qq.txt");

        // 3匣距。使用Properties 對(duì)象的load方法將流中數(shù)據(jù)加載到集合中。
        prop.load(fis);

        // 遍歷該集合
        Set<Entry<Object, Object>> entrySet = prop.entrySet();
        Iterator<Entry<Object, Object>> it = entrySet.iterator();
        while (it.hasNext()) {
            Entry<Object, Object> next = it.next();
            Object key = next.getKey();
            Object value = next.getValue();
        }
        // 通過(guò)鍵獲取指定的值
        Object object = prop.get("jack");
        System.out.println(object);

        // 通過(guò)鍵修改值
        prop.setProperty("jack", "888888");

        // 將集合中的數(shù)據(jù)寫入到配置文件中哎壳。
        FileOutputStream fos = new FileOutputStream("c:\\qq.txt");

        // 注釋:
        prop.store(fos, "yes,qq");

        fos.close();
        fis.close();
    }
  • 綜合示例: 獲取記錄程序運(yùn)行次數(shù):
public class Demo {
    public static void main(String[] args) throws IOException {
        int count = 0;
        Properties pro = new Properties();

        File file = new File("c:\\count.ini");
        FileInputStream fis = null;
        if (!file.exists()) {
            file.createNewFile();
        }
        fis = new FileInputStream(file);
        pro.load(fis);
        String str = pro.getProperty("count");
        if (str != null) {
            count = Integer.parseInt(str);
        }
        if (count == 3) {
            System.out.println("使用次數(shù)已到,請(qǐng)付費(fèi)");
            System.exit(0);
        }

        count++;
        System.out.println("歡迎使用本軟件" + "你已經(jīng)使用了:" + count + " 次");

        pro.setProperty("count", count + "");
        FileOutputStream fos = new FileOutputStream(new File("c:\\count.ini"));
        pro.store(fos, "請(qǐng)保護(hù)知識(shí)產(chǎn)權(quán)");

        fis.close();
        fos.close();

    }
}

打印流 (PrintStream)

  • 打印流概述:
    • 打印流可以接受文件和其他字節(jié)輸出流尚卫,所以打印流是對(duì)普通字節(jié)輸出流的增強(qiáng)归榕,其中定義了很多的重載的print()println(), 方便輸出各種類型的數(shù)據(jù). 打印流可以打印任意類型的數(shù)據(jù),而且打印數(shù)據(jù)之前都會(huì)先把數(shù)據(jù)轉(zhuǎn)換成字符串再進(jìn)行打印
    • 示例:
class Animal{
    String name;
    String color;
    public Animal(String name,String color){
        this.name = name;
        this.color = color;
    }
    @Override
    public String toString() {
        return "名字:"+this.name+ " 顏色:"+ this.color;
    }   
}
public class Demo {
    public static void main(String[] args) throws IOException {
        /*FileOutputStream fileOutputStream = new FileOutputStream("F:\\a.txt");
        fileOutputStream.write("97".getBytes());
        fileOutputStream.close();*/
        
        //打印流可以打印任何類型的數(shù)據(jù)吱涉,而且打印數(shù)據(jù)之前都會(huì)先把數(shù)據(jù)轉(zhuǎn)換成字符串再進(jìn)行打印刹泄。
        File file = new  File("F:\\a.txt");
        //創(chuàng)建一個(gè)打印流
        PrintStream printStream = new PrintStream(file);
        /*
        printStream.println(97);
        printStream.println(3.14);
        printStream.println('a');
        printStream.println(true);
        Animal a = new Animal("老鼠", "黑色");
        printStream.println(a);
        
        //默認(rèn)標(biāo)準(zhǔn)的輸出流就是向控制臺(tái)輸出的,
        System.setOut(printStream); //重新設(shè)置了標(biāo)準(zhǔn)的輸出流對(duì)象
        System.out.println("哈哈怎爵,猜猜我在哪里L厥!");
        */
        
        //收集異常的日志信息鳖链。
        File logFile = new File("F:\\2015年1月8日.log");
        PrintStream logPrintStream = new PrintStream( new FileOutputStream(logFile,true) );
        try{
            int c = 4/0;
            System.out.println("c="+c);
            int[] arr = null;
            System.out.println(arr.length);
            
        }catch(Exception e){
            e.printStackTrace(logPrintStream);
            
        }   
    }
}
  • PrintStream
    • 打印流(PrintStream) : 是一個(gè)字節(jié)打印流姆蘸,System.out對(duì)應(yīng)的類型就是PrintStream, 它的構(gòu)造函數(shù)可以接收三種數(shù)據(jù)類型的值
      1. 字符串路徑
      2. File對(duì)象
      3. OutputStream
public static void main(String[] args) throws IOException {
            PrintStream ps = System.out;

        // 普通write方法需要調(diào)用flush或者close方法才會(huì)在控制臺(tái)顯示
        // ps.write(100);
        // ps.close();

        // 不換行打印
            ps.print(100);
            ps.print('a');
            ps.print(100.5);
            ps.print("世界");
            ps.print(new Object());
            System.out.println("--------------");

        // 換行
            ps.println(100);
            ps.println('a');
            ps.println(100.5);
            ps.println("世界");
            ps.println(new Object());

        // 重定向打印流
            PrintStream ps2 = new PrintStream(new File("c:\\a.txt"));
            System.setOut(ps2);

        // 換行
            ps2.println(100);
            ps2.println('a');
            ps2.println(100.5);
            ps2.println("世界");
            ps2.println(new Object());

        // printf(); 格式化
            ps2.printf("%d,%f,%c,%s", 100, 3.14, '中', "世界你好!!!");
            ps2.printf("%4s和%8s 打價(jià)格戰(zhàn)", "京東", "蘇寧");     
          } 
}
  • 注意 : print 方法和write方法的卻別在于, print提供自動(dòng)刷新。普通的write方法需要調(diào)用flush或者close方法才可以看到數(shù)據(jù), JDK1.5之后Java對(duì)PrintStream進(jìn)行了擴(kuò)展, 增加了格式化輸出方式, 可以使用printf()重載方法直接格式化輸出. 但是在格式化輸出的時(shí)候需要指定輸出的數(shù)據(jù)類型格式

  • PrintWriter

    • 是一個(gè)字符打印流, 構(gòu)造函數(shù)可以接收四種類型的值
      1. 字符串路徑芙委。
      2. File對(duì)象逞敷。
      3. OutputStream
      4. Writer
    • 對(duì)于1/2類型的數(shù)據(jù), 還可以指定編碼表(也就是字符集); 對(duì)于3/4類型的數(shù)據(jù), 可以指定自動(dòng)刷新
    • 注意:該自動(dòng)刷新值為true時(shí),只有三個(gè)方法可以用:println,printf,format.
      如果想要既有自動(dòng)刷新灌侣,又可執(zhí)行編碼推捐。如何完成流對(duì)象的包裝?
      PrintWrter pw = new PrintWriter(new OutputSteamWriter(new FileOutputStream("a.txt"),"utf-8"), true);
    • 如果想要提高效率侧啼。還要使用打印方法: PrintWrter pw = newPrintWriter(new BufferdWriter(new OutputSteamWriter( newFileOutputStream("a.txt"), "utf-8")), true);
public static void testPrintWriter() throws Exception {
        PrintWriter pw = new PrintWriter("c:/b.txt", "gbk");

        // pw.append("xxx");
        // pw.println(55);
        // pw.println('c');
        // pw.printf("%.1s與%4s打價(jià)格戰(zhàn), %c", "京東","蘇寧", 'a');

        pw.close();
    }
  • Scanner
public static void testScanner() throws Exception {
        // Scanner scanner = new Scanner(new File("c:/test.txt"));
        Scanner scanner = new Scanner(System.in);

        System.out.println(scanner.nextInt());
        System.out.println(scanner.nextBoolean());

        scanner.close();
    }

操作數(shù)組的流對(duì)象

  • 操作字節(jié)數(shù)組: ByteArrayInputStream / ByteArrayOutputStream
    • 具體使用方法:
      • toByteArray();
      • toString();
      • writeTo(OutputStream);
public static void testByteArrayInputStream() throws Exception {
        InputStream in = new ByteArrayInputStream(new byte[] { 65, 66, 67 });
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        for (int b = -1; (b = in.read()) != -1;) {
            out.write(b);
        }

        in.close();
        out.close();

        System.out.println(Arrays.toString(out.toByteArray()));
        System.out.println(out);
    }
  • 操作字符數(shù)組 : CharArrayReader / CharArrayWriter
    • 對(duì)于這些流: 源是內(nèi)存, 目的也是內(nèi)存牛柒。而且這些流并未調(diào)用系統(tǒng)資源, 使用的就是內(nèi)存中的數(shù)組, 所以在使用的時(shí)候無(wú)需close。操作數(shù)組的讀取流在構(gòu)造時(shí)痊乾,必須要明確一個(gè)數(shù)據(jù)源, 所以要傳入相對(duì)應(yīng)的數(shù)組皮壁。對(duì)于操作數(shù)組的寫入流,在構(gòu)造函數(shù)可以使用空參數(shù)符喝。因?yàn)樗鼉?nèi)置了一個(gè)可變長(zhǎng)度數(shù)組作為緩沖區(qū)
public static void testCharArrayReader() throws Exception {
        CharArrayReader reader = new CharArrayReader(new char[] { 'A', 'b', 'c' });
        CharArrayWriter writer = new CharArrayWriter();

        for (int b = -1; (b = reader.read()) != -1;) {
            writer.write(b);
        }

        reader.close();
        writer.close();

        System.out.println(writer.toCharArray());
    }
  • 這幾個(gè)流的出現(xiàn)其實(shí)就是通過(guò)流的讀寫思想在操作數(shù)組闪彼。類似的對(duì)象同理:StringReader / StringWriter。
public static void testStringReader() throws Exception {
        StringReader reader = new StringReader("test 中國(guó)");
        StringWriter writer = new StringWriter();

        for (int b = -1; (b = reader.read()) != -1;) {
            writer.write(b);
        }

        reader.close();
        writer.close();

        System.out.println(writer.toString());
    }

操作基本數(shù)據(jù)類型的流對(duì)象

  • DataInputStream以及DataOutputStreamg概述 :

  • 查看API文檔DataInputStream的信息 : 發(fā)現(xiàn)從底層輸入流中讀取基本 Java 數(shù)據(jù)類型协饲。查看方法, 有讀一個(gè)字節(jié), 讀一個(gè)char, 讀一個(gè)double 的方法

  • DataInputStream從數(shù)據(jù)流讀取字節(jié)畏腕,并將它們轉(zhuǎn)換為正確的基本數(shù)據(jù)類型值或字符串。DataInputStream類繼承FilterInputStream類并實(shí)現(xiàn)了DataInput接口

  • DataOutputStream將基本類型的值或字符串轉(zhuǎn)換為字節(jié)茉稠,并且將字節(jié)輸出到數(shù)據(jù)流描馅。DataOutputStream類繼承FilterOutputStream并實(shí)現(xiàn)了DataOutput接口

  • DataInputStream 的操作基本數(shù)據(jù)類型的方法:

    • int readInt() : 一次讀取四個(gè)字節(jié),并將其轉(zhuǎn)成int值
    • boolean readBoolean() : 一次讀取一個(gè)字節(jié)
    • short readShort()
    • long readLong()
    • 剩下的數(shù)據(jù)類型一樣
    • String readUTF() : 按照utf-8修改版讀取字符而线。注意铭污,它只能讀writeUTF()寫入的字符數(shù)據(jù)
  • DataOutputStream 的操作基本數(shù)據(jù)類型的方法:

    • writeInt(int) : 一次寫入四個(gè)字節(jié)恋日。注意和write(int)不同。write(int)只將該整數(shù)的最低一個(gè)8位寫入嘹狞。剩余三個(gè)8位丟棄
    • writeBoolean(boolean)
    • writeShort(short)
    • writeLong(long)
    • 剩下是數(shù)據(jù)類型也也一樣
    • writeUTF(String) : 按照utf-8修改版將字符數(shù)據(jù)進(jìn)行存儲(chǔ)岂膳。只能通過(guò)readUTF讀取
  • 使用DataOutputStream寫數(shù)據(jù)文件

public static void testDataInputStream() throws Exception {
        DataOutputStream out = new DataOutputStream(new FileOutputStream(
                "c:/a.txt"));

        out.writeBoolean(true);
        out.writeByte(15); // 0x05 1 個(gè)字節(jié)
        out.writeBytes("abc"); // 0x 0041 2個(gè)字節(jié)
        out.writeChar('X'); // ??
        out.writeChars("xyz");
        out.writeLong(111);
        out.writeUTF("中國(guó)");

        out.close();

        DataInputStream in = new DataInputStream(
                new FileInputStream("c:/a.txt"));
        System.out.println(in.readBoolean());
        System.out.println(in.readByte());
        
        System.out.println(in.readByte());
        System.out.println(in.readByte());
        System.out.println(in.readByte());
        
        System.out.println(in.readChar());
        
        System.out.println(in.readChar());
        System.out.println(in.readChar());
        System.out.println(in.readChar());
        
        System.out.println(in.readLong());
        
        System.out.println(in.readUTF());
        in.close();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市磅网,隨后出現(xiàn)的幾起案子谈截,更是在濱河造成了極大的恐慌,老刑警劉巖涧偷,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件簸喂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡燎潮,警方通過(guò)查閱死者的電腦和手機(jī)喻鳄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)确封,“玉大人除呵,你說(shuō)我怎么就攤上這事∮绶剩” “怎么了竿奏?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)腥放。 經(jīng)常有香客問(wèn)我泛啸,道長(zhǎng),這世上最難降的妖魔是什么秃症? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任候址,我火速辦了婚禮,結(jié)果婚禮上种柑,老公的妹妹穿的比我還像新娘岗仑。我一直安慰自己,他們只是感情好聚请,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布荠雕。 她就那樣靜靜地躺著,像睡著了一般驶赏。 火紅的嫁衣襯著肌膚如雪炸卑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天煤傍,我揣著相機(jī)與錄音盖文,去河邊找鬼。 笑死蚯姆,一個(gè)胖子當(dāng)著我的面吹牛五续,可吹牛的內(nèi)容都是我干的洒敏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼疙驾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凶伙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起它碎,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镊靴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后链韭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡煮落,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年敞峭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝉仇。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旋讹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出轿衔,到底是詐尸還是另有隱情沉迹,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布害驹,位于F島的核電站鞭呕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宛官。R本人自食惡果不足惜葫松,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望底洗。 院中可真熱鬧腋么,春花似錦、人聲如沸亥揖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)费变。三九已至摧扇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胡控,已是汗流浹背扳剿。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昼激,地道東北人庇绽。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓锡搜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瞧掺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耕餐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • IO簡(jiǎn)單概述 IO解決問(wèn)題 : 解決設(shè)備與設(shè)備之間的數(shù)據(jù)傳輸問(wèn)題(硬盤 -> 內(nèi)存 內(nèi)存 -> 硬盤) 讀和寫文...
    奮斗的老王閱讀 3,429評(píng)論 0 53
  • # 3.1 File # ## 3.1.1 File基本概念 ## 1.基本概念 -File類用于表示文件(目錄)...
    閆子揚(yáng)閱讀 457評(píng)論 0 0
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法辟狈,內(nèi)部類的語(yǔ)法肠缔,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法哼转,線程的語(yǔ)...
    子非魚_t_閱讀 31,581評(píng)論 18 399
  • 一明未、流的概念和作用。 流是一種有順序的壹蔓,有起點(diǎn)和終點(diǎn)的字節(jié)集合趟妥,是對(duì)數(shù)據(jù)傳輸?shù)目偝苫虺橄蟆<磾?shù)據(jù)在兩設(shè)備之間的傳輸...
    布魯斯不吐絲閱讀 10,018評(píng)論 2 95
  • 我是這樣看態(tài)度的 昨天下午佣蓉,楊老師給我們講了態(tài)度決定一切披摄,那下面我就來(lái)說(shuō)說(shuō)態(tài)度吧! 態(tài)度決定一切。以欣...
    8b9542e8809c閱讀 170評(píng)論 0 1