IO流用来处理设备之间的数据传输.可以实现文件复制,上传文件和下载文件.

Jdk提供的流继承了四大类:InputStream(字节输入流),OutputStream(字节输出流),Reader(字符输入流),Writer(字符输出流)。

对文件进行操作:FileInputStream(字节输入流),FileOutputStream(字节输出流),FileReader(字符输入流),FileWriter(字符输出流)

对管道进行操作:PipedInputStream(字节输入流),PipedOutStream(字节输出流),PipedReader(字符输入流),PipedWriter(字符输出流)

PipedInputStream的一个实例要和PipedOutputStream的一个实例共同使用,共同完成管道的读取写入操作。主要用于线程操作。

字节/字符数组:ByteArrayInputStream,ByteArrayOutputStream,CharArrayReader,CharArrayWriter是在内存中开辟了一个字节或字符数组。

Buffered缓冲流::BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,是带缓冲区的处理流,缓冲区的作用的主要目的是:避免每次和硬盘打交道,提高数据访问的效率。

转化流:InputStreamReader/OutputStreamWriter,把字节转化成字符。

数据流:DataInputStream,DataOutputStream。

文件中的内容是无法直接操作的,所以要把文件中的数据读取到内存中,然后修改内存中的数据,修改完成后再由内存写入到文件中.

这里我们以操作文件为例子,主讲FileReader和FileWriter以及他们的缓冲流.

IO流

IO流可以吧数据存储到文件,也可以从文件中读取数据

输出流(写数据用)

FileWritervoid write(String str)  //写一个字符串数据
void write(String str,int index,int len)  //写一个字符串中的一部分数据
void write(int ch)  //写一个字符数据,写int类型好处是既可以写char类型的数据,也可以写插入对应的int类型数据
void write(char[] chs)  //写一个字符数据
void write(char[] chs,int index,int len)   //写一个字符数组一部分

步骤

往文件中写数据(对于cpu来说是往外输出)-->用输出流-->-->FileWriter
输出流写数据的步骤:A.创建输出流对象B.调用输出流对象写数据的方法C.释放资源

构造方法,创建输出流对象
    FileWriter(String fileName)  //fileName为文件路径不写盘符为相对路径(相对项目)

  FileWriter(String fileName,boolean append)   //输出到文件时添加到文件尾
  成员方法
    void write(String str)  //调用流对象写数据方法
    //数据没有直接写到文件中,其实是写到了内存缓冲区
    void flush()  //将内存缓冲区中的数据写入文件
    void close()  //关闭流,不然会一直占用文件无法操作文件.

输入流(读数据用)

FileReader

构造方法FileReader(String fileName)
成员方法int read()    //一次读取一个字符,返回的是字符的int值.如果没有数据了,返回-1int read(char[] cbuf)  //返回的int是实际读取的字符个数,cbuf是

步骤

A.创建输入流
B.调用输入流对象的读数据方法
C.关闭流

close()和flush()方法区别

  A.flush()刷新缓冲区.刷新后流对象还可以继续使用
  B.close()先刷新缓冲区,然后通知系统释放资源.流对象不可以再使用.

向文本文件中写字符时换行的方式mac是\r,linux是\n,windows是\r\n

文件复制(传输)时先用FileReader读取数据,再用FileWriter写数据.即先I在O.

        //创建输入流对象FileReader fr  = new FileReader("source.txt");//创建输出流对象FileWriter fw = new FileWriter("target.txt");/*读写数据int ch;while((ch=fr.read())!=-1) {   //读取到了返回字符int值,读不到返回-1fw.write(ch);}*///读写数据char[] chs = new char[1024];  //一般写1024的整数倍int len;while((len=fr.read(chs))!=-1) {  //读取到字符数组时返回数组长度,读取不到返回-1fw.write(chs, 0, len);  //最后一次读取的len可能小于1024.最后一次读取的放入char数组中覆盖上一次读取的前半部分,没覆盖的后半部分仍然是上次读取的内容,所以要从0读到len,len-1024是倒数第二次读取的内容.}//释放资源
        fw.close();fr.close();

