menu ChaYedan
Java基础知识(三)
415 浏览 | 2020-04-12 | 阅读时间: 约 11 分钟 | 分类: Java | 标签: Java
请注意,本文编写于 900 天前,最后修改于 831 天前,其中某些信息可能已经过时。

File类

win中的路径需要用\\

概述

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作

构造方法

  • public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  • public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
  • public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

注意:

  1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
  2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。

获取功能的方法

  • public String getAbsolutePath() :返回此File的绝对路径名字符串。
  • public String getPath() :将此File转换为路径名字符串。构造方法写的什么返回的就是什么
  • public String getName() :返回由此File表示的文件或目录的名称。
  • public long length() :返回由此File表示的文件的长度。只能查看单个文件的长度。不能直接查看文件夹的大小

判断方法

  • public boolean exists() :此File表示的文件或目录是否实际存在。
  • public boolean isDirectory() :此File表示的是否为目录。
  • public boolean isFile() :此File表示的是否为文件。

创建删除功能的方法

  • public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
  • public boolean delete() :删除由此F ile表示的文件或目录。
  • public boolean mkdir() :创建由此File表示的目录。只能创建一级目录
  • public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。能创建多级目录

API中说明:delete方法,如果此File表示目录,则目录必须为空才能删除

目录的遍历

  • public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
  • public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

如果目录不存在,返回null。目录里面没内容,返回空列表。所以在遍历之前,看看是不是空指针。

IO流

IO流分类

字节流:所有一切都是字节流

字符流:只能操作纯文本,不能操作其他文件

输入流输出流
字节流字节输入流InputStream字节输出流OutputStream
字符流字符输入流Reader字符输出流Writer

OutputStream(字节输出流)

java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字
节输出流的基本共性功能方法。抽象类不能创建对象,需要使用子类。

常用方法
  • public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
  • public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
  • public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
  • public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输
    出到此输出流。
  • public abstract void write(int b) :将指定的字节输出流。

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

常用子类

FileOutputStream类:文件字节输出流,向文件中写字节。

构造方法(常用)
  • public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。
  • public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文
件,会清空这个文件的数据。

字符串变成字节数组:public byte[] getBytes()

踩坑记录:

FileOutputStream不能在不存在的文件路径写,比如说不存在的文件夹下面

续写以及换行写入

每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能
继续添加新数据呢?

  • public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的
    文件。
  • public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。

这两个构造方法,参数中都需要传入一个boolean类型的值, true 表示追加数据, false 表示清空原有数据。

回车符 r 和换行符 n :

回车符:回到一行的开头(return)。

换行符:下一行(newline)。

系统中的换行:

Windows系统里,每行结尾是 回车+换行 ,即 rn ;

Unix系统里,每行结尾只有 换行 ,即 n ;

Mac系统里,每行结尾是 回车 ,即 r 。从 Mac OS X开始与Linux统一。

InputStream(字节输入流)

java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入
流的基本共性功能方法。抽象类不能创建对象,需要使用子类。

常用方法
  • public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
  • public abstract int read() : 从输入流读取数据的下一个字节。返回的是读到的字节
  • public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。返回的是读取字节的数量。且每次最大的读取字节个数是b的长度

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

常用子类

java.io.FileInputStream 类是文件输入流,从文件中读取字节。

构造方法(常用)
  • FileInputStream(File file) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系
    统中的 File对象 file命名。
  • FileInputStream(String name) : 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件
    系统中的路径名 name命名。

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出 FileNotFoundException

字节数组变成字符串:public String (byte[] bs) 理用的是String的构造方法

字节流读取中文的问题

当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为
一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文
件。但是,如果你不把他输入到控制台来看,其实也不会有什么问题。

Reader(字符输入流)

java.io.Reader 抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。

常用方法
  • public void close() :关闭此流并释放与此流相关联的任何系统资源。
  • public int read() : 从输入流读取一个字符。遇到EOF返回-1
  • public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中。每次读取的长度跟字符数组的长度有关。返回的是读取的个数。
常用子类

java.io.FileReader 类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

注意:

  1. 字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。
    idea中UTF-8
  2. 字节缓冲区:一个字节数组,用来临时存储字节数据。
