IO

Java IO 的四个主要抽要基类

  • 字节流的抽象基类
    InputStream,OutputStream
  • 字符流的抽象基类
    Reader,Writer

字符流

  1. 文件写 文件写的简单实例

  2. 在上个例子中,异常是直接抛的,这样显然不合适,IO异常的处理

  3. 如果使用fw = new FileWriter("demo.txt"); 则会覆盖原有的同名文件,如果想 续写 文件,就使用重载 fw = new FileWriter("demo.txt",true);

  4. 文件读 的简单实例:

    • 读取单个字符 ,read() 返回int,读取单个字符的ASCII码,
    • 读取字符数组,read(char[] buf)返回int,表示读取到的字符个数,读取到的字符存在buf中。
  5. 练习:以文件读取的方式复制文本文件

  6. 以上的方式效率都比较低,所以引入了 缓冲区: BufferedWriterBufferedReader

    缓冲区对象没有空参数的构造函数。因为缓冲区的出现是为了提高流的操作效率而出现的。所以在创建缓冲区之前,必须要先有流对象

    • BufferedWriter 的简单实例
    • BufferedReader的简单示例
  7. 练习:使用缓冲区复制文本文件

  8. 自定义MyBufferedReader 模拟缓冲区的实现过程

  9. 装饰设计模式:当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。

    装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。

    前面提到的BufferedReader其实就是FileReader的装饰。

    装饰设计模式举例

    自定义装饰类:修改上面的MyBufferedReader

  10. 读取行号 LineNumberReader的简单实例

    练习:模拟实现带行号的缓冲区对象

字节流

InputStream
OutputStream

  1. 文件读写的简单例子 link1

    • 练习1:利用字节流复制图片文件 link2
    • 练习2:利用字节流 缓冲区 复制文件 link3
  2. 自定义字节流缓冲区,演示缓冲区的工作原理(只需看懂就好,不需要自己写) link4

  3. 键盘录入

    System.in;  //标准输入,键盘(录入的是二进制数据)
    System.out;  //标准输出,控制台
    InputStream in=System.in;
    int by=in.read();   //by就是键盘录入的内容-->int
    • 练习3:通过键盘录入数据。当录入一行数据后,就将该行数据进行打印。如果录入的数据是over,那么停止录入。 link5
  4. 在这个练习中录入一行数据就是之前的 readLine() 方法,但是readLine() 是字符流 BufferedReader 类中的方法,而现在讨论的是字节流 InputStream 的问题:那么能不能将 字节流转成字符流 再使用字符流缓冲去的readLine方法呢?

    • 字节流—>字符流:InputStreamReader
    • 练习4:使用 readLine 修改上面的练习3 link6
    • 字符流—>字节流:OutputStreamWriter
    • 练习5:修改练习4 link7
  5. 在上一条中,输入输出的对象是键盘和控制台,如果想对文件操作的话,只需要做稍微的修改即可:

    • 将键盘录入写入到文件 link8
    • 从文件数据打印到控制台 link9
  6. 可以通过System.setIn();System.SetOut() 修改设置默认输入输出设备(默认是键盘和控制台)。(了解即可,不常用)

  7. 将异常信息保存到日志文件中 link10

  8. 获取系统信息link11

文件

  1. 将 文件或文件夹 封装成文件对象 link1

  2. File类的常用方法 1

    • 创建。
      boolean createNewFile():在指定位置创建文件,返回true,如果该文件已经存在,则不创建,返回false。 link2
      和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
      boolean mkdir():创建文件夹。
      boolean mkdirs():创建多级文件夹。link3

    • 删除。
      boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。link4
      void deleteOnExit();在程序退出时删除指定文件。

    • 判断。
      boolean exists(): 文件是否存在.
      boolean isFile(): 是否是文件,先判断文件是否存在
      boolean isDirectory(): 是否是目录,先判断文件夹是否存在
      boolean isHidden(): 是否隐藏
      boolean isAbsolute(): 时候绝对路径

    • 获取信息。
      String getName():
      String getPath(): 封装的路径,文件本身可以不存在
      String getAbsolutePath(): 绝对路径,文件本身可以不存在
      String getParent():该方法返回的是封装在File()中的目录中的路径,如果封装的是相对路径,至只返回相应的部分
      long lastModified() 最够一次修改的时间
      long length() 文件大小

    等等

  3. File类的常用方法——文件列表

    • 文件列表方法
      static File[] listRoots() 没有参数,返回文件根目录(盘符);
      String[] list() 返回指定目录下的所有的文件和文件夹;
      String[] list(FilenameFilter filter) 返回 过滤 之后的指定目录下的文件名称;link5

    等等

  4. 遍历某文件夹中的全部文件

    • 递归方法遍历:link6
    • 带层级关系的递归 link7
  5. 删除文件夹:在windows中,要删除文件夹必须先删除其中的文件,使用递归删除 : link8

  6. 练习:将一个指定目录下的java文件的绝对路径,存储到一个文本文件中,建立一个java文件列表文件。link9