char数组内存中的数据如下

        FileReader fr = new FileReader("source.txt");//调用输入流对象的读数据方法//int read(char[] cbuf):一次读取一个字符数组的数据,返回的是实际读取的字符个数char[] chs = new char[5];//第一次读数据int len = fr.read(chs);System.out.println("len:"+len);  //System.out.println(new String(chs));System.out.println(new String(chs,0,len));//第二次读数据len = fr.read(chs);System.out.println("len:"+len);//System.out.println(new String(chs));System.out.println(new String(chs,0,len));//第三次读数据len = fr.read(chs);System.out.println("len:"+len);    //最后一次为4,多以char[4]并没有被覆盖,仍然是rSystem.out.println(new String(chs,0,len)); 

当source.txt中为

hello
world

时,内存中char数组三次读取数据是这样的

缓冲流

缓冲流可以提高效率,所以每次用IO流读写时要在外面包装一层缓冲流
特殊功能
BufferedWriter

void newLine()   //换行

BufferedReader

String readLine()   //读取一行

因此,上面的程序可以这样写

        //创建输入缓冲流对象BufferedReader br = new BufferedReader(new FileReader("source.txt"));//创建输出缓冲流对象BufferedWriter bw = new BufferedWriter(new FileWriter("target.txt"));//读写数据/*//一次读写一个字符int ch;while((ch=br.read())!=-1) {bw.write(ch);}*///一次读写一个字符数组char[] chs = new char[1024];int len;while((len=br.read(chs))!=-1) {bw.write(chs,0,len);}//释放资源
        bw.close();br.close();

练习

