IO流常用类(打印流、序列化流、IO工具类)使用详解(二)

简介: IO流常用类(打印流、序列化流、IO工具类)使用详解(二)

打印流

概述、异同

虽然像 FileOutputStream、OutputStreamWriter 这些输出流可以输出信息,但是其会要求把数据先处理为字符串或字节数组,使用不便。为此在 Java IO 体系专门提供了两个打印流——PrintStream 字节打印流 、PrintWriter 字符打印流。二者均重载了print、println 等函数,方便开发者直接输出打印其它类型的数据

PrintStream 类和 PrintWriter 类的功能基本相同,PrintStream 能做的 PrintWriter 也都能实现,并且 PrintWriter 的功能更为强大。但由于 PrintWriter 出现的比较晚,较早的 System.out 使用的是 PrintStream 来实现的,所以为了兼容就没有废弃 PrintStream。

PrintStream 类和 PrintWriter 类最大的差别是:

  • PrintStream 在输出字符,将字符转换为字节时采用的是系统默认的编码格式,这样当数据传输另一个平台,而另一个平台使用另外一个编码格式解码时就会出现问题,存在不可控因素。
  • PrintWriter 可以在传入 Writer【OutputStreamWriter(OutputStream out, String charsetName)】时可由程序员指定字符转换为字节时的编码格式,兼容性和可控性会更好。


PrintStream:字节打印流

java.io.PrintStream extends OutputStream

特点:

  • PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

    PrintStream流中有两个特有的方法:print,println

  • 与其他输出流不同,PrintStream 永远不会抛出 IOException,创建对象的时候,传递路径不存在,可能会抛出文件找不到异常
  • PrintStream叫打印流,只负责输出(打印),不能读取

构造方法:

public PrintStream(File file)              // 打印流的目的地是一个文件
public PrintStream(OutputStream out)     // 打印流的目的地是一个字节输出流
public PrintStream(String fileName)     // 打印流的目的地是一个文件路径

成员方法:

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

自己特有的成员方法:

void print(Object x)        // 可以写任意类型数据,不换行
void println(Object x)      // 可以写任意类型的数据,换行


修改输出语句的目的地为打印流的目的地

使用System类中的方法setOut,修改输出语句的目的地(控制台)为打印流的目的地

static void setOut(PrintStream out)     // 重新分配“标准”输出流。

作用:不让输出语句在控制台输出了,在打印流的目的地文件中输出

使用示例

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class Demo01PrintStream {
    public static void main(String[] args) throws FileNotFoundException {
        /*
            基本使用
        */
        //1.创建PrintStream对象,构造方法中绑定要输出的目的地
        PrintStream ps = new PrintStream("day22\\print1.txt");
        //2.使用PrintStream对象中的方法write,print,println,把数据写入到文件中
        //继承自父类OutputStream的共性的成员方法write:使用write写数据,查看的时候,会查询编码表
        ps.write(97);//a

        //自己特有的成员方法:print,println写数据,原样输出
        ps.println(97);//97
        ps.println('@');//@
        ps.println(true);//true
        ps.println(1.1);//1.1
        ps.println("aaa");//aaa

        //3.释放资源
        ps.close();

        //打印字符数组不是地址值,是数组中的元素 void println(char[] x) 打印字符数组(字符串底层就是字符数组)
        char[] chars = {'a','b','c'};
        System.out.println(chars);//abc
        System.out.println("abc");//abc
        
        
        /*
            修改输出语句的目的地为打印流的目的地
        */
        System.out.println("输出语句的目的地默认是在控制台输出!");

        PrintStream ps = new PrintStream("day22\\print2.txt");
        System.setOut(ps);//修改输出语句的目的地(控制台)为打印流的目的地

        System.out.println(1);
        System.out.println(2);
        System.out.println(3);
        System.out.println("输出语句的目的地不是控制台了,是print2.txt文件中");
    }
}


PrintWriter:字符打印流

java.io.PrintWriter extends Writer

构造方法:

public PrintWriter(Writer out)
public PrintWriter(Writer out, boolean autoFlush)
public PrintWriter(OutputStream out)
public PrintWriter(OutputStream out, boolean autoFlush)
public PrintWriter(String fileName)
public PrintWriter(String fileName, String charsetName)
public PrintWriter(File file)
public PrintWriter(File file, String charsetName)

