Java基础IO专题笔记

javaSECore-IO

编码

。File

。字节流

。InputStream

。OutputStream

。字符流

。Reder

。Writer

。RandomAccessFile

。Properties类的使用

。序列化

1,java.io 包

API解释: 通过数据流,序列化和文件系统提供系统输入和输出。(主要针对文件的读写)

  1. 编码问题,一个字符串放入文本文件--------->其实是一种序列化,也可以称为字符串的序列胡

    从文本读取,-------->可以认为是一种反序列化

文本文件中内容都是以字节的盎司呈现的。

字符串放入文本文件 ,首先将字符串----》转化为字节,转化成字节的时候可以选择很多种编码。

以什么样的编码方式转化为字节的,将来需要转化为字符串也需要改编码的方式转化。

(如:使用gbk转化的 ,后面转化也需要gbk)

2,常用编码

gbk,utf-8,utf-16be

//java语言内部一个字符占两个字节,不管是中文还是英文

package corelesson4;
​
import java.io.UnsupportedEncodingException;
​
public class EncodeDemo1 {
    public static void main(String[] args) {
        String s="ABC沃";
        byte[] b = s.getBytes();// 默认会用项目的编码
        for (byte b1 : b) {
            System.out.print(Integer.toHexString(b1&0xFF)+" ");
​
        }
        System.out.println();
        try {
            s.getBytes("GBK");
            for (byte b1 : b) {
                System.out.print(Integer.toHexString(b1&0xFF)+" ");
            }
            // gbk 编码1个英文占用一个字节,一个中文占用两个字节
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println("\n===========================");
        try {
            s.getBytes("UTF-8");
            for (byte b1 : b) {
                System.out.print(Integer.toHexString(b1&0xFF)+" ");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
​
​
    }
}

// 可以看出 一个英文占用一个字节 ,一个中文占 三个字节。

41 42 43 e6 b2 83

41 42 43 e6 b2 83

2, Java.io.file 类

可以表示一个文件也可以表示一个目录。

file 类的常用方法

package corelesson4;
​
import java.io.File;
import java.io.IOException;
​
public class FileDemo1 {
    public static void main(String[] args) throws IOException {
        //代表一个目录  创建方式1
        File file = new File("F:\\1_java大神之路\\全新java分布式软件工程师\\13.JavaSECore-IO专题\\Filedemo");
        //判断一个目录是否存在
        //true 表示存在,false 表示不存在
        System.out.println(file.exists());
        // 创建方式2
        File file1 = new File("F:\\1_java大神之路\\全新java分布式软件工程师\\13.JavaSECore-IO专题\\Filedemo\\aaa");
        if (!file1.exists()){
            file1.mkdirs();//这个目录不存在就创建
        }else
        {
            file1.delete();//目录存在就删除
        }
        //创建方式3
        File file2 = new File(file, "bbb");
        if (!file2.exists()){
            file2.mkdirs();//这个目录不存在就创建 mkdirs 创建多级目录
        }else
        {
            file2.delete();//目录存在就删除
        }
        System.out.println("=================================");
        // 判断是否是目录
        System.out.println(file2.isDirectory());
        //判断是否是文件,如果目录不存在 也返回false
        System.out.println(file2.isFile());
        System.out.println("==========================================");
        // 创建一个文件
        File file3 = new File(file, "aaa.txt");
        if (!file3.exists())
        {
            file3.createNewFile();
        }
        System.out.println(file3.exists());
        System.out.println(file3.isFile());
​
        // 得到目录的绝对路径 getAbsolutePath
        System.out.println(file.getAbsolutePath());
        //  返回的是最后一个文件名
        System.out.println(file.getName());
        System.out.println(file2.getName());
        // 得到他的父目录
        System.out.println(file1.getParentFile());
        System.out.println(file1.getParentFile().getAbsolutePath());
        System.out.println(file2.getParentFile().getAbsolutePath());
        
    }
}
​

File 文件的过滤器

package corelesson4;
​
import java.io.File;
import java.io.FilenameFilter;
​
public class FileDemo2 {
    public static void main(String[] args) {
        File file = new File("E:\\Myeclipse\\MyEclipse2014汉化\\features");
      //  listFile(file);
       // listFile1(file);
        listFile2(file);
    }
    public static void listFile(File file){
        /**
         * list()显示里面所有的文件名和目录名,不会列出父目录
         * 也不会遍历子目录
         */
        String[] list = file.list();
        for (String s : list) {
            System.out.println(s);
        }
        System.out.println("====================================================");
         //直接累出目录下的,产生的是File对象
        File[] files = file.listFiles();
        for (File file1 : files) {
            //打印目录的所有名字
            System.out.println(file1.getAbsolutePath());
        }
    }
    /**
     * 把子目录下的也列出来
     * 和目录下所有的内容
     */
​
    public static void listFile1(File file){
        //拿到file对象
        File[] files = file.listFiles();
        for (File file1 : files) {
​
            if (file1.isFile()){ //如果是文件就列出来
                System.out.println(file1.getAbsolutePath());
            }else
            {
                listFile1(file1);// 如果是目录就递归调用
            }
        }
​
    }
    public static void listFile2(File file){
       // String[] list = file.list(new MyFileNameFileter());
        String[] list = file.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
​
​
                name.startsWith(".babel"); //过滤以这个开头的
                return name.endsWith("724060447");// 过滤以这个结尾的
            }
        });
        for (String s : list) {
            System.out.println(file.getAbsolutePath()+"/"+ s);
        }
​
    }
    //写个内部类实现这个过滤器接口
   static class MyFileNameFileter implements FilenameFilter{
        // file  列出的每个文件都要调用accept 方法, 返回true 留下,false 被过滤掉
       @Override
       public boolean accept(File dir, String name) {
           //File dir  代表父目录 ,String name 代表直接的文件名或者目录名
         //  System.out.println(dir.getAbsolutePath() +"        "+name);
​
           return name.endsWith("subversive_zh_4.2.0.v20130724060447");
       }
   }
}

