JavaSe之IO流学习笔记

1.文件操作

创建文件

//方式1 new File(String pathname)
@Test
public void create01() {
    String filePath = "e:\\news1.txt";
    File file = new File(filePath);
    try {
        file.createNewFile();
        System.out.println("文件创建成功");
    } catch (IOException e) {
        e.printStackTrace();
    }
}
    //方式2 new File(File parent,String child) //根据父目录文件+子路径构建
    //e:\\news2.txt
    @Test
    public  void create02() {
        File parentFile = new File("e:\\");
        String fileName = "news2.txt";
        //这里的file对象,在java程序中,只是一个对象
        //只有执行了createNewFile 方法,才会真正的,在磁盘创建该文件
        File file = new File(parentFile, fileName);
        try {
            file.createNewFile();
            System.out.println("创建成功~");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //方式3 new File(String parent,String child) //根据父目录+子路径构建
    @Test
    public void create03() {
        //String parentPath = "e:\\";
        String parentPath = "e:\\";
        String fileName = "news4.txt";
        File file = new File(parentPath, fileName);
        try {
            file.createNewFile();
            System.out.println("创建成功~");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

获取文件信息

//先创建文件对象 	
	File file = new File("e:\news1.txt");
	//调用相应的方法,得到对应信息
    System.out.println("文件名字=" + file.getName());
    //getName、getAbsolutePath、getParent、length、exists、isFile、isDirectory
    System.out.println("文件绝对路径=" + file.getAbsolutePath());
    System.out.println("文件父级目录=" + file.getParent());
    System.out.println("文件大小(字节)=" + file.length());
    System.out.println("文件是否存在=" + file.exists());//T
    System.out.println("是不是一个文件=" + file.isFile());//T
    System.out.println("是不是一个目录=" + file.isDirectory());//F

2.IO流

inputstream 字节输入流 reader(字符输入流)

outputstream 字节输出流 writer(字符输出流)

1.FileInputStream介绍

   //单个字节的读取,效率比较低
    @Test
    public void readFile01() throws IOException {
        String filePath = "f:\\hello.txt";
        FileInputStream fileInputStream=null;
        int readData=0;
        try {
            //创建字节输入流对象
            fileInputStream = new FileInputStream(filePath);
            //如果返回-1,表示读取完毕
            while((readData=fileInputStream.read())!=-1){
                System.out.print((char)readData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭流释放资源
            fileInputStream.close();
        }
    }

    @Test
    public void readFile02() throws IOException {
        FileInputStream fileInputStream = null;
        int readLen = 0;
        //定义一个字符数组,每次读取8个字节效率高
        byte[] bytes = new byte[8];
        String filePath = "f:\\hello.txt";
        try {
            //创建字节输入流对象
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取最多 b.length 字节的数据到字节数组。 此方法将阻塞,直到某些输入可
            //如果返回-1,表示读取完毕
            //如果读取正常,返回实际读取的字节数
            while ((readLen = fileInputStream.read(bytes)) != -1) {
                System.out.print(new String(bytes, 0, readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流释放资源
            fileInputStream.close();
        }
    }

2.FileOutputStream介绍

用于将数据写入到文件之中

  /**
         * 演示使用FileOutputStream 将数据写到文件中,
         * 如果该文件不存在,则创建该文件
         */
        @Test
        public void writeFile() {
            //创建 FileOutputStream对象
            String filePath = "e:\\news1.txt";
            FileOutputStream fileOutputStream = null;
            try {
                //得到 FileOutputStream对象 对象
                //说明
                //1. new FileOutputStream(filePath) 创建方式,当写入内容是,会覆盖原来的内容
                //2. new FileOutputStream(filePath, true) 创建方式,当写入内容是,是追加到文件后面
                fileOutputStream = new FileOutputStream(filePath, true);
                //写入一个字节
                //fileOutputStream.write('H');//
                //写入字符串
                String str = "hello,world!";
                //str.getBytes() 可以把 字符串-> 字节数组
                //fileOutputStream.write(str.getBytes());
                /*
                write(byte[] b, int off, int len) 将 len字节从位于偏移量 off的指定字节数组写入此文件输出流
                 */
                fileOutputStream.write(str.getBytes(), 0, str.length());
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

3.FileReader 相关方法:

  1. new FileReader(File/String)

2)read:每次读取单个字符,返回该字符,如果到文件末尾返回-1

String path="f:\\a.txt";
FileReader fileReader=null;
int data=0;
try {
    fileReader=new FileReader(path);
    //单个字符读取
    while((data = fileReader.read())!=-1){
        System.out.print((char)data);
    }
} catch (IOException e) {
    e.printStackTrace();
}finally {
    fileReader.close();
}

3)read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1

@Test
public void readFile01() throws IOException {
    String path="f:\\a.txt";
    FileReader fileReader=null;
    int readLen=0;
    char[] buf=new char[8];
    try {
        fileReader=new FileReader(path);
        //单个字符读取
        while((readLen = fileReader.read(buf))!=-1){
            System.out.print((new String(buf,0,readLen)));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        fileReader.close();
    }
}

相关API:
1)new String(char[]):将char[]转换成String

2)new String(char[],off,len):将charll的指定部分转换成String

4.FileWriter 常用方法

1)new FileWriter(File/String):覆盖模式,相当于流的指针在首端

2)new FileWriter(File/String,true):追加模式,相当于流的指针在尾端

3)write(int):写入单个字符

4)write(char[]):写入指定数组

5)write(char[],off,len):写入指定数组的指定部分

6)write(string):写入整个字符串

7)write(string,off,len):写入字符串的指定部分

   @Test
        public void fileWriter_01(){
            String path="f:\\hello.txt";
            FileWriter fileWriter=null;
            char[] chars={'a','b','c'};
            try {
                fileWriter=new FileWriter(path);
                //写入单个字符
    //            fileWriter.write('z');
                //写入一个字符数组
                fileWriter.write(chars);
                //写入整个字符串
                fileWriter.write("张佳亮".toString(),0,3);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //一定要关闭流,才能将数据真正的写进去
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("程序结束");
        }

相关API:String类:toCharArray:将String转换成char[]

注意:FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定的文件!

5.节点流和处理流

  • 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
  • 处理流(也叫包流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如:BufferedReader、BufferedWriter

节点流和处理流的区别和联系

  • 节点流是底层流/低级流,直接跟数据源相接。便的方法来完成输入输出。
  • 处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方处理流(也叫包装流)对节点流进行包装,使用了修 饰器设计模式,不会直接与数据源相连

处理流的功能主要体现在以下两个方面:

  • 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
  • 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
    BufferedReader 和 BufferedWrite
String filePath = "e:\\a.java";
        //创建bufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        //读取
        String line; //按行读取, 效率高
        //说明
        //1. bufferedReader.readLine() 是按行读取文件
        //2. 当返回null 时,表示文件读取完毕
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        //关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流
        bufferedReader.close();
 @Test
    public void testBufferWriter() throws IOException {
        String filePath = "e:\\ok.txt";
        //创建BufferedWriter
        //说明:
        //1. new FileWriter(filePath, true) 表示以追加的方式写入
        //2. new FileWriter(filePath) , 表示以覆盖的方式写入
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
        bufferedWriter.write("hello, mss!");
        bufferedWriter.newLine();//插入一个和系统相关的换行
        bufferedWriter.write("hello2, mss!");
        bufferedWriter.newLine();
        bufferedWriter.write("hello3, mss!");
        bufferedWriter.newLine();
        //说明:关闭外层流即可 , 传入的 new FileWriter(filePath) ,会在底层关闭
        bufferedWriter.close();
    }

BufferedInputStream 和 BufferedOutputStream

 //处理流实现文件的拷贝
    String srcPath = "f:\\hnt.png";
    String destPath = "f:\\hnt01.png";
    BufferedInputStream bis= null;
    BufferedOutputStream bos = null;
    try {
        bis=new BufferedInputStream(new FileInputStream(srcPath));
        bos=new BufferedOutputStream(new FileOutputStream(destPath));
        //循环读取
        byte[] bytes=new  byte[1024];
        int readLen = 0;
        while((readLen=bis.read(bytes))!=-1){
            bos.write(bytes,0,readLen);//边读边取
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

8.对象流
定义:就是能够将基本数据类型或者对象进行序列化和反序列化操作,提供了对基本类型或对象类型的序列化和反序列化的方法

  • ObjectOutputStream ,提供序列化功能
  • ObjectInputStream,提供反序列化功
    序列化和反序列化
  •   序列化就是在保存数据时,保存数据的值和数据类型
    
  •   反序列化就是在恢复数据时,恢复数据的值和数据类型
    

需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:
Serializable // 这是一个标记接口, 没有方法
Externalizable // 该接口有方法需要实现,因此我们一般实现上面的 Serializable接口
序列化操作

@Test
        //演示ObjectOutputStream的使用, 完成数据的序列化
        public void objectOutput() throws IOException {
            String path="E://add.dat";
            ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(path));
            //序列化数据到 e:\data.dat
            oos.writeInt(100);// int -> Integer (实现了 Serializable)
            oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)
            oos.writeChar('a');// char -> Character (实现了 Serializable)
            oos.writeDouble(9.5);// double -> Double (实现了 Serializable)
            oos.writeUTF("张三");//String
            //保存一个dog对象
            oos.writeObject(new Dog("旺财", 10, "日本", "白色"));
            oos.close();
            System.out.println("数据保存完毕(序列化形式)");
        }

反序列化操作

@Test
    public void objectInputStream() throws IOException, ClassNotFoundException {
        String path="E://add.dat";
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(path));
        //2.读取,注意顺序
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
        System.out.println(ois.readObject());
        System.out.println(ois.readObject());
        System.out.println(ois.readObject());
        //3.关闭
        ois.close();
        System.out.println("以反序列化的方式读取(恢复)ok~");
    }

关于序列化与反序列化对象操作

如果需要序列化某个类的对象,实现 Serializable
 public class Dog implements Serializable {
        private String name;
        private int age;
        //序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
        private static String nation;
        private transient String color;
        //序列化对象时,要求里面属性的类型也需要实现序列化接口
        private Master master = new Master();
        //serialVersionUID 序列化的版本号,可以提高兼容性
        private static final long serialVersionUID = 1L;
    
        public Dog(String name, int age, String nation, String color) {
            this.name = name;
            this.age = age;
            this.color = color;
            this.nation = nation;
        }
        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", color='" + color + '\'' +
                    '}' + nation + " " +master;
        }
        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;
        }
    }