属性类Properties

  1. Properties是hashtable的子类。也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串

    它是集合和IO技术相结合的集合容器。可以用于键值对形式的配置文件。

    那么在加载数据时,需要数据有固定格式:键=值

  2. 添加,修改,获取属性 link1

  3. 从文件中读取属性信息(通过“=”分割键值) link2

    但是这种方法显然比较笨拙,Properties类为我们提供了一个load方法,可以加载流数据 link3

  4. 在第二条中,使用setProperty()修改属性信息只是修改了内存中的信息,而没有修改相应文件中的信息。如果想连同文件一起修改,可以使用store() 方法 link4

  5. 练习:统计程序运行的次数:

    在这个练习中,不能使用在程序中设置count计数器的方法,因为程序一旦结束,内存清理,count也就消失了。我们要建立一个程序外的计数器,即一个配置文件。(配置文件可以实现应用程序数据的共享) link5

其他

  1. 打印流对象:该流提供了打印方法,可以将各种数据类型的数据都原样打印。

    • 字节打印流:PrintStream
      构造函数可以接收的参数类型:

      • file对象。File
      • 字符串路径。String
      • 字节输出流。OutputStream
    • 字符打印流:PrintWriter
      构造函数可以接收的参数类型:

      • file对象。File
      • 字符串路径。String
      • 字节输出流。OutputStream
      • 字符输出流,Writer。

      简单实例 link1

  2. 合并流 link2

  3. 分割流,使用ArrayList合并流 link3

  4. 使用ObjectOutputStream直接存储对象,存储的对象只能使用ObjectInputStream 获取。link4

  5. RandomAccessFile

    该类不是IO体系中子类,而是直接继承自Object。但是它是IO包中成员。它同时具备 读和写 功能。

    内部封装了一个数组,而且通过指针对数组的元素进行操作。
    可以通过 getFilePointer 获取指针位置,
    可以通过 seek 改变指针的位置。

    其能完成读写的原理就是内部封装了 字节输入流和输出流 。

    通过构造函数可以看出,该类 只能操作文件 ,分两种 模式:只读(“r”),读写(“rw”)

    • 如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
    • 如果模式rw。操作的文件不存在,会自动创建。如果存在则不会覆盖。

    该类相对于其他的 io 类的特点就是能够实现随机存取。
    数据分段的前提是存储的数据本身有规律,可以使用 空 补位

    link5

  6. 操作基本数据类型,可以使用DataStream link6

  7. 操作字节数组ByteArrayStream

    ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。

    ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
    这就是数据目的地。

    因为这两个流对象都操作的数组,并没有使用系统资源,所以不用进行close关闭。

    link7

    类似的还有: 操作字符数组CharArrayReader,CharArrayWriter
    操作字符串 StringReader,StringWriter

字符编码

  1. 在输入输出流中指定编码表 link1

  2. 在某些服务器中使用的是 IOS8859-1 编码表,不能识别中文,可以使用先编码再解码的方式解决 link2
    但是这种方式不能解决 UTF-8 的乱码问题,因为 UTF-8 本身也识别中文,依然会产生乱码。

  3. 练习:
    有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括姓名,三门课成绩),输入的格式:如:zhagnsan,30,40,60。计算出总成绩,并把学生的信息和计算出的总分数高低顺序存放在磁盘文件”stud.txt”中。

    • 描述学生对象。
    • 定义一个可操作学生对象的工具类。

    思想:

    • 通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。
    • 因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序, 所以可以使用TreeSet。
    • 将集合的信息写入到一个文件中。

    link3

你可能感兴趣的:(java,IO)