成员方法:

public void close()             // 关闭此输出流并释放与此流相关联的任何系统资源
public void flush()             // 刷新此输出流并强制任何缓冲的输出字节被写出
public void write(int c)
public void write(char buf[])
public void write(char buf[], int off, int len)
public void write(String s)
public void write(String s, int off, int len)
public PrintWriter append(CharSequence csq)
public PrintWriter append(CharSequence csq, int start, int end)
public PrintWriter append(char c)

特有的成员方法:

public void print(Object x)        // 可以写任意类型的数据,不换行
public void println(Object x)      // 可以写任意类型的数据,换行
// 使用指定的格式字符串和参数将格式化的字符串写入到这个写入器的便捷方法。如果启用了自动刷新,则对该方法的调用将刷新输出缓冲区
public PrintWriter printf(String format, Object ... args)

使用示例

import java.io.*;
import java.util.Locale;

public class PrintWriterDemo {
   public static void main(String[] args) {
      String s = "Hello World";
      
      try {
         PrintWriter pw = new PrintWriter(System.out);

         // %s 表示将在那里放置一个字符串,即s
         pw.printf(Locale.UK, "This is a %s program", s);

         // 换行
         pw.println();

         // %d 表示将放置一个整数,即100
         pw.printf(Locale.UK, "This is a %s program with %d", s, 100);

         pw.flush();
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}


序列化流

ObjectOutputStream:对象的序列化流

java.io.ObjectOutputStream extends OutputStream

作用:把对象以流的方式写入到文件中保存

构造方法:

public ObjectOutputStream(OutputStream out)     // 创建写入指定 OutputStream 的 ObjectOutputStream。
/* 参数:
        OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象
*/

特有的成员方法:

void writeObject(Object obj)         // 将指定的对象写入 ObjectOutputStream


ObjectInputStream:对象的反序列化流

java.io.ObjectInputStream extends InputStream

作用:把文件中保存的对象以流的方式读取出来使用

构造方法:

public ObjectInputStream(InputStream in)     // 创建从指定 InputStream 读取的 ObjectInputStream。
/* 参数:
        InputStream in:传递字节输入流,我们可以传递InputStream的任意子类对象
*/

特有的成员方法:

 Object readObject()     // 从 ObjectInputStream 读取对象


不能被序列化的情况

transient:瞬态关键字

被 transient 关键字修饰的变量不能被序列化

private transient int age;

oos.writeObject(new Person("小美女", 18));    // 不会把18写入到文件中
Object obj = ois.readObject();              // Person{name='小美女', age=0}


static:静态关键字

被static修饰的成员属于类,不属于某一个对象,被所有的对象所共享使用

被static修饰的成员,也不能序列化,序列化的是对象

private static int age;

oos.writeObject(new Person("小美女",18));     // 不会把18写入到文件中
Object obj = ois.readObject();              // Person{name='小美女', age=0}


可能抛出的异常

NotSerializableException

  • 在进行序列化|反序列化时,抛出 NotSerializableException:没有序列化异常
  • 实体类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。

    Serializable接口是一个标记型接口,类实现了 Serializable 接口,接口就会给类添加上一个标记。

    当进行序列化和反序列化的时候,JVM会检查类上是否有标记,有则序列化反序列化成功,没有会抛出异常

    实体类 ==> 添加上了标记 ==> 放心进行序列化和反序列化了 ==> 类做不做其他的用途没有影响


ClassNotFoundException

public final Object readObject() throws IOException, ClassNotFoundException
/*    readObject方法声明抛出了两个异常对象
    ClassNotFoundException:找不到class文件异常
*/

反序列化有两个前提:

  • 类实现 Serializable 接口
  • 类有对应的 class 文件(Person.class)


序列号冲突异常

1594540253575.png

可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)

显式声明其自己的 serialVersionUID:

private static final long serialVersionUID = xxL;

在类中手动添加了一个序列号,无论类是否修改,序列号都是固定写死的常量值,值是不会改变的,也就不会抛出异常了

例如:

public final class MyString implements java.io.Serializable

private static final long serialVersionUID = -6849794470754667710L;

示例:

public class Person implements Serializable{
    private static final long serialVersionUID = 1L;
    
