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. 手把手教你分析MySQL死锁问题,十分钟看完文章下次轻松完成不加班
  2. linux标准daemon编写方式
  3. 微服务和容器技术有风险,望君三思而后行
  4. 时频分析:短时傅里叶变换实现(1)
  5. 不出现用户帐户控制-让Win7的用户账户控制(UAC)放过信任的程序
  6. Transformer又又又升级了?
  7. redis内部数据结构深入浅出
  8. java sqlserver ssl_拦截SQLSERVER的SSL加密通道替换传输过程中的用户名密码实现运维审计(一)...
  9. dj鲜生-01-新建项目-配置数据库
  10. 【接口测试】FitNesse中文指南
  11. linux nload_Linux nload命令
  12. seay代码审计mysql插件报错_Seay源代码审计系统的配置和安装
  13. 前端学习第八弹:制作一个精美书签
  14. ARM汇编之TCP Bind Shell
  15. 敏感性、特异性、假阳性、假阴性(sensitivity and specificity)
  16. UNP卷一chapter17 ioctl操作
  17. 软著申请 计算机软件分类代码,软著申请代码有哪些要求
  18. 决策树决策算法ID3算法、改进算法C4.5算法和CART算法代码实现
  19. 关于whl,你想知道的
  20. openEuler安装GPU、CUDA、cudnn

热门文章

  1. 写一个Windows上的守护进程(4)日志其余
  2. c#实现播放器的集中方式
  3. 【Linux】Linux的关机和虚拟机克隆、快照
  4. 测试基础-04-用例的编写评审
  5. JMeter集合点功能的使用
  6. python03_Python中的列表、元组、字典和集合
  7. 动态规划算法实验报告_搞懂这几点,动态规划算法就是那么简单
  8. 8plus基带电源供电线路_双电源供电与双回路供电的区别是什么?别再傻傻分不清了!...
  9. 计算机科学与技术 课表 武汉,欢迎访问武汉理工大学计算机科学与技术学院
  10. android tools add native support,使用NDK进行开发android