java筆記--IO包中的其他類

打印流:PrintWriter,PrintStream--可以直接操作輸入流和文件。

PrintWriter:字符打印流。
構(gòu)造函數(shù):
1,字符串路經(jīng)。
2,F(xiàn)ile對象。
3,字符輸出流。
4,字節(jié)輸出流。
PrintStream:提供了打印方法可以對多種數(shù)據(jù)類型值進(jìn)行打印,并保持?jǐn)?shù)據(jù)的表現(xiàn)形式,不拋IOException。

public static void main(String[] args) throws IOException {

        /*
         * PrintStream:
         * 1,提供了打印方法可以對多種數(shù)據(jù)類型值進(jìn)行打印。并保持?jǐn)?shù)據(jù)的表示形式。 
         * 2,它不拋IOException.
         * 
         * 構(gòu)造函數(shù),接收三種類型的值:
         * 1,字符串路徑。
         * 2,F(xiàn)ile對象。
         * 3,字節(jié)輸出流。
         */
        
        PrintStream out = new PrintStream("print.txt");
        
//      int by = read();
//      write(by);
        
//      out.write(610);//只寫最低8位,
        
        out.print(97);//將97先變成字符保持原樣將數(shù)據(jù)打印到目的地。
        
        out.close();
    }

運(yùn)行:

SequenceInputStream:序列流--對多個流進(jìn)行合并。

