JavaIO流:主要知识点

JavaIO流:主要知识点

File

介绍:

  • java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关。
  • File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
  • 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。

File类常用构造器:

  • public File(String pathname)
    • pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
    • 如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目路径下。
  • public File(String parent,String child)
    • 以parent为父路径,child为子路径创建File对象。
  • public File(File parent,String child)
    • 根据一个父File对象和子文件路径创建File对象。
  • 路径中的每级目录之间用一个路径分隔符隔开
    • windowsDOS系统默认使用“\”来表示。
    • UNIX和URL使用“/”来表示。
    • 为了解决这个隐患,File类提供了一个常量:public static final String separator。根据操作系统,动态的提供分隔符。
      • 使用示例:

File类常用方法

  • public String getAbsolutePath():获取绝对路径。
  • public String getParent():获取上层文件目录路径。若无,返回null
  • public String getPath() :获取路径。
  • public String getName() :获取名称。
  • public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
  • public long lastModified() :获取最后一次的修改时间,毫秒值。
  • public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组。
  • public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组。
  • public boolean renameTo(File dest):把文件重命名为指定的文件路径。
  • public boolean isDirectory():判断是否是文件目录。
  • public boolean exists() :判断是否存在。
  • public boolean isFile() :判断是否是文件。
  • public boolean canRead() :判断是否可读。
  • public boolean canWrite() :判断是否可写。
  • public boolean isHidden() :判断是否隐藏。
  • public boolean createNewFile():创建文件。若文件存在,则不创建,返回false
  • public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
  • public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。
  • public boolean delete():删除文件或者文件夹。Java中的删除不走回收站。要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
  • File类的使用示例:

JavaIO流

JavaIO原理

  • 输入input:读取外部数据(磁盘、光盘等存储设备的数据到程序(内存)中。
  • 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。

流的分类

  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)。
  • 按数据流的流向不同分为:输入流,输出流。
  • 按流的角色的不同分为:节点流,处理流。
    • 节点流:直接从数据源或目的地读写数据。
    • 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
  • IO流体系图:

InputStreamReader

  • InputStreamReader 是所有输入流的基类。
  • InputStream(典型实现:FileInputStream),主要方法:
    • int read()
      • 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
    • int read(byte[] b)
      • 从此输入流中将最多 b.length 个字节的数据读入一个byte数组中。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取的字节数。
    • int read(byte[] b, int off,int len)
      • 将输入流中最多 len 个数据字节读入 byte 数组,从偏移量off开始存储。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于文件末尾而没有可用的字节,则返回值 -1。
    • public void close() throws IOException
      • 关闭此输入流并释放与该流关联的所有系统资源。
  • Reader主要方法:
    • int read()
      • 读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个字节的Unicode码),如果已到达流的末尾,则返回 -1。
    • int read(char[] cbuf)
      • 将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
    • int read(char[] cbuf,int off,int len)
      • 将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
    • public void close() throws IOException
      • 关闭此输入流并释放与该流关联的所有系统资源。

OutputStreamWriter

  • OutputStreamWriter 非常相似,主要方法如下:
    • void write(int b/int c)
      • 将指定的字节写入此输出流。write的常规协定是:向输出流写入一个字节。要写入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。
    • void write(byte[] b/char[] cbuf)
      • b.length 个字节从指定的 byte 数组写入此输出流。
    • void write(byte[] b/char[] buff, int off, int len)
      • 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
    • void flush()
      • 刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立即写入它们预期的目标。
    • void close()
      • 关闭此输出流并释放与该流关联的所有系统资源。
  • 因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来替换字符数组,即以 String 对象作为参数。
    • void write(String str)
    • void write(String str, int off, int len)
  • 使用示例:

节点流注意事项

  • 在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被覆盖。如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容。
  • 在读取文件时,必须保证该文件已存在,否则报异常。
  • 字节流操作字节,比如:.mp3,.avi,.rmvb,mp4,.jpg,.doc,.ppt。
  • 字符流操作字符,只能操作普通文本文件。最常见的文本文件:.txt,.java,.c,.cpp 等语言的源代码。尤其注意.doc,excel,ppt这些不是文本文件。