public static void main(String[] args) throws IOException{//定义文件路径String fileName = "students.txt";//为了让程序能够回到这里来,我们使用循环while(true) {//这是学生管理系统的主界面System.out.println("--------欢迎来到学生管理系统--------");System.out.println("1 查看所有学生");System.out.println("2 添加学生");System.out.println("3 删除学生");System.out.println("4 修改学生");System.out.println("5 退出");System.out.println("请输入你的选择:");//创建键盘录入对象Scanner sc = new Scanner(System.in);String choiceString = sc.nextLine();//用switch语句实现选择switch(choiceString) {case "1"://查看所有学生
                findAllStudent(fileName);break;case "2"://添加学生
                addStudent(fileName);break;case "3"://删除学生
                deleteStudent(fileName);break;case "4"://修改学生
                updateStudent(fileName);break;case "5":default:System.out.println("谢谢你的使用");System.exit(0); //JVM退出break;}}}//从文件中读数据到集合public static void readData(String fileName,ArrayList<Student> array) throws IOException {//创建输入缓冲流对象BufferedReader br = new BufferedReader(new FileReader(fileName));String line;while((line=br.readLine())!=null) {String[] datas = line.split(",");Student s = new Student();s.setId(datas[0]);s.setName(datas[1]);s.setAge(datas[2]);s.setAddress(datas[3]);array.add(s);}br.close();}//把集合中的数据写入文件public static void writeData(String fileName,ArrayList<Student> array) throws IOException {//创建输出缓冲流对象BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));for(int x=0; x<array.size(); x++) {Student s = array.get(x);StringBuilder sb = new StringBuilder();sb.append(s.getId()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());bw.write(sb.toString());bw.newLine();bw.flush();}bw.close();}//修改学生public static void updateStudent(String fileName) throws IOException {//创建集合对象ArrayList<Student> array = new ArrayList<Student>();//从文件中把数据读取到集合中
        readData(fileName, array);//修改学生的思路:键盘录入一个学号,到集合中去查找,看是否有学生使用的是该学号,如果有就修改该学生//创建键盘录入对象Scanner sc = new Scanner(System.in);System.out.println("请输入你要修改的学生的学号:");String id = sc.nextLine();//定义一个索引int index = -1;//遍历集合for(int x=0; x<array.size(); x++) {//获取每一个学生对象Student s = array.get(x);//拿学生对象的学号和键盘录入的学号进行比较if(s.getId().equals(id)) {index = x;break;}}if(index == -1) {System.out.println("不好意思,你要修改的学号对应的学生信息不存在,请回去重新你的选择");}else {System.out.println("请输入学生新姓名:");String name = sc.nextLine();System.out.println("请输入学生新年龄:");String age = sc.nextLine();System.out.println("请输入学生新居住地:");String address = sc.nextLine();//创建学生对象Student s = new Student();s.setId(id);s.setName(name);s.setAge(age);s.setAddress(address);//修改集合中的学生对象
            array.set(index, s);//把集合中的数据重新写回到文件
            writeData(fileName, array);//给出提示System.out.println("修改学生成功");}}//删除学生public static void deleteStudent(String fileName) throws IOException {//创建集合对象ArrayList<Student> array = new ArrayList<Student>();//从文件中把数据读取到集合中
        readData(fileName, array);//删除学生的思路:键盘录入一个学号,到集合中去查找,看是否有学生使用的是该学号,如果有就删除该学生//创建键盘录入对象Scanner sc = new Scanner(System.in);System.out.println("请输入你要删除的学生的学号:");String id = sc.nextLine();//我们必须给出学号不存在的时候的提示//定义一个索引int index = -1;//遍历集合for(int x=0; x<array.size(); x++) {//获取到每一个学生对象Student s = array.get(x);//拿这个学生对象的学号和键盘录入的学号进行比较if(s.getId().equals(id)) {index = x;break;}}if(index == -1) {System.out.println("不好意思,你要删除的学号对应的学生信息不存在,请回去重新你的选择");}else {array.remove(index);//把集合中的数据重新写回到文件
            writeData(fileName, array);System.out.println("删除学生成功");}}//添加学生public static void addStudent(String fileName) throws IOException {//创建集合对象ArrayList<Student> array = new ArrayList<Student>();//从文件中把数据读取到集合中
        readData(fileName, array);//创建键盘录入对象Scanner sc = new Scanner(System.in);//为了让id能够被访问到,我们就把id定义在了循环的外面
        String id;//为了让代码能够回到这里,用循环while(true) {System.out.println("请输入学生学号:");//String id = sc.nextLine();id = sc.nextLine();//判断学号有没有被人占用//定义标记boolean flag = false;//遍历集合,得到每一个学生for(int x=0; x<array.size(); x++) {Student s = array.get(x);//获取该学生的学号,和键盘录入的学号进行比较if(s.getId().equals(id)) {flag = true; //说明学号被占用了break;}}if(flag) {System.out.println("你输入的学号已经被占用,请重新输入");}else {break; //结束循环
            }}System.out.println("请输入学生姓名:");String name = sc.nextLine();System.out.println("请输入学生年龄:");String age = sc.nextLine();System.out.println("请输入学生居住地:");String address = sc.nextLine();//创建学生对象Student s = new Student();s.setId(id);s.setName(name);s.setAge(age);s.setAddress(address);//把学生对象作为元素添加到集合
        array.add(s);//把集合中的数据重新写回到文件
        writeData(fileName, array);//给出提示System.out.println("添加学生成功");}//查看所有学生public static void findAllStudent(String fileName) throws IOException {//创建集合对象ArrayList<Student> array = new ArrayList<Student>();//从文件中把数据读取到集合中
        readData(fileName, array);//首先来判断集合中是否有数据,如果没有数据,就给出提示,并让该方法不继续往下执行if(array.size() == 0) {System.out.println("不好意思,目前没有学生信息可供查询,请回去重新选择你的操作");return;}//\t 其实就是一个tab键的位置System.out.println("学号\t\t姓名\t年龄\t居住地");for(int x=0; x<array.size(); x++) {Student s = array.get(x);System.out.println(s.getId()+"\t"+s.getName()+"\t"+s.getAge()+"\t"+s.getAddress());}}

本程序内存图

转载于:https://www.cnblogs.com/aeolian/p/7768638.html