注意事项和细节说明

  • 读写顺序要一致
  • 要求序列化或反序列化对象,需要 实现 Serializable
  • 序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
  • 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
  • 序列化对象时,要求里面属性的类型也需要实现序列化接口
  • 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
  1. 标准输入输出流
    System.in 标准输入流
    System.out 标准输出流
    10.转换流
  • InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流)
  • OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
  • 处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流
  • 可以在使用时指定编码格式(比如 utf-8,gbk,gb2312,ISO8859-1 等)
@Test
    public void inputStream() throws IOException {
        String path="e://news1.txt";
        //1. 把 FileInputStream 转成 InputStreamReader
        //2. 指定编码 gbk
        InputStreamReader is=new InputStreamReader(new FileInputStream(path),"utf-8");
        //3.把 InputStreamReader 传入 BufferedReader
        BufferedReader br=new BufferedReader(is);
        /**
        将上面的第二部与第三步连起来写
        BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(path),"utf-8"));
        */
        System.out.println(br.readLine());
        //5. 关闭外层流
        br.close();
    }
/**
 * 将字节流转换成为字符流,并指定编码方式
 * @param args
 */
  @Test
    public void outputStream() throws IOException {
        String path="e://news1.txt";
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream(path),"utf-8");
        osw.write("今天适合出去玩耍");
        osw.close();
        System.out.println("添加文件成功");
    }