过滤器方式一 :FilenameFilter()

public static void listFile2(File file){ // String[] list = file.list(new MyFileNameFileter()); String[] list = file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) {

            name.startsWith(".babel"); //过滤以这个开头的
            return name.endsWith("724060447");// 过滤以这个结尾的
        }
    });
    for (String s : list) {
        System.out.println(file.getAbsolutePath()+"/"+ s);
    }
​
}

过滤器方式二 :FileFilter()

package corelesson4;
​
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
​
public class FileDemo2 {
    public static void main(String[] args) {
        File file = new File("E:\\Myeclipse\\MyEclipse2014汉化\\features");
      //  listFile(file);
       // listFile1(file);
        //listFile2(file);
       // listFile3(file);
        //listFile4(file);
        listFile5(file);
    }
    public static void listFile(File file){
        /**
         * list()显示里面所有的文件名和目录名,不会列出父目录
         * 也不会遍历子目录
         */
        String[] list = file.list();
        for (String s : list) {
            System.out.println(s);
        }
        System.out.println("====================================================");
         //直接累出目录下的,产生的是File对象
        File[] files = file.listFiles();
        for (File file1 : files) {
            //打印目录的所有名字
            System.out.println(file1.getAbsolutePath());
        }
    }
    /**
     * 把子目录下的也列出来
     * 和目录下所有的内容
     */
    public static void listFile1(File file){
        //拿到file对象
        File[] files = file.listFiles();
        for (File file1 : files) {
​
            if (file1.isFile()){ //如果是文件就列出来
                System.out.println(file1.getAbsolutePath());
            }else
            {
                listFile1(file1);// 如果是目录就递归调用
            }
        }
​
    }
    public static void listFile2(File file){
       // String[] list = file.list(new MyFileNameFileter());
        String[] list = file.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
​
​
                name.startsWith(".babel"); //过滤以这个开头的
                return name.endsWith("724060447");// 过滤以这个结尾的
            }
        });
        for (String s : list) {
            System.out.println(file.getAbsolutePath()+"/"+ s);
        }