构造方法(常用)
  • FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。
  • FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。

Writer(字符输出流)

java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。

常用方法
  • public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
  • public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
  • public void write(int c) :写出一个字符。
  • public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
  • public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量
    off开始输出到此输出流。
  • public void write(String str) :写出一个字符串。
  • public void write(String str, int off, int len) :写出一个字符串的指定部分
常用子类

java.io.FileWriter 类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

构造方法
  • FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
  • FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
  • public FileWriter(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的
    文件。boolean类型的值, true 表示追加数据, false 表示清空原有数据。
  • public FileWriter(String name, boolean append) : 创建文件输出流以指定的名称写入文件。boolean类型的值, true 表示追加数据, false 表示清空原有数据。

当创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。

相关方法

字符串转换为字符数组字符串.toCharArray()

flush和close

字节流内部没有缓冲区,只要调用write方法,就是写出到目的地,所以不关流,也不会丢失数据。

字符流内部有缓冲区,调用write方法,先写到缓冲区,如果缓冲区数据满了,会自动刷新到目的地,如果没有执行关闭流的操作,会导致缓冲区可能还会有数据,程序停止后,数据就会丢失。备注:查看源代码,缓冲区是1024个字节

  • flush :刷新缓冲区,流对象可以继续使用。
  • close :关闭流,释放系统资源。关闭前会刷新缓冲区。

IO的异常处理

throws:声明抛出异常,交给调用者处理

try-catch:自己来处理

但记着一定要close,即finally里面一定要调用close。以及不要把要io对象在try中定义,因为加了一个大括号后,就变成了在一个大括号中的局部变量,需要在try这个大括号以外进行声明(提升作用域)。另外在finally中,close方法也会有异常,需要两个分开处理。因为如果两个写在同一个try中,如果第一个close有异常,第二个close就不会执行。

JDK1.7之后:

属性集(Properties类)

java.util.Properties 继承于 Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其
对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时, System.getProperties 方法就是返回
一个 Properties 对象。格式:属性名=属性值

  • Properties类是Map集合的实现类,Map中定义的方法,都有
  • Properties类继承Hashtable<K,V>时,已经确定了K的类型:Object,V的类型:Object。所以Properties类没有泛型,创建Properties类的对象时,不能指定泛型
  • Properties类是唯一一个和IO流结合使用的双列集合

构造方法(部分)

public Properties() :创建一个空的属性列表。

特有方法

与获取值相关的

  • public Object setProperty(String key, String value) : 保存一对属性(保存一个键值对,等价于map中的put方法)。
  • public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。
  • public Set<String> stringPropertyNames() :所有键的名称的集合。

与IO流相关的

  • public void load(InputStream inStream) : 从字节输入流中读取键值对。其实是将文件的属性按键值对呈现出来
  • public void load(Reader r) :把子类FileReader对象关联的源文件中的内容,以键值对的方式,加载到Properties中。

注意:

  • Properties集合加载的文件,建议拓展名写.properties
  • .properties中的内容,一个键值对占一行,格式:键=值

读取Properties文件的快捷方式

java.util包中的resourcebundle

使用方法:
ResourceBundle rb = ResourceBundle.getBundle("redis")

注意这里不用写后缀名,因为这个类专门读properties文件

调用方法

rb.getString("键名")就能读到相应值,返回类型为字符串

缓冲流

缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:

  • 字节缓冲流: BufferedInputStream , BufferedOutputStream
  • 字符缓冲流: BufferedReader , BufferedWriter

缓冲流的基本原理,是 在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。(按我的理解,说白了就是一个包装流)

字节缓冲流

内部定义了定义了一个长度为8192长度的数组

构造方法
  • public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
  • public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
常用方法
  • public void close(): 关闭流,释放资源
  • public void write(int b): 写出一个字节的
  • public void write(byte[] bs): 写出一个字节数组的
  • public void write(byte[] bs,int off,int len): 写出一个字节数组的一部分
  • public int read(): 读取一个字节
  • public int read(byte[] bs):读取一些字节,把读取到的多个字节的内容,存储到方法参数字节数组bs中

参数:

byte[] bs: 字节数组

int off: 起始索引

int len: 写出字节的个数

注意事项

  • 对于缓冲流,不要自己调用flush方法
  • 只需要关闭缓冲流,缓冲流内部的IO流会自动关闭

字符缓冲流

构造方法
  • public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。
  • public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
常用方法
  • public void close(): 关闭流释放资源
  • public void write(int ch): 写出一个字符
  • public void write(char[] chs): 写出一个字符数组
  • public void write(char[] chs,int index,int len): 写出一个字符数组的一部分
  • public void write(String str): 写出一个字符串
  • public void write(String str,int index,int len): 写出一个字符串的一部分
  • public int read(): 读取一个字符
  • public int read(char[] chs):读取一些字符,把读取到的一些字符存入到方法参数字符数组chs中,返回的是读取的字符的数量。遇到文件结束标志,返回-1,说明读取文件应该结束了。
特有方法
  • public String readLine() : 读取一行文本,遇到文件结束标志: 返回null。读取到的一行文本的内容,不包含换行符,遇到换行符,说明这一行结束了。遇到文件结尾,返回null
  • public void newLine():写入一行分隔符(换行符),自适应系统

转换流

如何获取String的指定编码格式的字节内容? 编码

     String类的成员方法
         public byte[] getBytes(): 根据平台默认编码表(IDEA默认编码表: UTF-8),获取String的字节数组
         public byte[] getBytes(String charsetName) : 根据方法参数指定的编码表,获取String的字节数组
             参数:
                String charsetName: 编码表的名称   常用的编码表 GBK/UTF-8

如何把字节数组,按照指定编码格式,转换成String 解码

     String类的构造方法
     public String(byte[] bs):
         根据平台默认编码表(IDEA默认编码表: UTF-8),把构造方法参数中指定的字节数组,转换成String

​ public String(byte[] bytes, String charsetName):
​ 根据构造方法指定编码表,把构造方法参数中指定的字节数组,转换成String

InputStreamReader类

转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定
的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

构造方法
  • InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
  • InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。

OutputStreamWriter类

构造方法
  • OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
  • OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。

序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 、 对象的

类型 和 对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。存储的是对象的完整的字节内容

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。 对象的数据 、 对象的类型 和 对象

中存储的数据 信息,都可以用来在内存中创建对象。

总结:

序列化:把对象写入到文件

注意

在对对象进行序列化操作之前,需要实现Serializable接口来启用序列化功能

ObjectOutputStream类

构造方法

public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream。

常用方法

public void writeObject(Object obj) : 将指定的对象写入 把方法参数obj写入文件

ObjectInputStream类

ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

构造方法

public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。

常用方法

public Object readObject() : 将指定的对象写入 把方法参数obj写入文件

注意事项

静态和瞬态不能序列化

静态:加了static的变量不能被序列化,因为静态是属于类

瞬态:被transient的内容也不能被序列化

序列号冲突异常

当类实现Serializable接口后,在编译时会根据类的成员变量计算一个long类型数字(序列号),被保存在.class文件当中,当序列化对象时,同事在储存对象的文件中,也保存一份序列号。

只要修改类的成员,序列号就会重新计算。

当进行反序列化时,从文件中读取对象,会用文件中的序列号和.class文件中的序列号做对比,如果不一致,爆出序列号冲突异常

解决方案:

手动指定固定的序列号,这样不管怎么修改,就不会修改序列号

例如

public class Employee implements java.io.Serializable {
    // 加入序列版本号,其中权限修饰符可以是任意的,但static,final,long,serialVersionUID这四个是固定的,后面的             //值可以自己设定
    private static final long serialVersionUID = 1L;
    public String name;
    public String address;
// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
    public int eid;
    public void addressCheck() {
    System.out.println("Address check : " + name + " -- " + address);
    }
}

打印流

平时我们在控制台打印输出,是调用 print 方法和 println 方法完成的,这两个方法都来自于java.io.PrintStream 类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

PrintStream类

构造方法

public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流。

特有方法

print(xxx):原样输出

println(xxx):原样输出

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,快来留言吧!