11.打印流

打印流只有输出流,没有输入流,在默认情况下,PrintStream 输出数据的位置是标准输出

//字节打印流
PrintStream out = System.out;
out.print("你好");
out.write(12);
//修改打印输出的位置
System.setOut(new PrintStream("f:\\f1.txt"));
out.write(122);
out.close();

//字符打印流
PrintWriter printWriter=null;
printWriter = System.setOut("f:\\f1.txt");
printWriter.print("hi, 北京你好~~~~");
printWriter.close();//flush + 关闭流, 才会将数据写入到文件..

12.Properties

专门用于读写配置文件的集合类
配置文件的格式:键=值
注意:键值对不需要有空格~值不需要用引号一起来。默认类型是String

Properties的常见方法

  • load:加载配置文件的键值对到Properties对象
  • list:将数据显示到指定设备
  • getProperty(key):根据键获取值
  • setProperty(key,value):设置键值对到Properties对象
  • store:将Properties中的键值对存储到配置文件,在idea 中,保存信息到配置文件,如果含有中文,会存储为unicode码
    http://tool.chinaz.com/tools/unicode.aspx unicode码查询工具
	//1. 创建 Properties 对象
   Properties properties = new Properties();
	//2. 加载指定配置文件
   properties.load(new FileReader("F:\\workstudy\\hspJavaSe\\chapter0\\src\\mysql.properties"));
	//3. 把 k-v 显示控制台
   properties.list(System.out);
	//4. 根据 key 获取对应的值
   String user = properties.getProperty("user");
   String pwd = properties.getProperty("pwd");
   System.out.println("用户名=" + user);
   System.out.println("密码是=" + pwd);
	//使用 Properties 类来创建 配置文件, 修改配置文件
	Properties properties = new Properties();
	properties.setProperty("charset", "utf8"); 
	properties.setProperty("user", "汤姆");//注意保存时,是中文的 unicode码值
	properties.setProperty("pwd", "888888"); //将 k-v 存储文件中即可 
	properties.store(new FileOutputStream("src\\mysql2.properties"), null);
 	System.out.println("保存配置文件成功~");
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值