​
    }
    //写个内部类实现这个过滤器接口
   static class MyFileNameFileter implements FilenameFilter{
        // file  列出的每个文件都要调用accept 方法, 返回true 留下,false 被过滤掉
       @Override
       public boolean accept(File dir, String name) {
           //File dir  代表父目录 ,String name 代表直接的文件名或者目录名
         //  System.out.println(dir.getAbsolutePath() +"        "+name);
​
           return name.endsWith("subversive_zh_4.2.0.v20130724060447");
       }
   }
    public static void listFile3(File file){
        // 用匿名类方式实现 过滤器
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                //File pathname 就是ile下的每个文件or目录的全路径
                System.out.println(pathname);
                 //  只留下java  其他被过滤
                return  pathname.getAbsolutePath().endsWith(".java");
            }
        });
        System.out.println("===============================");
        for (File file1 : files) {
            System.out.println(file1.getAbsolutePath());
        }
    }
    /**
     * 递归拿出子目录下的.java 文件也拿出来
     * @param file
     */
    public static void listFile4(File file){
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                if (pathname.isFile()){
                    return pathname.getAbsolutePath().endsWith(".html");
                }else if ( pathname.isDirectory())
                    listFile4(pathname);
                  return true;
            }
        });
        for (File file1 : files) {
            if (file1.isFile()){
                System.out.println(file1.getAbsolutePath());
            }
​
        }
​
    }
    public static void listFile5(File file){
​
        File[] files = file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
             //   System.out.println(dir.getAbsolutePath()+"...."+name);
                // 需要重新构造file
                File file1=new File(dir,name);
                if (file1.isFile()){
                   return name.endsWith(".html");
                }else  if(file1.isDirectory()){
                    listFile5(file1);
                }
                return true;
            }
        });
        for (File file1 : files) {
            if (file1.isFile()){
                System.out.println(file1.getAbsolutePath());
            }
        }
​
    }
}

File类的常用方法

list(), listFiles, list(FilenameFilter) , listFile(FileFilter or FilenameFilter)

注意递归问题!

文件的递归删除

目录必须为空,该目录才能删除。

所以要删除一个目录先删除里面的东西

package corelesson4;
​
import java.io.File;
​
public class FileDemo3 {
​
    public static void main(String[] args) {
​
        File file = new File("E:\\Myeclipse\\MyEclipse2014汉化\\features");
        deleteFile(file);
    }
    public static void deleteFile(File file){
        File[] files = file.listFiles();
        for (File file1 : files) {
            if (file1.isFile()){
                System.out.println(file1.getAbsolutePath());
                file1.delete();// 如果是文件直接删除
            }
            else if(file1.isDirectory()){
                deleteFile(file1);// 递归删除
            }
        }
        //到这里为止删除的都是子目录,下面删除父目录
        System.out.println(file.getAbsolutePath());
        file.delete();
​
    }
}

3,字节流 (文件读写操作)

字节流-------------- > 读写以字节单位(各种类型 mp3,MP4

,图片 文本等)

字符流-----------------> 读写以字符单位(只适合 文本文件的读写)

输入流----》读操作的

输出流----》写操作的

3,1 以字节为单位的输入输出流 FileInputStream

输入流: InputStream(读)(它是一个抽象类)

read() 重载三个重要方法

------->FileInputStream(子类) :把文件作为字节流进行读操作

------->BufferedInputStream(先读到内存,再从内存中读取,多了一个缓冲区的功能)

          ------->PipedInputStream  : 管道流
​
          ------->DataInputStream   : 可以直接输出很多数据类型的方法,,分析读写的原理
​
          ------->System.in  : 从键盘读

如果是FileOutStream Out

out.write(10000); write 方法只能写一个字节

但是10000 是32 个字节,所以它只写后8位;

所以DataOutputStream dos 对象的writeInt 方法一定是利用out 对象的write 方法写4 次写8位

writeInt 方法内部一定是:

out.write(10000>>24)

out.write(10000>>16)

out.write(10000>>8)

out.write(10000)