    private String name;
    public int age;
}


案例

文件复制(缓冲流)

import java.io.*;

@slf4j
public class Demo03CopyFile {
    public static void main(String[] args) {
        /*
            字节缓冲流
        */
        long s = System.currentTimeMillis();

        try(
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\全球通史.txt"));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\全球通史.txt"));
        ){
            //一读一写复制文件
            byte[] bytes = new byte[1024 * 500];
            int len = 0;
            while ((len = bis.read(bytes)) != -1){
                bos.write(bytes, 0, len);    //写有效字节个数(最后一次读取不一定是1024个)
                bos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        long e = System.currentTimeMillis();
        log.info("复制文件共耗时:" + (e-s) + "毫秒");
        
        
        /*
            字符缓冲流
        */
        try(
            BufferedReader br = new BufferedReader(new FileReader("day22\\csb.txt"));
            BufferedWriter bw = new BufferedWriter(new FileWriter("day22\\出师表.txt"));
        ){
            //一读一写复制文件
            String line;
            while ((line = br.readLine()) != null){
                //5.把读取的每行数据,存储到ArrayList集合中
                bw.write(s);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


转换文件编码

将 GBK 编码的文本文件,转换为 UTF-8 编码的文本文件。

基本步骤:

​ 1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和GBK编码名称

​ 2.创建OutputStreamWriter对象,构造方法中传递FIleOutputStream对象和UTF-8编码名称

​ 3.使用InputStreamReader对象中的方法read,读取GBK编码的文件

​ 4.使用OutputStreamWriter对象中的方法write,把读取到的数据,以UTF-8编码,写入到内存缓冲区中

​ 5.释放资源(会先调用flush方法刷新数据到文件中)

import java.io.*;

public class Demo04Test {
    public static void main(String[] args) throws IOException {
        try (
            //1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和指定的编码表名称
            InputStreamReader isr = new InputStreamReader(new FileInputStream("day22\\utf-8.txt"),"GBK");
        ){
            //2.创建OutputStreamWriter对象,构造方法中传递FIleOutputStream对象和UTF-8编码名称
            //OutputStreamWriter osw = new OutputStreamWriter(
            //        new FileOutputStream("day22\\utf-82.txt"),"UTF-8");
            //不写编码名称默认UTF-8
            //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day22\\utf-83.txt"));
            FileWriter osw = new FileWriter("day22\\utf-84.txt");
            //3.使用InputStreamReader对象中的方法read,读取GBK编码的文件
            int len = 0;
            while ((len = isr.read()) != -1){
                //4.使用OutputStreamWriter对象中的方法write,把读取到的数据,以UTF-8编码,写入到内存缓冲区中
                osw.write(len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


IO工具类

java.io.File

参考:https://www.runoob.com/java/java-file.html

描述:文件和目录路径名的抽象表示形式

常用静态变量:

// 与系统有关的路径分隔符。 windows中分号";",Linux中冒号":"
static String pathSeparator
static char pathSeparatorChar

// 与系统有关的默认名称(文件夹名称)分隔符。windows中右斜杠"\",Linux中左斜杠"/"
static String separator
static char separatorChar

构造方法:

public File(String pathname)
public File(String parent, String child)
public File(File parent, String child)

常用方法:

/* 判断功能 */
// 此File表示的文件或目录是否实际存在
boolean exists()
// 是否为目录(文件夹)    // 需先判断路径是否实际存在
boolean isDirectory()
// 是否为文件          // 需先判断路径是否实际存在
boolean isFile()
// 测试此抽象路径名是否为绝对路径名
boolean isAbsolute()
// 测试此抽象路径名与给定对象是否相等
boolean equals(Object obj)
// 测试应用程序是否可以读取此抽象路径名表示的文件
boolean canRead()
// 测试应用程序是否可以修改此抽象路径名表示的文件
boolean canWrite()
    
/* 创建删除功能 */
// 当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。// 路径必须是存在的和有权访问的,否则会抛出异常。路径必须是存在的和有权访问的,否则会抛出异常。// 文件存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean createNewFile() throws IOException
// 创建单级文件夹 // 文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean mkdir()
// 即可以创建单级文件夹,又可以创建多级文件夹 // 文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean mkdirs()
// 删除文件或文件夹,不走回收站 // 路径不存在或者文件夹中有内容,不会删除,返回false
boolean delete()

/* 目录遍历 */
// 返回一个String数组,表示该File目录中的所有子文件或目录        // 路径必须是目录,否则会抛异常
String[] list()
// 返回一个File数组,表示该File目录中的所有的子文件或目录        // 路径必须是目录,否则会抛异常
File[] listFiles()

// 返回由此抽象路径名表示的文件或目录的名称(末尾部分)
String getName()
// 返回抽象路径名的绝对路径名字符串
String getAbsolutePath()
// 获取文件的大小,单位是字节
long length()
// 重新命名此抽象路径名表示的文件
boolean renameTo(File dest)


commons-io 工具包

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency

commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类

IOUtils 工具类

包路径:org.apache.commons.io.IOUtils;

处理输入 - 输出流。所有成员字段和方法都是静态的

链接:https://blog.csdn.net/l2580258/article/details/89227761

常用静态变量:

static String LINE_SEPARATOR;                        // 行分隔符
static String LINE_SEPARATOR_UNIX = "\n";            // Unix系统的行分隔符
static String LINE_SEPARATOR_WINDOWS = "\r\n";        // Windows系统的行分隔符

常用静态方法:

注:类中的所有处理InputStream的方法都带有内部的缓冲区,所以不需要再使用 BufferedReader或者 BufferedInputStream,默认的缓冲区大小为4K,不过也可以自定义它的大小。

// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
static int copy(Reader input, Writer output)                            // 字符流
static int copy(InputStream input, OutputStream output)                    // 字节流
static void copy(InputStream input, Writer output, Charset encoding)
// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)
static long copyLarge(InputStream input, OutputStream output)
static long copyLarge(Reader input, Writer output)
    
// 从流中读取内容,并转换为String的list
static List<String> readLines(InputStream input)
static List<String> readLines(InputStream input, String encoding)
        // input 的类型可以为 InputStream,Reader
        // encoding 的类型可以为 Charset,String

// 把数据写入到输出流中
static void write(String data, OutputStream output)
static void write(String data, OutputStream output, String encoding)
// 把string的List写入到输出流中
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output)
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output, String encoding)
        // data 的类型可以为 byte[],CharSequence,StringBuffer,String
        // output 的类型可以为 OutputStream,Writer
        // encoding 的类型可以为 Charset,String

// 无条件的关闭一个可被关闭的对象而不抛出任何异常。
// 重载支持关闭所有的InputStream、OutputStream、Reader和Writer。
static void closeQuietly(Closeable closeable)

// 比较两个Reader对象的内容是否相同,相同返回true,否则返回false
static boolean contentEquals(Reader input1, Reader input2)
static boolean contentEquals(InputStream input1, InputStream input2)
// 比较两个Reader对象的内容是否相同,忽略行结束符而比较内容
static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2)

// 从InputStream中返回一个行迭代器。行迭代器将持有一个打开的InputStream的引用。迭代结束后,应当关闭stream来释放内部资源。
static LineIterator lineIterator(InputStream input, String encoding)
        // input 的类型可以为 InputStream,Reader
        // encoding 的类型可以为 Charset,String。传null则使用默认的

// 返回字符输入流缓冲流
static BufferedReader toBufferedReader(Reader reader)
static BufferedReader toBufferedReader(Reader reader, int size)
// 返回字节输入流缓冲流
static InputStream toInputStream(CharSequence input)
static InputStream toInputStream(CharSequence input, String encoding)

// 返回字符串
static String toString(Reader input)
static String toString(InputStream input, String encoding)
static String toString(URI uri)
static String toString(URI uri, Charset encoding)
static String toString(URL url, Charset encoding)
static String toString(URL url, String encoding)
        // input 的类型可以为 InputStream,Reader,byte[]


FileUtils 工具类

包路径:org.apache.commons.io.FileUtils;

操作文件的工具类

常见工具类:

// 读取一个文件以字符串形式返回
static String readFileToString(File file)
static String readFileToString(File file, String encoding)

// 文件复制
static void copyFile(File srcFile, File destFile)
// 复制整个文件夹到另外一个地方
static void copyDirectory(File source, File destination)
// 复制整个文件夹到另外一个地方,过滤一些指定的文件(比如名字,修改时时间等等)
static void copyDirectory(File source, File destination, FileFilter filter)
// 把一个文件复制到一个文件夹中
static void copyFileToDirectory(File srcFile, File destDir)
// 文件夹复制
static void copyDirectoryToDirectory(File srcDir, File destDir)

// 使用指定的编码将CharSequence写入文件中
static void write(File file, CharSequence data)
// 将集合按行写入到文件中
static void writeLines(File file, Collection<?> lines)
// 把字符串写入到一个文件中
static void writeStringToFile(File file, String data)

// 返回一个File对象
static File getFile(String... names)
// 返回表示系统临时目录的File对象
static String getTempDirectory()
// 返回表示用户目录的File对象
static String getUserDirectory()
// 创建了一个迭代器,可以按行遍历给定的文件
static LineIterator lineIterator(File file)
// 返回目录内容的大小
static long sizeOfDirectory(File directory)

// 比较两个文件的内容,返回比较的结果
static boolean contentEquals(File file1, File file2)

// 递归的删除一个文件夹
static void deleteDirectory(File directory)


FilenameUtils 工具类

参考:https://www.cnblogs.com/xwb583312435/p/9014868.html

路径:org.apache.commons.io.FilenameUtils;

常用方法:

// 获取当前系统格式化路径
static String normalize(String filename)
// 获取当前系统无结尾分隔符的路径
static String normalizeNoEndSeparator(String filename)

// 合并目录和文件名为文件全路径
static String concat(String basePath, String fullFilenameToAdd)

// 获取文件名称,包含后缀
static String getName(String filename)
// 获取文件路径去除目录和后缀后的文件名
static String getBaseName(String filename)
// 获取文件的后缀
static String getExtension(String filename)
// 获取文件的完整目录(示例:/D:/aa/bb/cc/)
static String getFullPath(String filename)
// 获取文件的目录不包含结束符(示例:/D:/aa/bb/cc)
static String getFullPathNoEndSeparator(String filename)
// 获取去除前缀的路径(示例:D:/aa/bb/cc/)
static String getPath(String filename)
// 获取去除前缀并结尾去除分隔符的路径(示例:D:/aa/bb/cc)
static String getPathNoEndSeparator(String filename)
// 获取前缀
static String getPrefix(String filename)
// 获取最后一个.(文件名与拓展名的分隔符)的位置
static int indexOfExtension(String filename)
// 获取最后一个分隔符的位置
static int indexOfLastSeparator(String filename)

// 转换分隔符为当前系统分隔符
static String separatorsToSystem(String path)
// 转换分隔符为linux系统分隔符
static String separatorsToUnix(String path)
// 转换分隔符为windows系统分隔符
static String separatorsToWindows(String path)

// 判断文件路径是否相同
static boolean equals(String filename1, String filename2)
// 判断文件路径是否相同,格式化并大小写不敏感    // IOCase.INSENSITIVE
static boolean equals(String filename1, String filename2, boolean normalized, IOCase caseSensitivity)
// 判断文件路径是否相同,格式化并大小写敏感
static boolean equalsNormalized(String filename1, String filename2)
// 判断文件路径是否相同,不格式化,大小写敏感根据系统规则:windows:敏感;linux:不敏感
static boolean equalsOnSystem(String filename1, String filename2)

// 判断文件扩展名是否等于指定扩展名
static boolean isExtension(String filename, String extension)
// 判断文件扩展名是否包含在指定字符串数组中
static boolean isExtension(String filename, String[] extensions)
// 判断文件扩展名是否包含在指定集合中
static boolean isExtension(String filename, Collection<String> extensions)

// 判断文件扩展名是否和指定规则匹配,大小写敏感
static boolean wildcardMatch(String filename, String wildcardMatcher)
// 判断文件扩展名是否和指定规则匹配,大小写不敏感        // IOCase.INSENSITIVE
static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity)
// 判断文件扩展名是否和指定规则匹配,根据系统判断敏感型:windows:不敏感;linux:敏感
static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher)
    
// 移除文件的扩展名
static String removeExtension(String filename)
// 判断目录下是否包含指定文件或目录
static boolean directoryContains(String canonicalParent, String canonicalChild)


拓展

Properties 集合

java.util.Properties extends Hashtable<k,v> implements Map<k,v>

  • Properties(属性) 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。
  • Properties 集合是一个唯一和 IO 流相结合的集合:

    • 可以使用 Properties 集合中的方法 store(),把集合中的临时数据 持久化到 硬盘中存储(内存 ==> 硬盘)
    • 可以使用 Properties 集合中的方法 load(),把硬盘文件中保存的键值对 读取到 内存中集合里边使用(硬盘 ==> 内存)
  • 属性列表中每个键及其对应值都是一个字符串。

    Properties 是一个双列集合,不需要写泛型,key 和 value 默认都是字符串String类型


常用方法:

Object setProperty(String key, String value)  // 往Properties集合中添加键值对,相当于Map集合的put方法
String getProperty(String key)             // 根据key获取value,相当于Map集合的get(key)方法
Set<String> stringPropertyNames()         // 返回此属性列表中的键集,相当于Map集合的keySet方法

// 把集合中的临时数据,持久化到硬盘中存储(内存-->硬盘)
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
/* 方法的参数:
        OutputStream out:传递字节输出流,不能写中文,会出现乱码,可以传递OutputStream的任意子类对象
        Writer writer:传递字符输出流,能写中文,不会出现乱码,可以传递Writer的任意的子类对象
        String comments:注释解释说明我们保存文件是做什么用的,一般传递""
                         注释不能写中文,默认使用Unicode编码,写中文会出现乱码
*/

// 把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘-->内存)
void load(InputStream inStream)     // 传递字节输入流,不能读取含有中文的文件,可以传递InputStream的任意子类对象
void load(Reader reader)              // 传递字符输入流,可以读取含有中文的文件,可以传递Reader的任意子类对象
/* 注意:
        1.在Properties集合的配置文件中,可以使用 # 进行注释,被注释的键值对不会被读取
        2.在Properties集合的配置文件中,健和值之间可以使用 =,空格,冒号 等一些符号作为键与值的分割符号
        3.在Properties集合的配置文件中,健和值默认都是String类型,不需要添加引号,否则会画蛇添足
*/


使用示例

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

public class Demo01Properties {
    public static void main(String[] args) {
        /*
            基本使用:使用Properties集合存储数据,遍历集合获取集合中的元素
        */
        Properties prop = new Properties();
        //使用Properties集合中的方法setProperty往集合中添加键值对
        prop.setProperty("迪丽热巴","168");
        prop.setProperty("古力娜扎","165");
        //使用Properties集合中的方法stringPropertyNames,获取集合中所有的key,把key存储到一个Set集合中返回
        Set<String> set = prop.stringPropertyNames();
        //遍历Set集合,获取Properties集合的每一个key
        for (String key : set) {
            //使用Properties集合中的方法getProperty根据key获取value
            String value = prop.getProperty(key);
            System.out.println(key + "=" + value);
        }
        
        
        /*
            把集合中的临时数据,持久化到硬盘中存储(内存-->硬盘)
        */
        /*FileOutputStream fos = new FileOutputStream("day21\\prop1.txt");
        prop.store(fos, "save data");
        fos.close();*/
        // 如果对象只使用一次,可以使用匿名对象(会自动关闭)
        prop.store(new FileOutputStream("day21\\prop1.txt"), "save data");
        prop.store(new FileWriter("day21\\prop2.txt"), "save data");
        // 一般存储键值对的文件,叫配置文件,文件的后缀名一般都使用.properties
        prop.store(new FileWriter("day21\\prop.properties"), "save data");
        
        
        /*
            把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘-->内存)
        */
        Properties prop = new Properties();
        // 使用Properties集合中的方法load,把硬盘文件中保存的键值对,读取到内存中集合里边使用
        //prop.load(new FileInputStream("day21\\prop.properties"));
        prop.load(new FileReader("day21\\prop.properties"));
        // 遍历Properties集合
        Set<String> set = prop.stringPropertyNames();
        Iterator<String> it = set.iterator();
        while (it.hasNext()){
            String key = it.next();
            String value = prop.getProperty(key);
            System.out.println(key+"\t"+value);
        }
    }
}

prop.properties

#save data
#Fri Jul 10 14:51:47 CST 2020
赵丽颖 160
杨幂:172
#古力娜扎=165
"迪丽热巴"=168
#马尔扎哈=180


ResourceBundle 工具类

java.util.ResourceBundle:操作资源的工具类

作用:我们可以使用ResourceBundle类中的方法读取以 .properties 结尾的文件

注意:

  • ResourceBundle是一个抽象类,我们无法直接创建对象使用,我们可以使用ResourceBundle类中的静态方法获取ResourceBundle的子类对象

    static ResourceBundle getBundle(String baseName)
    /* 参数:
            String baseName:传递以.properties结尾的文件名称
            data.properties ==> 传递data
    */
  • 以properties结尾的文件必须放在当前模块的src下边,否则获取对象找不到配置文件,会抛出异常MissingResourceException: Can't find bundle for base name data, locale zh_CN


常用方法:

 // 用于读取配置文件(存储的都是键值对)
String getString(String key)      // 根据配置文件中key,读取配置文件中的value
/* 注意:
        配置文件中的key和value不要使用中文
*/


使用示例

import java.util.ResourceBundle;

public class Demo02ResourceBundle {
    public static void main(String[] args) {
        //获取ResourceBundle对象
        ResourceBundle bundle = ResourceBundle.getBundle("data");
        //使用ResourceBundle对象中的方法getString,根据配置文件中key,读取配置文件中的value
        String username = bundle.getString("username");
        System.out.println(username);//jack
        
        String password = bundle.getString("password");
        System.out.println(password);//1234
        
        String sex = bundle.getString("sex");
        System.out.println(sex);//Å®(sex=女)
        
        //String age = bundle.getString("年龄");//java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key 年龄
        //System.out.println(age);
    }
}

data.properties(放在src的下边)

username=jack
password=1234
sex=女
年龄=18

IO 类思维导图

IO类思维导图.png

ASCII码表完整版

image-20221218231514111.png

相关文章
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
Java
缓冲流和转换流的使用【 File类+IO流知识回顾③】
这篇文章介绍了Java中缓冲流(BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter)和转换流(InputStreamReader, OutputStreamWriter)的使用,包括它们的构造方法和如何利用它们提高IO操作的效率及处理字符编码问题。
缓冲流和转换流的使用【 File类+IO流知识回顾③】
|
2月前
|
存储 Java 调度
FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】
这篇文章回顾了Java中FileInputStream、FileOutputStream、FileReader和FileWriter类的基本使用方法,包括读取和写入文件的操作,以及字符流和字节流的区别和应用场景。
FileInputStream,FileOutputStream 和 FileReader ,FileWriter 类的基本使用【 File类+IO流知识回顾②】
|
2月前
|
Java
File类的基本使用【 File类+IO流知识回顾①】
这篇文章回顾了Java中File类的基本使用,包括创建File对象、获取文件数据信息、判断文件存在与否、创建和删除文件目录,以及遍历文件目录的方法。
File类的基本使用【 File类+IO流知识回顾①】
|
2月前
|
存储 Java
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
这篇文章介绍了Java中ObjectInputStream和ObjectOutputStream类的基本使用,这两个类用于实现对象的序列化和反序列化。文章解释了序列化的概念、如何通过实现Serializable接口来实现序列化,以及如何使用transient关键字标记不需要序列化的属性。接着,通过示例代码演示了如何使用ObjectOutputStream进行对象的序列化和ObjectInputStream进行反序列化。
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
|
3月前
|
Java
IO流操作-------File类、输入流和输出流(二)
这篇文章介绍了Java中IO流操作的基本概念和使用,包括字节流和字符流的读取与写入,以及如何使用缓冲流提高文件读写效率和实现文件复制的方法。
IO流操作-------File类、输入流和输出流(二)
|
2月前
|
JSON 安全 编译器
扩展类实例的序列化和反序列化
扩展类实例的序列化和反序列化
35 0
|
3月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
3月前
|
JSON Java 数据格式
【IO面试题 七】、 如果不用JSON工具,该如何实现对实体类的序列化?
除了JSON工具,实现实体类序列化可以采用Java原生序列化机制或第三方库如Protobuf、Thrift、Avro等。
|
3月前
|
Java
IO流操作-------File类(一)
这篇文章介绍了Java中File类的常用操作,包括创建文件/文件夹、删除文件、查询文件属性(如存在性、大小、名称、路径)以及递归遍历文件夹下所有文件的方法。
IO流操作-------File类(一)