public class SequenceInputStreamDemo {
    public static void main(String[] args) throws IOException {

        
        /*
         * 需求:將1.txt 2.txt 3.txt文件中的數(shù)據(jù)合并到一個文件中。
         */
        
//      Vector<FileInputStream> v = new Vector<FileInputStream>();      
//      v.add(new FileInputStream("1.txt"));
//      v.add(new FileInputStream("2.txt"));
//      v.add(new FileInputStream("3.txt"));
//      Enumeration<FileInputStream> en = v.elements();
        
        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
        for(int x=1; x<=3; x++){
            al.add(new FileInputStream(x+".txt"));
        }
        
        Enumeration<FileInputStream> en = Collections.enumeration(al);
        
        
        
        /*
        final Iterator<FileInputStream> it = al.iterator();
        Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){

            @Override
            public boolean hasMoreElements() {
                
                return it.hasNext();
            }

            @Override
            public FileInputStream nextElement() {
                
                return it.next();
            }
            
        };*/
        
        SequenceInputStream sis = new SequenceInputStream(en);
        
        FileOutputStream fos = new FileOutputStream("1234.txt");
        
        byte[] buf = new byte[1024];
        
        int len = 0;
        
        while((len=sis.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        
        fos.close();
        sis.close();
        
    }
}

運(yùn)行:

切割文件:

public class SplitFileDemo {

    private static final int SIZE = 1024 * 1024;

    public static void main(String[] args) throws Exception {

        File file = new File("c:\\a.mp3");

        splitFile_2(file);
    }

    private static void splitFile_2(File file) throws IOException {

        // 用讀取流關(guān)聯(lián)源文件。
        FileInputStream fis = new FileInputStream(file);

        // 定義一個1M的緩沖區(qū)。
        byte[] buf = new byte[SIZE];

        // 創(chuàng)建目的。
        FileOutputStream fos = null;

        int len = 0;
        int count = 1;
        
        
        /*
         * 切割文件時,必須記錄住被切割文件的名稱,以及切割出來碎片文件的個數(shù)。 以方便于合并。
         * 這個信息為了進(jìn)行描述,使用鍵值對的方式。用到了properties對象
         * 
         */
        Properties prop  = new Properties();
        
    

        File dir = new File("c:\\partfiles");
        if (!dir.exists())
            dir.mkdirs();

        while ((len = fis.read(buf)) != -1) {

            fos = new FileOutputStream(new File(dir, (count++) + ".part"));
            fos.write(buf, 0, len);
            fos.close();
        }
        
        //將被切割文件的信息保存到prop集合中。
        prop.setProperty("partcount", count+"");
        prop.setProperty("filename", file.getName());
        
        
        
        fos = new FileOutputStream(new File(dir,count+".properties"));
        
        //將prop集合中的數(shù)據(jù)存儲到文件中。 
        prop.store(fos, "save file info");

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

    }

    public static void splitFile(File file) throws IOException {

        // 用讀取流關(guān)聯(lián)源文件。
        FileInputStream fis = new FileInputStream(file);

        // 定義一個1M的緩沖區(qū)。
        byte[] buf = new byte[SIZE];

        // 創(chuàng)建目的。
        FileOutputStream fos = null;

        int len = 0;
        int count = 1;

        File dir = new File("c:\\partfiles");
        if (!dir.exists())
            dir.mkdirs();

        while ((len = fis.read(buf)) != -1) {

            fos = new FileOutputStream(new File(dir, (count++) + ".part"));
            fos.write(buf, 0, len);
        }

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

    }
}

運(yùn)行:

合并文件:

public class MergeFile {
    public static void main(String[] args) throws IOException {

        File dir = new File("c:\\partfiles");
        
        mergeFile_2(dir);
    }
    
    public static void mergeFile_2(File dir) throws IOException {
        
        /*
         * 獲取指定目錄下的配置文件對象。
         */
        File[] files = dir.listFiles(new SuffixFilter(".properties"));
        
        if(files.length!=1)
            throw new RuntimeException(dir+",該目錄下沒有properties擴(kuò)展名的文件或者不唯一");
        //記錄配置文件對象。
        File confile = files[0];
        
        
        
        //獲取該文件中的信息================================================。
        
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream(confile);
        
        prop.load(fis);
        
        String filename = prop.getProperty("filename");     
        int count = Integer.parseInt(prop.getProperty("partcount"));
        
        
        
        
        //獲取該目錄下的所有碎片文件。 ==============================================
        File[] partFiles = dir.listFiles(new SuffixFilter(".part"));
        
        if(partFiles.length!=(count-1)){
            throw new RuntimeException(" 碎片文件不符合要求,個數(shù)不對!應(yīng)該"+count+"個");
        }
        
        
        
        //將碎片文件和流對象關(guān)聯(lián) 并存儲到集合中。 
        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
        for(int x=0; x<partFiles.length; x++){
            
            al.add(new FileInputStream(partFiles[x]));
        }
        
        
        
        //將多個流合并成一個序列流。 
        Enumeration<FileInputStream> en = Collections.enumeration(al);
        SequenceInputStream sis = new SequenceInputStream(en);
        
        FileOutputStream fos = new FileOutputStream(new File(dir,filename));
        
        byte[] buf = new byte[1024];
        
        int len = 0;
        while((len=sis.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        
        fos.close();
        sis.close();
        
        
        
        
        
        
    }

    public static void mergeFile(File dir) throws IOException{
        
        
        ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
        
        for(int x=1; x<=3 ;x++){
            al.add(new FileInputStream(new File(dir,x+".part")));
        }
        
        Enumeration<FileInputStream> en = Collections.enumeration(al);
        SequenceInputStream sis = new SequenceInputStream(en);
        
        FileOutputStream fos = new FileOutputStream(new File(dir,"2.mp3"));
        
        byte[] buf = new byte[1024];
        
        int len = 0;
        while((len=sis.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        
        fos.close();
        sis.close();
        
    }
}

運(yùn)行:

ObjectInputStream與ObjectOutputStream:操作對象,但是被操作的對象需要實(shí)現(xiàn)Serializable。
Serializable:用于給被序列化的類加入ID號,用于判斷類和對象是否是同一個版本。

public class Person implements Serializable/*標(biāo)記接口*/ {

    private static final long serialVersionUID=9527l;//Serializable使得類每次改動都會生成不同的序列號,所以會發(fā)生InvalidClassException.這里給固定一個序列,解決問題。
    private String name;//可改動變量修飾符試一下是否拋出InvalidClassException.
    private int age;
    
    
    public Person(String name, int age) {
        super();
        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;
    }
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
            
//      writeObj();
        readObj();
    }

    public static void readObj() throws IOException, ClassNotFoundException {
        
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
        //對象的反序列化。 
        Person p = (Person)ois.readObject();
        
        System.out.println(p.getName()+":"+p.getAge());
        
        ois.close();
        
    }

    public static void writeObj() throws IOException, IOException {
        
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
        //對象序列化。  被序列化的對象必須實(shí)現(xiàn)Serializable接口。 
        oos.writeObject(new Person("小強(qiáng)",30));
        
        oos.close();

    }
}

運(yùn)行:


transient:非靜態(tài)數(shù)據(jù)不想序列化可使用這個關(guān)鍵字修飾。
writeObject:對象的類、類的簽名,以及類及其所有超類型的非瞬態(tài)和非靜態(tài)字段的值都可被寫入。

public class Person implements Serializable/*標(biāo)記接口*/ {

    /**
     * transient:非靜態(tài)數(shù)據(jù)不想被序列化可以使用這個關(guān)鍵字修飾。
     */
    private static final long serialVersionUID = 9527l;
    private transient String name;
    private static int age;//靜態(tài)不可被寫入
    
    
    public Person(String name, int age) {
        super();
        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;
    }   
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
            
//      writeObj();
        readObj();
    }

    public static void readObj() throws IOException, ClassNotFoundException {
        
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
        //對象的反序列化。 
        Person p = (Person)ois.readObject();
        
        System.out.println(p.getName()+":"+p.getAge());
        
        ois.close();
        
    }

    public static void writeObj() throws IOException, IOException {
        
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
        //對象序列化。  被序列化的對象必須實(shí)現(xiàn)Serializable接口。 
        oos.writeObject(new Person("小強(qiáng)",30));
        
        oos.close();

    }
}

運(yùn)行:

RandomAccessFile:隨機(jī)訪問文件,自身具備讀寫的方法。通過skipBytes(int x),seek(int x)來達(dá)到隨機(jī)訪問。
因?yàn)榭梢噪S機(jī)寫入,所以寫文件可用多線程同時進(jìn)行讀寫操作。

public class RandomAccessFileDemo {

    public static void main(String[] args) throws IOException {
        /*
        RandomAccessFile:
            1,該對象既能讀,又能寫
            2,該對象內(nèi)部維護(hù)了一個byte數(shù)組,并通過指針可以操作數(shù)組中的元素
            3,可以通過getFilePointer方法獲取指針位置,通過seek方法設(shè)置指針位置
            4,其實(shí)該對象就是將字節(jié)輸入流和輸出流進(jìn)行了封裝。
            5,該對象的源或者目的只能是文件。可通過構(gòu)造函數(shù)看出。
            */
        
//      writeFile();
        readFile();
    }
    
    public static void readFile() throws IOException {
        
        RandomAccessFile raf=new RandomAccessFile("ranacc.txt","r");
        
        byte[] buf=new byte[4];
        raf.read(buf);
        
        String name=new String(buf);
        int age=raf.readInt();
        
        System.out.println("name="+name);
        System.out.println("age="+age);
        raf.close();
    }

    //使用RandomAccessFile對象寫入一些人員信息,比如姓名,年齡
    public static void writeFile() throws IOException {
        
//      如果文件不存在,則創(chuàng)建,存在則不創(chuàng)建
        RandomAccessFile raf=new RandomAccessFile("ranacc.txt","rw");//rw:打開以便讀取和寫入,若文件不存在,嘗試創(chuàng)建
        
        raf.write("張三".getBytes());
        raf.writeInt(97);
        raf.write("小強(qiáng)".getBytes());
        raf.writeInt(99);
        
        raf.close();
    }
}

運(yùn)行:
public static void randomWrite() throws IOException {
        RandomAccessFile raf=new RandomAccessFile("ranacc.txt","rw");
        
        //往指定位置寫入數(shù)據(jù)
        raf.seek(3*8);
        
        raf.write("哈哈".getBytes());
        raf.writeInt(108);
        
        raf.close();
    }

    public static void readFile() throws IOException {
        
        RandomAccessFile raf=new RandomAccessFile("ranacc.txt","r");
        
        //通過seek設(shè)置指針的位置
        raf.seek(1*8);//隨機(jī)讀取,只要指定指針位置即可
        
        byte[] buf=new byte[4];
        raf.read(buf);
        
        String name=new String(buf);
        
        int age=raf.readInt();
        
        System.out.println("name="+name);
        System.out.println("age="+age);
        
        System.out.println("pos="+raf.getFilePointer());
        raf.close();
    }

運(yùn)行:

PipedInputStream,PipedOutputStream:管道流,輸入輸出可以直接進(jìn)行連接,通過結(jié)合線程使用。

public class PipedStream {

    public static void main(String[] args) throws IOException {
        
        PipedInputStream input=new PipedInputStream();
        PipedOutputStream output=new PipedOutputStream();
        
        input.connect(output);
        
        new Thread(new Input(input)).start();
        new Thread(new Output(output)).start();

    }

}

class Input implements Runnable{
    
    private PipedInputStream in;
    Input(PipedInputStream in){
        this.in = in;
    }
    public void run(){
        
        try {
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            
            String s = new String(buf,0,len);
            
            System.out.println("s="+s);
            in.close();
        } catch (Exception e) {
        }
        
    }
}
class Output implements Runnable{
    private PipedOutputStream out;
    Output(PipedOutputStream out){
        this.out = out;
    }
    public void run(){
        
        try {
            Thread.sleep(5000);
            out.write("hi,管道來了!".getBytes());
        } catch (Exception e) {
        }
    }
}

運(yùn)行:

DataInputStream,DataOutputStream:操作基本數(shù)據(jù)類型。

public class DataStreamDemo {

    public static void main(String[] args) throws IOException {
        
        writeData();
        readData();
    }

    public static void readData() throws IOException {
        
        DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
        
        String str=dis.readUTF();
        
        System.out.println(str);
    }

    public static void writeData() throws IOException {
        
        DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
        
        dos.writeUTF("你好");
        
        dos.close();
    }
}

運(yùn)行:

ByteArrayReader,CharArrayWrite:操作字節(jié)數(shù)組。
CharArrayReader,CharArrayWrite:操作字符數(shù)組。
StringReader,StringWriter:操作字符串。

public class ByteArrayStreamDemo {

    public static void main(String[] args) {
        
        ByteArrayInputStream bis=new ByteArrayInputStream("abcdef".getBytes());
        
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        
        int ch=0;
        
        while((ch=bis.read())!=-1){
            bos.write(ch);
        }
        System.out.println(bos.toString());
    }

}

運(yùn)行:

字符編碼:字符流的出現(xiàn)是為了方便操作字符,更重要的是加入了編碼轉(zhuǎn)換--通過子類轉(zhuǎn)換流完成--InputStreamReader,OutputStreamWriter。在兩個對象進(jìn)行構(gòu)造的時候可以加入字符集。

public class EncodeDemo {

    public static void main(String[] args) throws IOException {
        /*
        字符串 -->字節(jié)數(shù)組:編碼。
        字節(jié)數(shù)組 -->字符串:解碼。
        */
        
        String str="謝謝";
        
        byte[] buf=str.getBytes("gbk");
        
        String s1=new String(buf,"UTF-8");
        
        System.out.println("s1="+s1);
        
        byte[] buf2=s1.getBytes("UTF-8");//獲取源字節(jié)。
        
        printBytes(buf2);
        
        String s2=new String(buf2,"GBK");
        
        System.out.println("s2="+s2);
        
        encodeDemo(str);
    }

    public static void encodeDemo(String str) throws UnsupportedEncodingException {
        //編碼
        byte[] buf=str.getBytes("UTF-8");
        
        printBytes(buf);
        
        //解碼
        String s1=new String(buf,"UTF-8");
        
        System.out.println("s1="+s1);
    }

    public static void printBytes(byte[] buf) {
        for(byte b:buf){
            System.out.print(b+" ");
        }
        
    }
}

運(yùn)行:

聯(lián)通問題(utf-8修改版字節(jié)表現(xiàn)形式):


新建文本

保存后再打開

原因:保存時,默認(rèn)系統(tǒng)編碼方式,打開時以utf-8的方式打開。

驗(yàn)證:

public class LianTong {

    public static void main(String[] args) throws IOException {
        String str="聯(lián)通";
        
        byte[] buf=str.getBytes("gbk");
        
        for(byte b:buf){
            System.out.println(Integer.toBinaryString(b&255));
        }

    }
}

運(yùn)行:

截取字符:

public class Test {

    public static void main(String[] args) throws IOException {
        
        String str="ab你好cd謝謝";
//      str="ab琲琲cd琲琲";
        
        /*int len=str.getBytes("gbk").length;
        for(int x=0;x<len;x++){
            System.out.println("截取"+(x+1)+"個字節(jié)結(jié)果是:"+cutStringByByte(str,x+1));
        }*/
        
        int len=str.getBytes("utf-8").length;
        for(int x=0;x<len;x++){
            System.out.println("截取"+(x+1)+"個字節(jié)結(jié)果"+cutStringByU8Byte(str,x+1));
        }
        
        /*String str="琲";
        byte[] buf=str.getBytes("gbk");
        for(byte b:buf){
            System.out.println(b);
        }*/
    }
    /*
    在java中,字符串"abcd"與字符串"ab你好"的長度是一樣的,都是四個字符。
    但對應(yīng)的字節(jié)數(shù)不同,一個漢字占兩個字節(jié)。
    定義一個方法,按照最大的字節(jié)數(shù)來取子串。
    如:對于"ab你好",如果取三個字節(jié),那么子串就是ab與"你"字的半個,沒那
    么半個就要舍棄。如果去四個字節(jié)就是"ab你",取五個字節(jié)還是"ab你"。
    */

    public static String cutStringByU8Byte(String str, int len) throws IOException {
        
        byte[] buf =str.getBytes("utf-8");
        
        int count=0;
        for(int x=len-1;x>=0;x--){
            if(buf[x]<0)
                count++;
            else
                break;
        }
        if(count%3==0)
            return new String(buf,0,len,"utf-8");
        else if(count%3==1)
            return new String(buf,0,len-1,"utf-8");
        else
            return new String(buf,0,len-2,"utf-8");
    }

    public static String cutStringByByte(String str, int len) throws IOException {
        
        byte[] buf=str.getBytes("gbk");
        
        int count=0;
        for(int x=len-1;x>0;x--){
            if(buf[x]<0)
                count++;
            else
                break;
        }
        if(count%2==0)
            return new String(buf,0,len,"gbk");
        else
            return new String(buf,0,len-1,"gbk");
    }
}

運(yùn)行:
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容