输出流 : OutputStream(写) 同理读也是读4次

write () 重载三个写的方法

------->FileOutputStream(子类) :把文件作为字节流进行写操作

------->BufferedOutputStream

------->PipedOutputStream

      ------->DataOutputStream  
​
          ------->System.out  :-------> PrintStream 输出流

package corelesson4;

        import javax.print.DocFlavor;
        import java.io.FileInputStream;
        import java.io.FileNotFoundException;
        import java.io.FileOutputStream;
        import java.io.IOException;

public class StreamDemo1 {
    public static void main(String[] args) throws IOException {
        // test1();
        //test2();
        test3();
    }


    // 所有的IO操作都会产生 IOEx产品提on
    public static void test1(){
        FileInputStream in=null;
        try {
            in = new FileInputStream("H:\\WorkspacesMyEclipse2014\\ssh_test1\\src\\org\\sshtest\\entities\\UserInfo.java");
            FileOutputStream out = new FileOutputStream("D:\\1.txt"); // 读文件 然后写到这个文件中
            //1.txt 不存在就创建,如果存在先删除 在创建
            /**
             * //read 一个字节一个字节的读
             * 问题1:对于单字节编码 没有问题,对于多字节的文字会有乱码
             * 问题2:对于大文件,读取效率比较低
             */
            int c;
            while ((c=in.read())!=-1){
                //怎么读的就怎么写
                out.write(c);
                System.out.print((char)c);
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if (in!=null){
                try {
                    // 最后关闭
                    in.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 这里先不关心异常
    public static void test2() throws IOException {
        FileInputStream in = new FileInputStream("H:\\WorkspacesMyEclipse2014\\ssh_test1\\src\\org\\sshtest\\entities\\UserInfo.java");
        FileOutputStream out = new FileOutputStream("D:\\11.txt"); // 读文件 然后写到这个文件中

        byte[] b = new byte[1024 * 5];
        //读到这个数组,从第0个位置开始放 放到哪里,

        //int bytes = in.read(b, 0, b.length);//返回读到字节的个数
        // 往b字节数组中放 最多放b.length个
        // 相当于开辟了一个内存空间,把读到的放进去
        //  相当于批量读取,效率高
        //  String s = new  String (b,0,bytes);
        //System.out.println(s);
        // 方式二
        int bytes;
        // 这样写的话就是bytes 中放满了 输出 然后清空 再放 ,在放满再输出,在放
        while ((bytes=in.read(b,0,b.length))!=-1){
            // 然后构造字符串, 从内存中读,如果不是文本文件 可以不用打印到控制台
            String s=new String(b,0,bytes);
            // 写的话就直接卸载文件中 不需要构造再写
            out.write(b,0,bytes);
            System.out.println(s);
        }



    }
    //方式三
    public static void test3() throws IOException {
        /**
         * 缺点:如果文件很大 开辟的内存空间很大 建议都用test2 方法写文件。
         */
        FileInputStream in = new FileInputStream("H:\\WorkspacesMyEclipse2014\\ssh_test1\\src\\org\\sshtest\\entities\\UserInfo.java");
        FileOutputStream out = new FileOutputStream("D:\\21.txt"); // 读文件 然后写到这个文件中

        int length = in.available();// 返回可读的字节数
        // 构造字节数组
        byte[] b = new byte[length];
        int read = in.read(b);
        String s= new String (b,0,b.length);
        System.out.println(s);
        //这里直接写在文件中
        out.write(b);
        in.close();
    }
    //不管是读写  建议使用 第二种方式。

    public static void test4(){
        FileInputStream in = null;
        try {
            in = new FileInputStream("D:\\aa.txt");
            FileOutputStream out = new FileOutputStream("D:\\bb.txt"); // 读文件 然后写到这个文件中

            byte[] b = new byte[1024 * 5];
            int bytes;
            while ((bytes=in.read(b,0,b.length))!=-1){
                String s=new String(b,0,bytes,"utf-8");//这里解决字符编码不一样的问题

                out.write(b,0,bytes);
                System.out.println(s);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

------->BufferedInputStream

------->BufferedInputStream(先读到内存,再从内存中读取,多了一个缓冲区的功能)

内部源码有一个:protected volatile byte buf[]; 数组

package corelesson4;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class StreamDemo2 {
    public static void main(String[] args) {
        try {
            BufferedInputStream in = new BufferedInputStream(new FileInputStream("D:\\1.txt"));
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\a1.txt"));
            byte[] bytes = new byte[10000];

            int c;
            //内部操作先把文件放置到 内存中(缓冲区字节数组),所以也不太适合太大的文件
            //我们读的时候充内存中读取。
            while ((c=in.read(bytes,0,bytes.length))!=-1){
                //把缓冲区中读到的内容写入磁盘,刷新缓冲区才会写入磁盘
                out.write(bytes,0,c);
                out.flush();//刷新缓冲区 ,缓冲区大小满了 会自动刷新。

            }
             in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

------->PipedInputStream : 管道流

PipedInputStream (PipedOutputStream())

PipedInputStream (PipedInputStream() )

out写出的数据正好被in 读到

package corelesson4;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class StreamDemo3 {
    public static void main(String[] args) {
        // 管道流
        try {
            PipedInputStream in = new PipedInputStream();
            PipedOutputStream out = new PipedOutputStream(in);
            Send send = new Send(out);
            Receive rec = new Receive(in);
            send.send();
            rec.rec();
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class Send{
OutputStream out;
    public Send(OutputStream out) {
        super();
        this.out = out;
    }
    public void send(){
        byte value=(byte)(Math.random()*100);
        try {
            System.out.println("send the value is: "+value);
            out.write(value);//写出去
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class Receive{
    InputStream in;
    public Receive(InputStream in) {
        super();
        this.in = in;
    }
    public void rec(){
        try {
            byte value  = (byte)in.read();
            System.out.println("rec the value is: "+value);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

将来 两个需要交互的时候 一边写,正好被一边读到。

------->DataInputStream

package corelesson4;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class StreamDemo4 {
    public static void main(String[] args) {
        wirte();
        read();
    }
     public static void wirte(){

         try {
             //把1.txt文件作为字节输出流,并且直接写java的数据类型
           //  DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\1.txt"));

             // 都是一个字节流装饰出来的,称装饰模式
             // 把 1.txt 文件作为字节输出流,并且先写入缓冲区,可以直接写数据类型
           //  DataOutputStream dos1 = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:\\1.txt")));
          // 发现 特殊功能流类都是基本的流,嵌套构造出来,其实是一种装饰模式。
             // 优点 直接写数据类型
             DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\1.txt"));
             // 写一个int 类型
             dos.writeInt(10000);
             //写一个Boolean 类型
             dos.writeBoolean(true);
             //写一个Double类型
             dos.writeDouble(10.03);
             //写一个字符串类型
             dos.writeUTF("HELLO");
             dos.close();




         } catch (IOException e) {
             e.printStackTrace();
         }

     }
    public static void read(){
        try {
            DataInputStream dis = new DataInputStream(new FileInputStream("D:\\1.txt"));
           // 对应的读出来
            System.out.println(dis.readInt());
            System.out.println(dis.readBoolean());
            System.out.println(dis.readDouble());
            System.out.println(dis.readUTF());

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

------->System.in : 从键盘读

package corelesson4;
import java.io.IOException;

public class StreamDemo5 {
    public static void main(String[] args) {
        byte[] bytes = new byte[10000];
        System.out.println("请输入: ");
        try {
           while (true){
               int read = System.in.read(bytes, 0, bytes.length);
               String str = new String(bytes, 0, read);
               if ("end".equals(str)){
                   break;
               }
               System.out.println(str);
           }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

-------> PrintStream 输出流

文件找那个追加写内容

FileOutputStream("D:\2.txt"),true); //后面这里为true 如果文件存在 就会追加写在里面

package corelesson4;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class StreamDemo6 {
    public static void main(String[] args) {
        try {
            PrintStream ps = new PrintStream(new FileOutputStream("D:\\2.txt"));
            //FileOutputStream("D:\\2.txt"),true); //后面这里为true 如果文件存在 就会追加写在里面
            // System.out 目标是标准输出设备 System.in 标准输入设备 就是我们的控制台
         ps.println("hello");
         ps.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4 字符流,(文本操作)

字符流(文本操作)------>都是有字节流构造出来的(用到的是适配器模式)

输入流 ------->Reader

---------------->InputStreamReader

----------------> FileReader

----------------> BufferedReafer   一次可以读一行字符字符串

输出流-------->Writer

---------------->OutputStreamReader

----------------> FileWriter

----------------> BufferedWriter一次可以写一行字符字符串

---------------------------------PrintWriter

主要的方式也是读和写

不管是字符流还是字节流我们需要关注的是输入和输出的方法。

1, ------>InputStreamReader

bufferedReader

package corelesson4;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class RWDemo1 {
    public static void main(String[] args) {
        RWStream1();
        RWStream2();

    }

    public static void RWStream1(){
        try {
            InputStreamReader in = new InputStreamReader(new FileInputStream("D:\\11.txt"));
            OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\\11w.txt"));

            // 一个字符一个字符的读
            int c;
            while ((c=in.read())!=-1){
                // c 读到的是一个字符  这样读取没有乱码 ,默认是一样的
                System.out.print((char)c);
                out.write(c);
                out.flush();// 字符流都是有缓冲区的 不要忘记了刷新
            }
            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void RWStream2(){
        try {
            InputStreamReader in = new InputStreamReader(new FileInputStream("D:\\11.txt"));
            OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\\11w1.txt"));
            char[] c = new char[1000];
            int len;
             while ((len=in.read(c,0,c.length))!=-1){
                 // 然后拿字符数组来构造成字符串
                 String s= new String (c,0,c.length);
                 System.out.print(s);
                 out.write(c,0,len);
                 out.flush();
             }

            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

2, ---------------> FileReader

package corelesson4;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class RWDemo2 {
    public static void main(String[] args) {
        RWStream1();
    }
    public static void RWStream1(){

        try {
            //这样构造就很方便,缺点 不能指定编码
            FileReader fr = new FileReader("D:\\11.txt");
            FileWriter fw = new FileWriter("D:\\11w2");
            char[] chars = new char[1000];
            int len;
            while ((len=fr.read(chars,0,chars.length))!=-1) {
                // 构造成字符串打印熬控制台
                String s = new String(chars, 0, chars.length);
                System.out.print(s);
                fw.write(chars,0,len);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }


    }

}

3,-----> BufferedReafer 一次可以读一行字符字符串

Filewriter

注意: 读一行readLine ,换行 newLine,刷新缓冲 bw.flush();

package corelesson4;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public class RWDemo3 {
    public static void main(String[] args) {
        try {
          //  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\11.txt")));
            BufferedReader br = new BufferedReader(new FileReader("D:\\11.txt"));
            BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\11w3.txt"));

            // 有一个重要的方法就是readLine()方法一次可以读一行
            String s=null;
            while ((s=br.readLine())!=null){
                System.out.print(s);// 一次读一行不读取换行
                // 读一行写一行
                bw.write(s);
                // 读一行还下一行开始写
                bw.newLine();
                // 读完一行刷新依稀缓存
                bw.flush();
            }
            br.close();
               bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

PrintWriter也比较常用

package corelesson4;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class RWDemo4 {
    public static void main(String[] args) {
        try {


          //  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\11.txt")));
            BufferedReader br = new BufferedReader(new FileReader("D:\\11.txt"));
            PrintWriter pw = new PrintWriter(new FileOutputStream("D:\\44.txt"),true);//加true  自动刷新 不用非手动flush了
            // 有一个重要的方法就是readLine()方法一次可以读一行
            String s=null;
            while ((s=br.readLine())!=null){
                System.out.print(s);// 一次读一行不读取换行
                // 读一行写一行
                pw.println(s);
            }
            br.close();
            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

字节流决定 输入输出的目标, 字符流呢就是适配它自己的类型。

从键盘一次读一行 读到end 及结束

最内层决定了它的输入输出目标

package corelesson4;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class RWDemo5 {
    public static void main(String[] args) {
        try {
    //  从键盘一次读一行   读到end  及结束
            // 输入输出  是由最内层来决定的。  这个过程就是一个适配器的过程。

            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

          while (true){
              String str=br.readLine();
              System.out.println(str);
              if("end".equals(str)){
                  break;
              }
          }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

5,RandomaccessFile 随机访问的流类

一种比较早的方式

package corelesson4;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RWDemo6 {
    public static void main(String[] args) {

        try {
            RandomAccessFile raf = new RandomAccessFile("D:\\44.txt","rw");

            System.out.println(raf.getFilePointer());
            raf.writeInt(1000);
            System.out.println(raf.getFilePointer());
            // 相当于写了
            raf.write(1000>>24);
            raf.write(1000>>16);
            raf.write(1000>>8);
            raf.write(1000);
            System.out.println(raf.getFilePointer());

            raf.writeUTF("hello");  //写入hello
            System.out.println(raf.getFilePointer());// 查看hello  所在的位置

       byte[]  b=new byte[10000];
            int bytes = raf.read(b, 0, b.length);//   返回的是字节的个数


        } catch (IOException e) {

           e.printStackTrace();
        }
    }

}

6.java.util.Properties(并不是IO种的类)

实际使用需要和IO结合在一起

资源文件已properties 作为文件的扩展名

文件的内容 是以key =value 的方式进行存放的

properties 的使用

package corelesson4;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo1 {

    public static void main(String[] args) {


        Properties prop = new Properties();
           //加载这个文件,  把这个文件转化为输入流。
        try {

            prop.load(new FileInputStream("这里 放properties  文件"));

            for (Object o : prop.keySet()) {
                  String key=(String)o;
                System.out.println(key+"="+prop.get(key));

            }

            // 资源文件中的内容是可以看见的  key 就是已知的

            //可以直接这样用
            System.out.println( prop.getProperty("key"));// 直接拿到里面的值

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

properties 基本使用 升级2

package corelesson4;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo2 {

    public static void main(String[] args) {


        Properties prop = new Properties();
        //加载这个文件,  把这个文件转化为输入流。
        try {
  //   缺点  :  这样写 路径就写死了  项目一旦移动就找不到路径了
           // prop.load(new FileInputStream("这里 放properties  文件"));
              //  使用class  得到当前类的字节流
            //getResourceAsStream  得到的是classPath 路径
            //  用哪个类的 类类型呢? 都是可以的在同一包下什么类的类类型 的classpath  都是一样的
            prop.load(PropertiesDemo2.class.getResourceAsStream(""));  //  这种方式 用的多一些

        //  还有一种 是加载包下的properties 文件 直接输入包下的文件

           //class.getClassLoader()  获得的是类加载器
             prop.load(PropertiesDemo2.class.getClassLoader().getResourceAsStream("corelesson4/aa.properties"));



            //可以直接这样用
            System.out.println( prop.getProperty("key"));// 直接拿到里面的值

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

资源文件 将来 在设计中 用来解耦的。 一般和反射结合使用。

7, IO 序列化问题

序列化---->对象系列化

(对象进行存储or 在网络中进行传递,该对象必须进行序列化)

Java.ioObjectOutputStream

Java.ioObjecInputStream

java.io.Serializable 如果一个对象想要 序列化 必须实现这个序列化的接口

该接口只是一个标准规范 ,没有任何方法。

7.2 transient 关键字

如果该对象的属性用transient 关键字来修饰,那么 该属性不会做jvm 默认的序列化工作

package corelesson4;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SeriDemo1 {
    public static void main(String[] args) {
        Student stu = new Student(1000,"zhangshan",20);
        try {
            //写入文件
            ObjectOutputStream out = new ObjectOutputStream(
                    new FileOutputStream("D:\\55.txt"));
                out.writeObject(stu);//直接写入一个对象
                   out.flush();
                   out.close();
                   //读操作
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\44.txt"));
       Student stu1=(Student)in.readObject();
            System.out.println(stu1);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }

}

7.3 集合中的 类是如何序列化的 比如ArrayList

ArrayList 中有数组,且数组不一定放满元素, 所以没有必要吧整个数组做序列化。只需要序列化有效元素。

用了以下两个方法签名做了 序列化和反序列化的工作。

Private void readObject (java.io.ObjectInputStream stream)

throws IOExcrption,ClassNoFoundException;

Private void writeObject (java.io.ObjectOutputStream stream)

throws IOExcrption;

这样的新能比较高

7.4 java 实现接口,继承 都有传递性

如果父类 实现了Serializable 接口,那么其子类都可以序列化

需要注意的是:

如果父类是可序列化的,那么在反序列化子类的时候不会调用父类

的构造函数,如果父类是不可序列化的,而子类是可以序列化的,那么在子类反序列化时,会调用父类的构造函数。

package corelesson4;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

public class SeriDemo2 {
    public static void main(String[] args) {

           // 1 序列化
        try {
//            ObjectOutputStream out = new ObjectOutputStream(
//
//            new FileOutputStream("D:\\66.txt"));
//           // 2,创建对象
//            C c = new C();
//            //3 ,接下来 做序列化工作。
//            out.writeObject(c);
//           out.flush();
//           out.close();
           //4,以上就是他的序列化

            //5 .接下来做反序列化, 保存到那个文件,就到哪个文件去取
            ObjectInputStream out = new ObjectInputStream(new FileInputStream("D:\\66.txt"));
            C c=(C)out.readObject();
            System.out.println(c);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

class A implements Serializable{
    public A() {

        System.out.println("a.....");
    }
}

class B extends  A{
    // 这样 B类是可以被序列化的

    public B() {
        System.out.println("b......");
    }

}
class C extends  B{
    public C() {
        System.out.println("c.....");
    }
}

7.5 java 中 有一个克隆的功能Object 类中已经提供了

一个类的对象要进行克隆直接实现Cloneable 接口即可

Cloneable 也是一个标准 没有具体的方法;

package corelesson4.prototype;

public class CloneTest {
    public static void main(String[] args) {
        User user = new User();
        User user1=null;
        Address address = new Address();
        user.setAddress(address);
        //现在就可以克隆新的对象
        try {

            // 这样就克隆 一个新的对象出来了
            user1 =(User)user.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        System.out.println(user==user1);
        System.out.println(user.getAddress()==user1.getAddress());
    }
}

称为: 浅克隆 or 浅拷贝

浅拷贝主要是内部引用指向同一个对象的内存。

比如 A---->b1 ---->C对象

B ------->b2----->C 对象 内部指向的都是C对象同一块内存 称为浅拷贝

深拷贝

1,对当前对象序列化的工作,

深克隆or 深拷贝 , 通过序列化和反序列化的方式

这其实是一个设计模式---》原型模式

7.6 结合集合使用IO

案例 有如下文本文件

1,zhangshan,28
2,lishi,23
3,wangwu,19
4,zhaoliu,24
5,zhangshan,28
6,zhangshan,28
7,lishi,23
8,zhangshan,28
9,tianqi,30

要求统计姓名出现的次数 ,并且按照次数降序输出,如果次数相同,按照名字升序。

思路: 一次读一行,然后进行字符串分割,把名字放入map 集合中

统计次数,然后 用treeSet 排序

package corelesson4;
​
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
​
public class works {
    public static void main(String[] args) {
        getStuduens();
    }
​
    public static HashMap<String ,Integer> getStuduens(){
​
        HashMap<String, Integer> map = new HashMap<>();
        try {
            BufferedReader br = new BufferedReader(new FileReader("D:\\aa.txt"));
​
            String str= null;
            while ((str=br.readLine())!=null){
                 String[] ss=str.split(",");
                for (String s : ss) {
                    System.out.print(s+" ");
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
​
        return  null;
    }
​
}

IO 专题主要是这些 后续有补充的在补充笔记!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值