Java基础-IO流(13)相关推荐

  1. Java基础-IO流对象之数据流(DataOutputStream与DataInputStream)

    Java基础-IO流对象之数据流(DataOutputStream与DataInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据流特点 操作基本数据类型 ...

  2. Java基础IO流(二)字节流小案例

    JAVA基础IO流(一)https://www.cnblogs.com/deepSleeping/p/9693601.html ①读取指定文件内容,按照16进制输出到控制台 其中,Integer.to ...

  3. # Java基础——IO流

    Java基础--IO流 File类的使用(熟悉构造器和方法的使用) File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹) File类的声明在java.io包下 文件和文件目录路径的抽象表示 ...

  4. Java基础IO流之字符流的使用

    ☆引言☆ 大家好,我是痛而不言笑而不语的浅伤.IO流分为字节流和字符流,而上一篇文章我们学习了字节流(Java基础IO流之字符流的使用),这篇文章带大家一起来学习字符流吧.对文章中描述错误的希望大家积 ...

  5. 黑马程序员-JAVA基础-IO流之字符流和字符流缓冲区

    ------- android培训.java培训.期待与您交流!------- Java 的IO 流 是实现输入和输出的基础,Java 中把不同的输入.输出源抽象表述为"流" (S ...

  6. Java基础—IO流

    第一讲   IO概述 1. 流的概念 IO流即InputOutput的缩写,在Java中IO流用来处理设备之间的数据传输,Java对数据的操作是通过IO流的方式, 我们可以把IO流抽象的当作一根管道, ...

  7. java基础 io流 字节流 字符流 节点流 包装流 转换流 缓冲流 对象流 打印流 Properties类

    目录 1.概念 2.常用的文件操作 2.1 创建文件 2.2 获取文件相关信息 2.3 目录的操作和文件删除 3. IO流原理及流的分类 3.1 流的分类 4.InputStream 字节输入流 4. ...

  8. JAVA基础 IO流技术学习笔记

    目录 一.IO 流技术介绍 1.1  什么是IO? 1.2  流的概念 1.3  数据源 1.3.1 什么是数据源? 1.3.2数据源的分类 二.第一个简单的IO流程序 三.IO流经典写法(适用于任何 ...

  9. 黑马程序员-JAVA基础-IO流之流操作规律及读写转换流

    ------- android培训.java培训.期待与您交流!------- 在操作IO流时,常常会迷惑:流对象很多,不知道该使用哪一个? 一.流操作的基本规律: 通过三个明确来完成: 1.明确'源 ...

最新文章

  1. vs2010 使用STLport-5.2.1
  2. python列表解析式如何使用_python列表推导式操作解析
  3. mybatis关联查询
  4. 【cJson】 JSON格式详解
  5. leetcode1300. 转变数组后最接近目标值的数组和
  6. python文件操作小总结
  7. 自己编写一个前端精确打印控件
  8. 工程之道,解读业界最佳的深度学习推理性能优化方案
  9. poj 1723 中位数
  10. 在Spring环境下存取properties文件中的数值
  11. cvSetMouseCallback()鼠标坐标、事件返回
  12. 98道常见Hadoop面试题及答案解析
  13. 手机android的文件怎么恢复,手机文件误删除怎么恢复-互盾安卓恢复大师
  14. httpclient+nekohtmlnbsp;解析HTML[转]
  15. 编程猫python教学_有老师使用过编程猫进行教学吗?
  16. 计算机图形学方向的基本能力
  17. 二维小球完全弹性碰撞绝对坐标速度计算公式
  18. STM32RTC简单万年历制作
  19. jzoj4024 [佛山市选2015]石子游戏
  20. SecureFx设置密钥登陆

热门文章

  1. 【LeetCode】 sort list 单清单归并
  2. underscore javascript工具库支持seajs模块化
  3. Web.py Cookbook 简体中文版 - 在webpy中使用Cheetah模板引擎
  4. extend the gridview control
  5. 浅谈软件测试人员不要这样写测试用例(给测试新手和老鸟的提示)
  6. python批量运行cmd_python 批量ssh并执行命令
  7. linux en_us支持什么格式的中文,更改Linux操作系统下的显示默认支持语言
  8. 学Web前端开发需要哪些基础?零基础小白该怎么入行?
  9. html浮动跟随鼠标,jQuery 图片跟随鼠标浮动
  10. python编写程序题目_让我们一起来写python程序,做些简单的题目