-------http://www.itheima.comjava培训、android培训期待与您交流!-------
接着学习,,,,,
四、Properties
1、概述
Properties 是集合中和IO技术相结合的集合容器。
可用于键值对形式的配置文件
加载数据时,需要数据有固定格式,即键=值。
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。
2、获取
import java.io.*; import java.util.*; class PropertiesDemo { public static void main(String[] args) { //创建对象 Properties prop = new Properties(); //设置属性,以键值的形式设置 prop.setProperty("wangwu","20"); prop.setProperty("lisi","30"); //以键值对的形式打印 System.out.println(prop); //通过键取值 String value = prop.getProperty("wangwu"); System.out.println(value); //先将map转化成set集合,再获取 Set<String> names = prop.stringPropertyNames(); for (String s : names ) { //若只打印 s ,只是获取的是姓名 System.out.println(s+"----"+prop.getProperty(s)); } } }
3、
用于记录应用程序运行次数 如果使用次数已到,那么给出注册提示信息。那么就要用计数器记录运行的次数,但是在程序结束后,会在内存中消失,此时就需要将其存入到文件中,
所以需要一个配置文件,用于记录该软件使用的次数。下次程序启动时会先加载该计数器的值并加以后重新存储。Map+IO=Properties
import java.util.*; import java.io.*; class RunCount { public static void main(String [] args)throws IOException { //创建一个Properties对象,集合和io的结合 Properties pop = new Properties(); //创建一个文件对象,用于操作文件 File file = new File("count.ini"); //先判断文件是否存在,如果不存在就创建一个 if(!file.exists()) file.createNewFile(); //创建读取流对象,读取文件中的信息 FileInputStream fis = new FileInputStream(file); //将流中的文件信息存入集合中 pop.load(fis); //定义计数器 int count = 0; //获取文件中键所对应的值 String value = pop.getProperty("time"); //判断值是否为null,不为空就将值传给计数器 if(value!=null) { count = Integer.parseInt(value); //判断计数器是否为到达次数 if(count>=5) { System.out.println("次数已到,请注册"); return ; } } count++; //将获得的键值设置后存入集合中 pop.setProperty("time",count+""); FileOutputStream fos = new FileOutputStream(file); pop.store(fos,""); fos.close(); fis.close(); } }
五、IO包中的其他流
1、打印流
打印流提供了打印方法,可将各种数据类型的数据都原样打印。
(1)字节打印流:PrintStream
构造函数可接收的参数类型:
File对象 File
字符串路径 String
字节输出流 OutputStream
(2)字符打印流:PrintWriter,这是web开发常用的。
构造函数可接收的参数类型:
File对象 File
字符串路径 String
字节输出流 OutputStream
字符输出流 Writer
import java.io.*; class PrintDemo { public static void main(String[] args) throws IOException { //键盘录入,创建读取流对象 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //使用打印流,将文件输出 //输出到屏幕 //PrintWriter(Writer out, boolean autoFlush) 这里的autoFlush设置为true //则不用刷新缓冲区, PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true); String line = null; while((line=bufr.readLine())!=null) { if("over".equals(line)) break; out.println(line.toUpperCase()); //out.flush(); } bufr.close(); out.close(); } }
2、合并流
将多个输入流合并到一个流中。
import java.io.*; class SequenceInputStreamDemo { public static void sequenceFile()throws IOException { //合并流对象 FileOutputStream fos = null; SequenceInputStream sis = null; try { //创建集合,存储多个文件 ArrayList<FileInputStream> al = new ArrayList<FileInputStream>(); for(int i=1;i<=3;i++) { al.add(new FileInputStream(i+".part")); } //匿名内部类访问局部变量要final final Iterator<FileInputStream> it = al.iterator(); //创建Enumeration匿名对象 Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() { public boolean hasMoreElements() { return it.hasNext(); } public FileInputStream nextElement() { return it.next(); } }; //合并流对象,将集合元素加入。 sis = new SequenceInputStream(en); //创建写入流对象,FileOutputStream fos = new FileOutputStream("7.bmp"); byte[] b = new byte[1024*1024]; int len = 0; //循环,将数据写入流资源 while((len=sis.read(b))!=-1) { fos.write(b); } } catch (IOException e) { throw new RuntimeException("文件操作失败"); } //关闭流资源 finally { try { if(fos!=null) fos.close(); } catch (IOException e) { throw new RuntimeException("关闭流资源操作失败"); } try { if(sis!=null) sis.close(); } catch (IOException e) { throw new RuntimeException("关闭流资源操作失败"); } } } }
3、切割文件
import java.io.*; class SplitFile { //切割流对象 public static void splitFile()throws IOException { //创建全局变量 FileInputStream fis = null; FileOutputStream fos = null; try { //创建文件读取流 fis = new FileInputStream("0.bmp"); //创建数组 byte[] b = new byte[1024*1024]; int len = 0; //计数器 int count = 1; //循环写入数据 while((len=fis.read(b))!=-1) { //每次创建一个新写入流,写入后关闭流资源 fos = new FileOutputStream((count++)+".part"); fos.write(b,0,len); fos.close(); } } catch (IOException e) { throw new RuntimeException("关闭流资源操作失败"); } //关闭流资源 finally { try { if(fis!=null) fis.close(); } catch (IOException e) { throw new RuntimeException("关闭流资源操作失败"); } } } } }
4、对象的序列化
将对象中的数据(信息,如姓名、年龄等)存储到指定的文件(硬盘)中,就叫对象的序列化或对象的持久化存储。可以说,存储的文件是一个可以长久存储对象的介质。
需要注意的是,
静态不能被序列化,因为静态在方法区中存储,而序列化的是内存中的信息数据。
被transient关键字修饰的不能被序列化(即不能被存储到文件中)。
//创建Person类,实现序列化 class Person implements Serializable{ //定义自身的序列化方式 public static final long serialVersionUID = 42L; //定义私有属性 private String name; private int age; //该属性被transient修饰,故id不能被序列化 transient String id; //该属性被被static修饰,故"cn"不能被序列化 static String country = "cn"; //构造Person类 Person(String name,int age,String id,String country){ this.name = name; this.age = age; this.id = id; this.country = country; } //覆写toString方法 public String toString(){ return name+ ":" + age + ":" + id + ":" + country; } } //对象序列化测试 class ObjectStreamDemo{ public static void main(String[] args){ //对象写入流 writeObj(); //对象读取流 readObj(); } //定义对象读取流 public static void readObj(){ ObjectInputStream ois = null; try{ //创建对象读取流 ois = new ObjectInputStream(new FileInputStream("obj.txt")); //通过读取文件数据,返回对象 Person p = (Person)ois.readObject(); System.out.println(p); }catch (Exception e){ throw new RuntimeException("写入文件失败"); } //最终关闭流对象 finally{ try{ if(ois!=null) ois.close(); }catch (IOException e){ throw new RuntimeException("写入流关闭失败"); } } } //定义对象写入流 public static void writeObj(){ ObjectOutputStream oos = null; try{ //创建对象写入流 oos = new ObjectOutputStream(new FileOutputStream("obj.txt")); //写入对象数据 oos.writeObject(new Person("lisi",25,"01","cn")); }catch (Exception e){ throw new RuntimeException("写入文件失败"); } //关闭流资源 finally{ try{ if(oos!=null) oos.close(); }catch (IOException e){ throw new RuntimeException("写入流关闭失败"); } } } }
5、管道流
PipedOutputStream
PipedInputStream
输入和输出可直接进行连接,结合线程使用
import java.io.*; class PipedStream { public static void main(String[] args)throws Exception { PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(); in.connect(out); Read r = new Read(in); Write w = new Write(out); new Thread(r).start(); new Thread(w).start(); } } class Read implements Runnable { private PipedInputStream in; Read(PipedInputStream in) { this.in = in; } public void run() { try { //定义一个字节数组,用于存储读出的数据 byte[] buf = new byte[1024]; System.out.println("读取前,,没有数据阻塞"); //将数据读取到字节数组中 int len = in.read(buf); System.out.println("读到数据,,阻塞结束"); //将有效数据转换成字符串打印 String s = new String(buf,0,len); System.out.println(s); in.close(); } catch (IOException e) { throw new RuntimeException("管道读取流失败"); } } } class Write implements Runnable { private PipedOutputStream out; Write(PipedOutputStream out) { this.out = out; } public void run() { try { System.out.println("开始写入数据,等待6秒后"); Thread.sleep(6000); out.write("管道流创建成功".getBytes()); out.close(); } catch (IOException ioe) { throw new RuntimeException("管道s输出流失败"); } } }
6、RandomAccessFile
RandomAccessFile类是随机访问文件类,他并不是io体系中的子类,
而是直接继承Object。
但他是IO包中的成员,因为他既能读取数据也可写入数据。
他的内部封装了一个数组么热切通过指正对数组的元素进行操作,
getFilePointer() 获取指针位置
seek() 改变指针位置
其完成读写原理是:内部封装了字节输入流和输出流。
通过构造函数,该类只能操作文件,且操作的文件还有模式。
RandomAccessFile(String name, String mode)
创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
r: 只读模式,即对该文件的操作只能是读取已存在文件的数据,
不会创建文件,,若该文件不存在,会出现异常
rw: 可读可写,即对该文件的操作可以是读取也可以是写入数据,
如果要操作的文件不存在,则会在当前目录下自动创建,
若该文件存在不会讲该文件中的内容覆盖。
import java.io.*; class RandomAccessFileDemo { public static void main(String[] args) throws IOException { writeFile(); //writeFile_2(); readFile(); } public static void readFile()throws IOException { RandomAccessFile raf = new RandomAccessFile("random.txt","r"); //调整对象中指针,获取该指针位置的数据信息 u获取的信息不一样8*0 8*1 //raf.seek(8*1); //跳过指定的子节数,跳过8个字节,获取8个字节后的数据信息 //该方法只能向后跳,不能向前跳(回跳) raf.skipBytes(8); byte[] buf = new byte[4]; /* raf.write("你好".getBytes()); Exception in thread "main" java.io.IOException: 拒绝访问。 若设定的文件操作模式为只读,则不能再对其进行写入操作 */ raf.read(buf); //将姓名打印在控制台 String name = new String(buf); //获取年龄,此处要使用获取整数数据的方法 int age = raf.readInt(); System.out.println(name); System.out.println(age); raf.close(); } public static void writeFile_2()throws IOException { RandomAccessFile raf = new RandomAccessFile("random.txt","rw"); //将第一个指针处的数据信息 李四a 修改掉,变为周六 raf.seek(8*0); raf.write("周六".getBytes()); raf.writeInt(113); raf.close(); } public static void writeFile()throws IOException { //创建随机访问文件的对象,并关联一文件,指定模式类型 RandomAccessFile raf = new RandomAccessFile("random.txt","rw"); /* raf.write(97); 存储数据的结果为:李四a raf.write(258);存储结果为:李四 查表 数据丢失 //打印结果: 100000010 将最低8位写出 数据丢失 System.out.println(Integer.toBinaryString(258)); */ raf.write("李四".getBytes()); raf.writeInt(97); raf.write("王五".getBytes()); raf.writeInt(99); raf.close(); } }
7、DataInputStream/DataOutputStream,可直接操作基本数据类型。
写入的是什么顺序,就按照什么顺序读取。
import java.io.*; class DataStream { public static void main(String[] args) throws IOException { //writeData(); //readData(); //writeUTF(); readUTF(); } public static void readUTF()throws IOException { //若使用readUTF方法读取gbk编码的数据文件会报异常, //所以写入的是什么编码的数据就使用哪种读取的方法读取 DataInputStream dis = new DataInputStream(new FileInputStream("dataUTF.txt")); String s = dis.readUTF(); System.out.println(s); dis.close(); } public static void writeUTF() throws IOException { /* 该文件4字节大小 */ OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("GBK.txt"),"GBK"); osw.write("你好"); osw.close(); /* 该文件大小为6字节 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("dataUTF.txt"),"UTF-8"); osw.write("你好"); osw.close(); */ /* 该文件大小8字节 DataOutputStream dos = new DataOutputStream(new FileOutputStream("dataUTF.txt")); //默认是写入的是UTF修改版的编码 dos.writeUTF("你好"); dos.close(); */ } public static void readData()throws IOException { //创建数据输入流对象,并接收一个文件输入流,指定读取数据的来源 DataInputStream dis = new DataInputStream(new FileInputStream("data.txt")); //对文件进行读取操作,一定要按照写入的顺序读取,否则读取的数据不对 int num = dis.readInt(); boolean b = dis.readBoolean(); double d = dis.readDouble(); System.out.println("num=="+num); System.out.println("b=="+b); System.out.println("d=="+d); dis.close(); } public static void writeData() throws IOException { //创建数据输出流对象,并在一初始化就关联一个文件输出流 DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt")); //将指定基本数据类型的数据写入,写入的数据大小为8个字节 dos.writeInt(234); dos.writeBoolean(true); dos.writeDouble(3223.123); //关闭数据输出流资源 dos.close(); } }
8、ByteArrayInputStream/ByteArrayOutputStream
(1)不涉及调用底层资源,所以不用关流。不产生任何IOException。
(2)输出流中缓冲区随着数据的不断写入而自动增长。
(3)操作的是数组,即目的地是数组
import java.io.*; class ArrayStreamDemo { public static void main(String[] args) { //数据源 ByteArrayInputStream bais = new ByteArrayInputStream("ABCDEFF".getBytes()); //数据目的 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int by = 0; //读取和写入数据 while((by=bais.read())!=-1) { baos.write(by); } System.out.println(baos.size()); System.out.println(baos.toString()); try { //方法,此处抛异常,所以上面需要抛出去 baos.writeTo(new FileOutputStream("a.txt")); } catch (IOException e) { throw new RuntimeException("写入文件失败"); } } }
9、转换流的字符编码
可传入编码表的有:
(1)转换流:InuputStreamReader和OutputStreamWriter
2)打印流:PrintStream和PrintWriter,只有输出流
字符编码/解码
(1)编码:字符串变成字节数组
(2) 解码:字节数组变成字符串
2、转换:
(1)默认字符集:
String ---> byte[] :srt.getBytes()
byte[] ---> String :new String(byte[])
2)指定字符集:
String ---> byte[] :srt.getBytes(charsetName)
byte[] ---> String :new String(byte[],charsetName)
字符编码--联通
12、练习
需求:
有5个学生,3门成绩,
从键盘输入学生数据,
格式为:zhangsan,78,98,96
学生的属性有姓名,3门课程的名称,
计算出学生3门课程的总成绩,并按照从高到底的顺序将总成绩排序。
并将该信息存储到一个文件中:studentInfor.txt
描述学生对象,
定义学生信息工具类,
分析:
1、定义一学生类,属性有:name,3门课程:math chinese english ,总成绩sum
复写hashCode()和equals()方法,(可能将数据存储到hashMap表中)
使学生具有比较性,实现Comparable接口,复写compareTo()方法,自定义比较方法
复写toString()方法,获得信息:name,math chinese english
2、定义一工具类,用于向集合中存储数据信息 TreeSet(要存储的信息有顺序)
将信息通过键盘录入写入到studentInfor.txt文件中
import java.util.*; import java.io.*; class Student implements Comparable<Student> { private String name; private int math; private int chinese; private int english; private int sum; Student(String name,int chinese,int english ) { this.name = name; this.math = math; this.chinese = chinese; this.english = english; sum = math + chinese + english; } //复写hashCode方法,自定义比较方式 public int hashCode() { //判断对象属性的姓名的哈希值 return name.hashCode()+sum*5; } //复写equals方法,将 public boolean equals(Object obj) { //判断传递进来的数据是否是Student类型,如果不是,抛出异常 if (!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); //如果是,将传递进来的数据强转为Student类型 Student stu = (Student)obj; return this.name.equals(s.name) && this.sum == s.sum; } //复写Comparable接口的compareTo方法, public int compareTo(Student s) { int num = new Integer(this.sum).compareTo(new Integer(s.sum)); if (num ==0) return this.name.compareTo(s.name); return num; } //定义方法,获取姓名和总成绩 public String getName() { return name; } public int getSum() { return sum; } public String toString() { return name+ math+ chinese + english; } } class StudentInforTool { public static Set<Student> getStudnets() { return getStudents(null); } //定义一个带有比较器的学生集合 public static Set<Student> getStudnets() { //读取键盘录入 BufferedReader bufr = null; Set<Student> stus = null; try { //创建读取流对象缓冲区,键盘录入 bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; //选择集合是否有比较器 if(cmp==null) stus = new TreeSet<Student>(); else stus = new TreeSet<Student>(cmp); //循环读取键盘录入的数据 while((line=bufr.readLine())!=null) { if("over".equals(line)) break; //对读取的数据进行分割并存入集合 String[] info = line.split(","); Student stu = new Student(info[0],Integer.parseInt(info[1]), Integer.parseInt(info[2]), Integer.parseInt(info[3])); stus.add(stu); } } catch (IOException e) { throw new RuntimeException("学生信息读取失败"); } //关闭流资源 finally { try { if(bufr!=null) bufr.close(); } catch (IOException e) { throw new RuntimeException("读取流关闭失败"); } return stus; } } //将数据写入指定文件 public static void write2File(Set<Student> stus,String fileName) { BufferedWriter bufw = null; try { //创建写入流对象 bufw = new BufferedWriter(new FileWriter(fileName)); //循环写入数据 for(Student stu : stus) { bufw.write(stu.toString() + "\t"); bufw.write(stu.getSum() + ""); bufw.newLine(); bufw.flush(); } } catch (IOException e) { throw new RuntimeException("读取流关闭失败"); } //关闭流资源 finally { try { if(bufw!=null) bufw.close(); } catch (IOException e) { throw new RuntimeException("写入流关闭失败"); } } } } class StudentInfoTest { public static void main(String[] args) { //反转比较器,将成绩从大到小排 Comparator<Student> cmp = Collections.reverseOrder(); //将录入的学生信息存入集合 Set<Student> stus = StudentInfoTool.getStudents(cmp); //将信息写入指定文件中 StudentInfoTool.write2File(stus,"sudentinfo.txt"); } }
-------http://www.itheima.comjava培训、android培训期待与您交流!-------
发表评论
-
黑马程序员---集合框架
2013-05-19 20:10 961-------http://www.itheima.comja ... -
黑马程序员----面向对象---异常
2013-05-16 17:31 722[size=small] -------http://www. ... -
黑马程序员---String、StringBuffer、StringBuilder
2013-05-23 18:44 1165-------http://www.itheima.comj ... -
黑马程序员---面向对象---接口、多态、Object类、内部类
2013-05-23 21:48 822-------http://www.itheima.comj ... -
黑马程序员 --- 面试
2013-05-31 14:03 994-------http://www.itheima.comja ... -
黑马程序员---GUI
2013-05-30 09:14 941-------http://www.itheima.comj ... -
黑马程序员---java高新技术
2013-05-31 14:03 934-------http://www.itheima.comja ... -
黑马程序员---网络编程
2013-05-31 14:03 999-------http://www.itheima.comja ... -
黑马程序员---java基础
2013-05-16 18:20 1003-------http://www.itheima.comja ... -
黑马程序员-------面向对象---概述、封装、继承、抽象类
2013-04-22 11:44 984---------------http://www.ithei ... -
黑马程序员---IO流(1)
2013-05-30 09:53 1033-------http://www.itheima.c ... -
黑马程序员---多线程
2013-04-14 14:31 843... -
黑马程序员---单例设计模式
2013-04-14 14:29 808------- http:/ ... -
黑马程序员---泛型
2013-04-14 14:15 481-----http://www.itheima.comjava ...
相关推荐
本资料包“Java-IO流高级-例题 & 例题源码 & PPT教学文档(黑马程序员详细版).rar”提供了一个深入学习Java IO流的全面资源,包含实例题目、源代码以及PPT教学材料,适合对Java IO有进阶需求的开发者。 1. **Java ...
黑马程序员_毕向东_Java基础视频教程第18天-14-IO流(拷贝文本文件图例).zip
黑马程序员_毕向东_Java基础视频教程第18天-09-IO流(文件的续写)
在这个“黑马程序员_毕向东_Java基础视频教程第18天-12-IO流(文本文件读取练习)”中,毕向东老师将深入讲解如何使用Java IO流来读取文本文件。Java IO流提供了多种类和方法,使得开发者可以灵活高效地处理输入和输出...
本教程《黑马程序员_毕向东_Java基础视频教程第18天-13-IO流(拷贝文本文件)》专注于讲解如何利用IO流来实现文本文件的复制操作。这个过程涉及到了对文件读取、数据缓冲以及写入等基础知识,对于初学者来说是理解和...
### 黑马程序员入学Java精华总结 #### 一、Java概述与基础知识 1. **何为编程?** - 编程是指通过编写计算机能够理解的指令来解决问题或完成特定任务的过程。这些指令通常被组织成算法,并使用某种编程语言实现。...
"IO-黑马程序员Java学习笔记"这个压缩包包含了关于Java IO的详细教程,可以帮助我们深入理解这个关键领域。下面将根据提供的文件名来解析可能包含的知识点。 1. **IO.md**: 这个文件很可能是Markdown格式的学习...
Java的IO体系主要包括字节流(InputStream/OutputStream)和字符流(Reader/Writer),它们用于处理文件读写、网络通信等操作。 #### 18. 集合体系 Java集合框架主要包括List、Set、Map三种集合类型,以及它们的...
Java IO流是Java编程语言中一个非常重要的概念,它提供了数据传输的能力,使得程序能够读取和写入数据到各种输入/输出设备,如硬盘、内存、网络等。本资源包含的是Java-IO流的基础例题、源码及PPT教学文档,适合初学...
在本教程“黑马程序员_毕向东_Java基础视频教程第18天-11-IO流(文本文件读取方式二)”中,主讲人毕向东将深入讲解如何使用Java有效地读取文本文件,特别是第二种常用的方法。以下是关于Java IO流和文本文件读取的...
传智播客黑马程序员javaIO流重点总结(必读).doc
《黑马程序员Java面试宝典》是一本专门为Java开发者准备的面试指南,包含了广泛而深入的Java技术知识,以及面试过程中可能会遇到的各种问题。这本书的完整版PDF提供了丰富的学习材料,帮助求职者提升自己的技术水平...
6. **IO流** - 文件操作:File类的使用,以及FileReader/Writer、FileInputStream/FileOutputStream的读写操作。 - 流的分类:字节流和字符流,输入流和输出流。 - 缓冲流:BufferedReader和BufferedWriter的性能...
- 键盘输入通常有三种方式:命令行参数`String[] args`、`BufferedReader`通过IO流读取、`Scanner`类从`System.in`获取输入。`Scanner`的使用步骤包括导入包,创建对象,然后调用相应方法接收数据。 5. **switch...
7. **IO流**:教授输入输出流的使用,包括文件读写、对象序列化和反序列化等。 8. **集合框架**:介绍ArrayList、LinkedList、HashSet、HashMap等容器的使用,以及泛型的概念。 9. **多线程**:讲解如何创建和管理...
Java的IO流系统支持数据的输入和输出,包括字符流和字节流,以及缓冲区、转换流和对象序列化等。 16. **多线程**: Java内置了对多线程的支持,通过Thread类或实现Runnable接口可以创建并管理多个执行线程。 17....
### 黑马程序员入学Java知识(精华总结) #### 一、Java概述与基础知识 ##### 1、何为编程? 编程是指使用计算机语言来编写指令,这些指令被计算机执行以完成特定任务的过程。通过编程,我们可以控制计算机的行为...
这其中包括了对Java集合框架的理解(List、Set、Map接口及其实现类)、异常处理、多线程编程、IO流、反射、设计模式等进阶主题。 黑马程序员面试技巧则提供了面试策略和技巧,如如何清晰地表达思路,怎样在短时间内...
- **数据传输:** IO流主要用于实现不同设备间的通信和数据传输。 - **数据操作:** Java通过流的方式对数据进行操作。 **IO流的位置:** - 所有的IO流类都位于`java.io`包中。 **流的分类:** 1. **按数据类型分...