IO流
一、什么是io流
I:input 输入(读取)
O:output 输出(写入)
流:数据(字符、字节)1个字符 = 2个字节,一个字节 = 8个二进制位
简单的说就是:读取与写入
输入:把数据从硬盘上,读取到内存中使用
输出:把内存中的数据,写出到硬盘上保存
输入流 | 输出流 | |
---|---|---|
字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输出流 Writer |
Java 中 I/O 操作主要是指使用 java.io 包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做写出数据。
二、字节流
2.1字节输出流【OutputStream】
java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将制定的字节信息写出到目的地,它定义了字节输出流的基本共性功能方法。
void |
close() 关闭此输出流并释放与此流相关联的任何系统资源。 |
---|---|
void |
flush() 刷新此输出流并强制任何缓冲的输出字节被写出。 |
void |
write(byte[] b) 将 b.length 字节从指定的字节数组写入此输出流。 |
void |
write(byte[] b, int off, int len) 从指定的字节数组写入 len 个字节,从偏移 off 开始输出到此输出流。 |
abstract void |
write(int b) 将指定的字节写入此输出流。 |
close方法,当完成流的操作时,必须调用此方法,释放系统资源
FilterOutputStream类
java.io.FilterOutputStream 类是文件字节输出流,用于将内存中的数据写入到硬盘的文件中。
构造方法
FileOutputStream(File file) 创建文件输出流以写入由指定的 File 对象表示的文件。
FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。
参数:写入数据的目的地
File file:目的地是一个文件
String name:目的地是一个文件的路径
作用:
- 创建一个 fileOutputStream 对象
- 会根据构造方法中传递的文件、文件路径,创建一个空的文件。
- 会把 FileOutputStream 对象指向创建好的文件
原理
java程序–>JVM(java虚拟机)–>os(操作系统)–>os调用写数据的方法–>把数据写入到文件中
步骤(重点)
- 创建一个 FileOutputStream 对象,构造方法中传递写入数据的目的地
- 调用 FileOutputStream 对象中的方法
write
,把数据写入到文件中 - 释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
import java.io.FileOutputStream;
import java.io.IOException;
public class MyOutputStream {
public static void main(String[] args) throws IOException {
//报错,需要抛出一个文件找不到异常“throws IOException”
//1. 创建一个FileOutputStream 对象,构造方法中传递写入数据的目的地
FileOutputStream fos = new FileOutputStream("I:\\javaclass\\src\\com\\sxmz\\IoClass\\class01\\a.txt");
//2.调用 FileOutputStream 对象中的方法 write(文件指定输出流),把数据写入到文件中
fos.write(97);
//3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
fos.close();
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class MyOutputStream02 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("I:\\javaclass\\src\\com\\sxmz\\IoClass\\class01\\b.txt");
//一次只能写一个,很麻烦
fos.write(49);
fos.write(48);
fos.write(48);
/*
byte[] b 将b.length 字节从指定的字节数组写入此输出流。
一次写多个字符:
如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
如果写的是一个字节是负数,
那么第一个字节会和第二个字节,
两个字节组成一个中文显示
查询系统默认码表(GBK)
*/
byte[]bytes = {
65,66,67,68,69};//ABCDE
//byte[]bytes2 = {-65,-66,-67,68,69,-70,71};//烤紻E篏
fos.write(bytes);
//fos.write(bytes2);
/*
write(byte[] b, int off, int len)
从指定的字节数组写入 len个字节,
从偏移 off开始输出到此输出流。
*/
fos.write(bytes,1,3);
/*
写入字符的方法:可以使用String类中的方法把字符串转换为字节数组
byte[] getBytes 把字符串转换为字节数组
*/
byte[] bytes3 = "你好".getBytes();
//[-28, -67, -96, -27, -91, -67]
System.out.println(Arrays.toString(bytes3));
fos.write(bytes3);
fos.close();
}
}
write():单个输入
write(byte[] b) :字节数组输入
write(byte[] b, int off, int len):指定某一数组位置
byte[] getBytes:利用getBytes
可将String类字符串转换为字节数组
文件存储原理和即使本打开文件的原理
写数据的时候,会把10进制的整数97,转换为二进制整数97,。
fos.write(1100001);97–>1100001
任意的文本编译器(记事本,notepad++…)
在打开文件的时候,都会查询编码表,把字节转换为字符表示
0-127:查询ASCII表示(97–>a)
其他值:查询系统默认码表(中文系统GBK)
数据追加续写
FileOutputStream(String name, boolean append)
创建文件输出流以指定的名称写入文件。
FileOutputStream(File file, boolean append)
创建文件输出流以写入由指定的 File
对象表示的文件
String name,File file:写入数据的目的地
boolean append:追加写开关
-
true:创建对象不会覆盖原源文件,继续在文件的末尾追加写数据
-
false:创建一个新文件,覆盖源文件
数据换行
写换行代码
windows:\r\n
Linux:/n
mac:/r
import java.io.FileOutputStream;
import java.io.IOException;
public class MyOutputStream03 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("src\com\sxmz\IoClass\class01\c.txt",true);
for (int i = 0; i <=10 ; i++) {
fos.write("你好".getBytes());
fos.write("\r\n".getBytes());
}
fos.close();
}
}
2.2字节输入流【InputStream】
java.io.InputStream
此抽象类是表示字节输入流的所有类的超类
read()
从输入流读取数据的下一个字节
read(byte[] b)
从输入流读取一些字节数,并将它们存储到缓冲区 b
close()
关闭此输入流并释放与流相关联的任何系统资源
FileInputStream类【文件字节输入流】
FileInputStream
文件字节输入流
java.io.FileInputStream extemds InputStream
作用:把硬盘文件中的数据,读取到内存中使用
构造器方法
FileInputStream(String name)
FileInputStream(File file)
参数:读取文件的数据流
String name:文件的路径
File file:文件
作用:
- 会创建一个 FileInputStream 对象
- 会把 FileInputStream 对象指定构造方法中要读取的文件
原理
硬盘–>内存
java程序–>JVM–>os–>os读取数据的方法–>读取文件
步骤(重点)
- 创建 FileInputStream 对象,构造方法中绑定要读取的数据源
- 使用 FileInputStream 对象中的方法read ,读取文件
- 释放资源
import java.io.FileInputStream;
import java.io.IOException;
public class MyInputStream {
public static void main(String[] args) throws IOException {
//创建 FileInputStream 对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("src\\com\\sxmz\\IoClass\\class01\\a.txt");
//使用 FileInputStream 对象中的方法read ,读取文件
//int redd()读取文件中的字节并返回,同时位置递增,读取到文件的末尾返回-1
/* int len = fis.read();
System.out.println(len); //a-97
len = fis.read(); //上次赋值后,位置已递增至后一位
System.out.println(len); //b-98
len = fis.read();
System.out.println(len); //c-99
len = fis.read();
System.out.println(len); //-1
*/
/*
发现以上读取文件是重复的过程,所以可以使用循环优化
不知道文件中有多少字节,使用while循环
while 循环结束条件,读取到-1的时候结束
布尔表达式(len=fis.read()) !=-1
1.fis.read():读取一个字节
2.len = fis.read():把读取的字节赋值给变量len
3.len=fis.read()) !=-1:判断变量len是否不等于-1
*/
int len = 0;
while ((len=fis.read()) !=-1){
System.out.print(len+" ");
System.out.println((char)len+" ");
}
/*
while (fis.read() !=-1){
System.out.println(fis.read()); //输出结果为:98 , -1
//由于fis.read()判断成功后递进为98位,打印结果就为98.同时又递进为99位
//99位再次判断成功后递进为-1位,再次打印就为-1
//所有需要将fis.read()赋值给变量len进行打印
}
*/
//释放资源
fis.close();
}
}
读取多个字节
int read(byte[] b)
从输入流中读取一定数量的字节,并将它们存储到缓冲区 b 中。
明确两件事情:
-
方法的参数 byte[] 的作用?
起到缓存作用,存储每次读取到的多个字节
数组的长度一般定义为1024(1kb) 或者 1024的倍数
-
方法的返回值 int 是什么?
每次读取的有效字节个数
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; //String类的构造方法 //String(byte[] bytes):把字节数组转换为字符串 //String(byte[] bytes, int offset, int length) :把字节数组的一部分转换为字符串 //offset:数组的开始索引; length:转换的字节个数 public class MyInputStream02 { public static void main(String[] args) throws IOException { //创建FileInputStream对象, 构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("sxmz\\src\\com\\sxmz\\IoClass\\class01\\b.txt"); //使用FileInputStream对象中的方法read读取文件 //int read(byte[] b)从输入流中读取一定数量的文字,并将其存储在缓冲区 b 中。 /*byte[] bytes = new byte[2]; int len = fis.read(bytes); System.out.print(len+" ");//2 System.out.print(Arrays.toString(bytes)+" "); //65,66 System.out.println(new String(bytes)); //AB len = fis.read(bytes); System.out.print(len+" ");//2 System.out.print(Arrays.toString(bytes)+" "); //65,66 System.out.println(new String(bytes)); //CD len = fis.read(bytes); System.out.print(len+" ");//1 System.out.print(Arrays.toString(bytes)+" "); //65,66 System.out.println(new String(bytes)); //ED // 由于有效字节个数为1,将0位置覆盖,而1位置没有覆盖所以还是之前数组 len = fis.read(bytes); System.out.print(len+" ");//-1 System.out.print(Arrays.toString(bytes)+" "); //65,66 System.out.println(new String(bytes)); //ED // 没有有效字节显示-1(结束标记为jVM设定值),由于没有覆盖,所以打印之前数组*/ //循环简化 byte[] bytes = new byte[1024]; int len = 0; while (( len = fis.read(bytes))!=-1){ //String(byte[] bytes, int offset, int length) :把字节数组的一部分转换为字符串 System.out.println(new String(bytes,0,len)); } fis.close(); } }
2.3练习:图片复制
文件复制:一读一写
一切的文本都是由字节组成
明确
数据源:c:\
数据的目的地:D:\
文件复制的步骤
- 创建一个字节输入流对象,构造方法中绑定要读取的数据源
- 创建一个字节输出流对象,构造方法中绑定要写入的目的地
- 使用字节输入流中的方法
read
读取文件 - 使用字节输出流中的
write
,把读取到的字节写入到目的地文件中 - 释放资源
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyCopyFile {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();//当前时间
//1.
FileInputStream fis = new FileInputStream("c:\\1.jpg");
//2.
FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
//3.
/*int len = 0;
while ((len = fis.read())!=-1){
//4.
fos.write(len);
}
速度太慢,每次字节都要读取、打印
*/
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1){
fos.write(bytes,0,len);
}
fos.close();
fis.close();
long e = System.currentTimeMillis();//当前时间
//总用时时间
System.out.println("复制文件共耗时:"+(e-s)+"毫秒")
}
}
注意
释放资源,先关写,后关读。因为写完肯定读完,但读完不一定写完
三、字符流
中文字符时,可能会显示不完整的字符。因为一个中文同时使用多个字节(GBK使用2个字节,UTF-8使用3个字节),而一次只能输出一个字节。
import java.io.FileInputStream;
import java.io.IOException;
public class MyStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\javaclass\\sxmz\\src\\com\\sxmz\\IoClass\\class01\\c.txt");
int len = 0;
while ((len = fis.read())!=-1){
System.out.println(len); //输出6个字节
System.out.println((char)len); //编程char类型就会乱码,因为一次读取了3/1个中文
}
fis.close();
}
}
3.1字符输入流【Reader】
java.io.Reader
所有字符输入流的超类
read()
读一个字符
read(char[] cbuf)
将字符读入数组
【FileReader】文件字符输入流
java.io.FileReader extends InputStreamReader(转换流) extends Reader
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法
FileReader(String fileName)
FileReader(File file)
参数:读取文件的数据源
String fileName:文件的路径
File file:一个文件
作用:
- 创建一个
FileReader
对象 - 会把
FileReader
对象指向要读取的文件
使用步骤
- 创建
FileReader
对象,构造方法中绑定要读取的数据源 - 使用
FileReader
对象中的方法read
读取文件 - 释放资源
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class MyReader02 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("sxmz\\src\\com\\sxmz\\IoClass\\class01\\c.txt");
/*//int read() 读取单字符并返回
int len = 0;
while ((len = fr.read())!=-1){
System.out.print(len+":");
System.out.print((char) len+"; ");
}*/
//int read(char[] cbuf) 一次读取多个字符,将字符读入数组中。
char[] cs = new char[1024];
int len = 0; //记录的每次读取的有效字符个数
while ((len = fr.read(cs))!= -1){
/*
String类的构造方法
String(char[] value) 把字符数组转换为字符串
String(char[] value, int offset, int count) 把字符数组的一部分转换为字符串;
offset 数组的开始索引 count 转换个个数
*/
System.out.println(new String(cs,0,len));
}
fr.close();
}
}
3.2字节输出流【Writer】
java.io.Writer
: 字符输出流,所有字符输出流的最顶层父类,是个抽象类。
void write(int c)
写一个字符
void write(char[] cbuf)
写入一个字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(String str)
写一个字符串
void write(String str, int off, int len)
写一个字符串的一部分。
abstract void flush()
刷新流。
abstract void close()
关闭流,先刷新。
【FileWriter】文件字符输出流
java.io.FileWriter extends OutputStreamWriter extends Writer
FileWriter
:文件字符输出流
作用:把内存中字符数据写入到文件中
构造方法
FileWriter(File file)
给一个File对象构造一个FileWriter对象。
FileWriter(String fileName)
构造一个给定文件名的FileWriter对象。
参数:写入参数的目的地
String fileName
:文件的路径
File file
:一个文件
作用:
- 会创建一个
FileWriter
对象 - 会根据构造方法中传递的文件/文件的路径,创建文件
- 会把
FileWriter
对象指向创建好的文件
使用步骤
- 创建
FileWriter
对象,构造方法中绑定要写入数据的目的地 - 使用
FileWriter
中的方法write
,把数据写入到内存缓冲区中(字符转换为字节的过程) - 使用
FileWriter
中方法flush
,把内存缓冲区中的数据,刷新到文件中 - 释放资源(会先把内存缓存区内的数据刷新到文件中)
import java.io.FileWriter;
import java.io.IOException;
public class MyWriter {
public static void main(String[] args) throws IOException {
//创建`FileWriter`对象,构造方法中绑定要写入数据的目的地
FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\d.txt");
//使用`FileWriter`中的方法`write`,把数据写入到**内存缓冲区**中(字符转换为字节的过程)
//void write(int c)
fw.write(97);
/*//使用`FileWriter`中方法`flush`,把内存缓冲区中的数据,刷新到文件中
fw.flush();*/
//释放资源(会先把内存缓存区内的数据刷新到文件中)
fw.close();
/*如果没有使用 flush 或 close 刷新,当程序结束时,
存在内存缓冲区内的字符就会自动清除,无法保存在指定文件中*/
}
}
关闭和刷新的却别
flush
:刷新缓冲区,流对象可以继续使用
close
:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用。
import java.io.FileWriter;
import java.io.IOException;
public class MyCloseAndFlush {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\e.txt");
fw.write(97);
fw.flush();
fw.write(98);
//flush刷新后还可以使用write,但需要再次flush刷新或close
fw.flush();
fw.write(99);
fw.close();
//fw.write(99); 报错:IOException: Stream closed
//close 方法之后流已经关闭,已经从内测中消失,流不能再被使用。
}
}
其他方法
void write(char[] cbuf)
写入一个字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(String str)
写一个字符串
void write(String str, int off, int len)
写一个字符串的一部分。
import java.io.FileWriter;
import java.io.IOException;
public class MyWriter02 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\f.txt");
//`void write(char[] cbuf)`写入一个字符数组。
char[] cs = {
'a','b','c','d','e'};
fw.write(cs);
//`abstract void write(char[] cbuf, int off, int len)`写入字符数组的一部分。
fw.write(cs,1,3);
//`void write(String str)`写一个字符串
fw.write("传智播客");
//`void write(String str, int off, int len)`写一个字符串的一部分。
fw.write("黑马程序员",2,3);
fw.close();
}
}
续写和换行
FileWriter(String fileName, boolean append)
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。
FileWriter(File file, boolean append)
给一个File对象构造一个FileWriter对象。
参数:
String fileName,File file
:写入数据的目的地
boolean append
:续写开关,true
:不会创建新的文件覆盖源文件,可以续写;false
:创建新的文件覆盖源文件
换行:换行符号
windows:\r\n
Linux:/n
mac:/r
import java.io.FileWriter;
import java.io.IOException;
public class MyWriter03 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\g.txt",true);
for (int i = 0; i <10 ; i++) {
fw.write("HelloWorld,"+i+"\r\n");
}
fw.close();
}
}
四、IO异常的处理
JDK7之前[try…catch…finally]
之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理。
在 jdk1.7 之前使用try...catch...finally
代码块,处理流中异常。
格式:
try{
可能会产生异常的代码
}catch(异常类变量 变量名){
异常的处理逻辑
}finally{
一定会指定的代码
资源释放
}
练习
import java.io.FileWriter;
import java.io.IOException;
public class MyTryCatch {
public static void main(String[] args) {
//将fw的作用域提高,让finally可以使用
//变量在定义的时候,可以没有值,但是使用的时候必须有值
//如果不赋值,当try执行失败,fw没有值,fw.close会报错
FileWriter fw = null;
try{
//可能会产生异常的代码
fw = new FileWriter("w:sxmz\\src\\com\\sxmz\\IoClass\\class01\\g.txt",true);
for (int i = 0; i <10 ; i++) {
fw.write("HelloWorld,"+i+"\r\n");
}
}catch (IOException e){
//异常的处理逻辑
System.out.println(e);
}finally {
//一定会执行的代码
if (fw!=null){
try {
fw.close(); //close方法本身是会有抛出异常对象,所有需要再次进行try...catch要么throws
} catch (IOException e) {
e.printStackTrace();
}
}
/*当路径不正取时,除了已设定的正常抛出,还出现NullPointerException(空指针异常);
是由于创建对象失败,fw默认值为null,而null是不能够调用方法的,所以会抛出NullPointerException(空指针异常);
所以需要增加一个判断if,当fw不是null时再把资源释放
*/
}
}
}
JDK7的新特性
在try
的后边可以增加一个(),在括号中可以定义流对象,这个流对象的作用域就在try
中有效
try
中的代码执行完毕,会自动把流对象释放,不用写finally
格式:
try(定义流对象;定义流对象...){
可能会产生异常的代码
}catch(异常类变量 变量名){
异常的处理逻辑
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyJDK7 {
public static void main(String[] args) {
try( //定义流对象
FileInputStream fis = new FileInputStream("c:\\1.jpg");
FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
) {
//可能会产生异常的代码
int len = 0;
while ((len = fis.read())!=-1){
fos.write(len);
}
}catch (IOException e){
//异常的处理逻辑
System.out.println(e);
}
//由于流对象只存在于`try`中,所以当代码执行完毕时就对自动释放
}
}
JDK9的新特性
try
的前边可以定义流对象,在try
后边()中可以直接引入流对象的名称(变量名),在try
代码执行完毕后,流对象也可以释放掉,不用写finally
格式:
A a = new A();
B b = new B();
try(a,b){
可能会产生异常的代码
}catch(异常类变量 变量名){
异常的处理逻辑
}
练习
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyJDK9 {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fis = new FileInputStream("c:\\2.jpg");
FileOutputStream fos = new FileOutputStream("d:\\2.jpg");
try(fis;fos) {
//**报错**
int len = 0;
while ((len = fis.read())!=-1){
fos.write(len);
}
}catch (IOException e){
System.out.println(e);
}
}
}
JDK9比较麻烦,即要try...catch
又要throws
try(fis;fos)
不清楚什么情况报错,提示需要<标识符>;视频中并没有报错
五、属性集
【Propertise】集合
- java.lang.Object
-
- java.util.Dictionary<K,V>
-
- java.util.Hashtable<Object,Object>
-
- java.util.Properties
java.util.Properties集合 extends Hashtable<k,v> implements Map<k,v>
Propertise 类表示了一个持久的属性集合。Propertise
可保存在流中或从流中加载。
Propertise集合是一个唯一和IO流相结合的集合
- 可以使用Propertise集合中的方法
store
,把集合中的临时数据,持久化写入到硬盘中存储 - 可以使用Propertise集合中的方法
load
,把硬盘中保存的文件(键值对),读取到集合中使用
属性列表中每个键及其对应值都是一个字符串
Propertise集合是一个双列集合,key
和value
默认都是字符串
Propertise集合有一些操作字符串的特有方法
Object setProperty(String key, String value)
调用Hashtable
的方法put
。
String getProperty(String key)
通过key
找到value
值,此方法相当于Map集合中的get(key)
方法
Set< String > stringPropertyNames()
返回此属性列表中的一组键,其中键及其对应的值为字符串,
此方法相当于Map集合中的keySet
方法
import java.util.Properties;
import java.util.Set;
public class MyPropertise {
public static void main(String[] args) {
show01();
}
/*
使用Propertise集合存储数据,遍历取出Propertise集合中的数据
Propertise集合是一个双列集合,key和value默认都是字符串
Propertise集合有一些操作字符串的特有方法
Object setProperty(String key, String value) 调用 Hashtable的方法 put 。
String getProperty(String key) 通过key找到value值,此方法相当于Map集合中的get(key)方法
Set<String> stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,
此方法相当于Map集合中的keySet方法
*/
private static void show01() {
//创建一个Propertise集合对象
Properties prop = new Properties();
//使用setProperty往集合中添加数据
prop.setProperty("颖","168");
prop.setProperty("巴","165");
prop.setProperty("扎","160");
//prop.put(1,true); 可以使用任何类型
//使用stringPropertyNames()把Property集合中的键取出,存储到一个Set集合中
Set<String> set = prop.stringPropertyNames();
for (String key : set){
String value = prop.getProperty(key);
System.out.println(key+"="+value);
}
String key = "颖";
String value = prop.getProperty(key);
System.out.println(key+"="+value);
}
}
store方法
可以使用Propertise集合中的方法store
,把集合中的临时数据,持久化写入到硬盘存储
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
参数:
OutputStream out
:字节输出流,不能写入中文
Writer writer
:字符输出流,可以写入中文
String comments
:注释,用来解释说明保存的文件是做什么用的
不能使用中文,会产生乱码,由于默认是Unicode编码,而电脑系统常使用UTF-8
一般使用“ ”空字符串
使用步骤:
- 创建Propertis集合对象,添加数据
- 创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
- 使用Propertis集合中的方法
store
,把集合中的临时数据,持久化写入到硬盘中存储 - 释放资源
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class MyPropertise {
public static void main(String[] args) throws IOException {
show02();
}
/*
可以使用Propertise集合中的方法store,把集合中的临时数据,持久化写入到硬盘存储
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
参数:
OutputStream out:字节输出流,不能写入中文
Writer writer:字符输出流,可以写入中文
String comments:注释,用来解释说明保存的文件是做什么用的
不能使用中文,会产生乱码,由于默认是Unicode编码,而电脑系统常使用UTF-8
一般使用“ ”空字符串
*/
private static void show02() throws IOException {
//创建Propertis集合对象,添加数据
Properties prop = new Properties();
prop.setProperty("颖","168");
prop.setProperty("巴","165");
prop.setProperty("扎","160");
/*//创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
FileWriter fw = new FileWriter("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop.txt");
//使用Propertis集合中的方法`store`,把集合中的临时数据,持久化写入到硬盘中存储
prop.store(fw," ");
//释放资源
fw.close();*/
prop.store(new FileOutputStream("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop2.txt")," ");
//如果使用字节流中文会出现乱码
//同时由于此IO是匿名对象,当使用完会自动释放,所以不需要close。
}
load方法
可以使用Propertise集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(InputStream inStream)
void load(Reader reader)
参数:
InputStream inStream
:字节输入流,不能读取含有中文的键值对
Reader reader
:字符输入流,能读取含有中文的键值对
使用步骤:
- 创建Propertise集合对象
- 使用Propertise集合对象中的方法load读取保存键值对的文件
- 遍历Propertise集合
注意:
- 存储键值对的文件中,键与值默认的连接符号可以使用
=
,空格(其他符号) - 存储键值对的文件中,可以使用
#
进行注释,被注释的键值对不会再被读取 - 存储键值对的文件中,键与值默认都是字符串,不用再加引号
import java.io.*;
import java.util.Properties;
import java.util.Set;
public class MyPropertise {
public static void main(String[] args) throws IOException {
show03();
}
/*
可以使用Propertise集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(InputStream inStream)
void load(Reader reader)
*/
private static void show03() throws IOException {
Properties prop = new Properties();
prop.load(new FileReader("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop.txt"));
Set<String> set = prop.stringPropertyNames();
for (String key : set){
//扎=160
//巴=165
//颖=168
String value = prop.getProperty(key);
System.out.println(key+"="+value);
/*
输入:#扎=160(巴-165) (颖 168)
读取:不读取 (巴-165=)(颖=168)
存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
*/
/*prop.load(new FileInputStream("sxmz\\src\\com\\sxmz\\IoClass\\class01\\prop.txt"));
使用字节流会产生乱码
*/
}
}