处理流1:缓冲流

  • 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
  • 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
    • BufferedInputStreamBufferedOutputStream
    • BufferedReaderBufferedWriter
  • 当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区。
  • 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中读取下一个8192个字节数组。
  • 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法flush()可以强制将缓冲区的内容全部写入输出流。
  • 关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流。
  • 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷新缓冲区,关闭后不能再写出。
  • 使用示例:

处理流2:转换流

  • 转换流提供了在字节流和字符流之间的转换。字节流中的数据都是字符时,转成字符流操作更高效。很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能。
  • Java API提供了两个转换流:
    • InputStreamReader
      • InputStream转换为Reader,实现将字节的输入流按指定字符集转换为字符的输入流。需要和InputStream"套接"。
      • 构造器:
        • public InputStreamReader(InputStream in)
        • public InputSreamReader(InputStream in,String charsetName)
          • 使用:Reader isr = new InputStreamReader(System.in,"gbk")
    • OutputStreamWriter
      • Writer转换为OutputStream,实现将字符的输出流按指定字符集转换为字节的输出流。需要和OutputStream"套接"。
      • 构造器:
        • public InputStreamReader(InputStream in)
          - public InputSreamReader(InputStream in,String charsetName)
          • 使用: Reader isr = new InputStreamReader(System.in,"gbk")
    • 使用示例:

处理流3:标准输入输出流

  • System.inSystem.out分别代表了系统标准的输入和输出设备。默认输入设备是:键盘,输出设备是:显示器。
  • System.in的类型是InputStreamSystem.out的类型是PrintStream,其是OutputStream的子类。
  • 重定向:通过System类的setInsetOut方法对默认设备进行改变。
    • public static void setIn(InputStream in)
    • public static void setOut(PrintStream out)
  • 使用示例:
    • BufferedReader br = new BufferedReader(new InputStreamReader(System.in)), 把"标准"输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流

处理流4:打印流

  • 实现将基本数据类型的数据格式转化为字符串输出。
  • 打印流:PrintStreamPrintWriter
    • 提供了一系列重载的print()println()方法,用于多种数据类型的输出。
    • PrintStreamPrintWriter的输出不会抛出IOException异常。
    • PrintStreamPrintWriter有自动flush功能。
    • PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。
    • System.out返回的是PrintStream的实例。
  • 使用示例:

处理流5:数据流

  • 为了方便地操作Java语言的基本数据类型和String的数据,可以使用数据流。
  • 数据流有两个类:(用于读取和写出基本数据类型、String类的数据)
    • DataInputStreamDataOutputStream
    • 分别"套接"在 InputStreamOutputStream 子类的流上。
    • 主要方法如下:
      • boolean readBoolean()
      • byte readByte()
      • char readChar()
      • float readFloat()
      • double readDouble()
      • short readShort()
      • long readLong()
      • int readInt()
      • String readUTF()
      • void readFully(byte[] b)
  • 使用示例:

处理流6:对象流

  • 用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
  • 处理流的两个类为:ObjectInputStreamOjbectOutputSteam
  • 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制。流程如下:
    • 创建一个 ObjectOutputStream
    • 调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象
    • 注意写出一次,操作flush()一次。
  • 反序列化:用ObjectInputStream类读取基本类型数据或对象的机制。流程如下:
    • 创建一个 ObjectInputStream
    • 调用 readObject() 方法读取流中的对象。
  • 对象序列化的要求:
    • 类必须实现如下两个接口之一:SerializableExternalizable。否则,会抛出NotSerializableException异常。
    • 如果序列化的类中某个属性不是基本数据类型或String类型,而是另一个引用类型,那么这个引用类型必须是可序列化的(就是它也要实现那两个接口)。
    • 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
      • private static final long serialVersionUID
      • serialVersionUID用来表明类的不同版本间的兼容性。其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。(比如存对象时使用的UID是1,后面你对类进行了修改,UID改为了3,那么此时取出的对象和当前已修改了的新对象不兼容)。serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
      • 如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
  • 使用示例:

posted @   街晚  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示