属性集(Properties):
java.util.Properties类继承于HashTable用来表示一个持久的属性集,它使用键值结构存取数据,每个键及其对应的值都是一个字符串。
构造方法:
public Properties():创建一个空的属性集列表。
共性的API方法:
public Object setProperty(String key,String value):保存一对属性。
public String getProperty(String key):使用此属性列表中的指定的键搜索对应的值。
public Set<String> stringPropertyNames():获取所有键的名称并封装到Set集合中。
public static void demo(){
//创建属性集对象
final Properties properties = new Properties();
//添加键值对元素
properties.setProperty("java", "abc.txt");
properties.setProperty("size", "12000");
properties.setProperty("destination", "abc.txt");
properties.put("data", "2020-12-16");
System.out.println(properties);//{destination=abc.txt, size=12000, java=abc.txt}
//通过键来获取值
final String data = properties.getProperty("data");
System.out.println(data);
final String size = properties.getProperty("size");
System.out.println(size);
//遍历该属性集
final Set<String> set = properties.stringPropertyNames();
for(String key:set){
System.out.println(key+":"+properties.getProperty(key));
}
与流相关的方法
public void load(InputStream input ): 从字节输入流中读取键值对
参数中使用了字节输入流,通过流对象,可以关联到某个文件上,这样就可以加载文件中的数据文件中的数据的格式:key=value
如:date=小孙 size=12000 name=a'b'c
/*
可以使用properties集合中的load方法对输入流进行操作,把硬盘文件中的数据读取出来,保存到集合properties当中使用。
void load(InputStream input):从字节输入流中读取键值对
void load(Writer writer):从字符输入流中读取文件的键值对
参数:
InputStream input:字节输入流,不能读取含有中文的键值对
使用步骤:
1.创建Properties集合
2.使用Properties集合中的方法load读取保存在输入流中的数据
3.遍历Properties集合
注意:
1.在存储键值对的文件中,键与值默认的链接符号是“=”,可以使用空格(其他符号)
2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会被读取到.
3.存储键值对的文件中,键与值默认都是字符串,不用额外添加双引号
*/
public static void demo1() throws Exception {
//构建流对象
FileReader fileReader = new FileReader("day29--IO\\abc.txt");
//1.创建Properties集合
final Properties properties = new Properties();
// 2.使用Properties集合中的方法load读取保存在输入流中的数据
properties.load(fileReader);
// 3.遍历Properties集合
final Set<String> set = properties.stringPropertyNames();
for (String s : set) {
System.out.println(s+" = "+properties.getProperty(s));
}
}
public void store(OutoutStream out ,String comments):从集合当中的数据写入到字节输出流中。
可以使用properties集合当中的方法store把集合中的临时数据,持久化写入到硬盘文件中保存
/*
public void store(OutputStream out ,String comments):从集合当中的数据写入到字节输出流中。
void store(Writer writer,String comments);
参数:
OutputStream out 字节输出流,不能含有中文
writer writer:字符输出流,可以含有中文
String comments: 注释,解释说明保存的文件用来做什么的。
注意:注释不能使用中文,有中文会产生乱码,默认使用的是Unicode编码
一般使用""表示.
使用步骤:
1.创建Properties集合对象
2.创建字节输出流/字符输出流对象,构造方法中绑定需要写入的数据的目的地
3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘当中存储
4.释放资源
*/
public static void demo2() throws IOException {
//1.创建Properties集合对象
final Properties properties = new Properties();
properties.setProperty("四大名著1", "红楼梦");
properties.setProperty("四大名著2", "水浒传");
properties.setProperty("四大名著3", "西游记");
properties.setProperty("四大名著4", "三国演义");
//2.创建字节输出流/字符输出流对象,构造方法中绑定需要写入的数据的目的地
final FileWriter fileWriter = new FileWriter("day29--IO\\f.txt", true);
//3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘当中存储
properties.store(fileWriter, "si da ming zhu");
//4.释放资源
fileWriter.close();
}
缓冲流(Buffered)
缓冲流我们理解为对原来的使用数组方式进行数据传输的一种增强
按照类型分为:
字符缓冲流:BufferedReader,BufferedWriter
字节缓冲流: BufferedInputStream, BufferedOutputStream
缓冲流的基本模型:是在创建流对象的时候,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写数据,减少系统IO操作的次数,减少开销,提高程序的运行效率。
字节缓冲流:
构造方法:
public BufferedInputStream(InputStream input):创建一个新的缓冲输入流
public BufferedOutputStream(OutoutStream output):创建一个新的缓冲输出流
/*
BufferedOutputStream extends OutputStream
字节缓冲输出流
它里面继承从父类继承过来的api方法:close(),flush(),write(int b),write(byte[] bytes)...
构造方法:
public BufferedOutputStream(OutputStream output):创建一个新的缓冲输出流 ,以将具有指定缓冲区大小的数据写入字节输出流中
使用步骤:
1.创建一个FileOutputStream流对象,构造方法中绑定需要写入数据的目的地
2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream流对象
3.使用BufferedOutputStream对象中的write方法,把数据写入到内部缓冲区中
4.使用BufferedOutputStream对象中的flush方法,把内存缓冲区的数据刷新到新的目的地中。
5.释放资源
*/
public static void demo1() throws Exception {
// 1.创建一个FileOutputStream流对象,构造方法中绑定需要写入数据的目的地
final FileOutputStream fileOutputStream = new FileOutputStream("day29--IO\\one.txt");
//2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream流对象
final BufferedOutputStream bufferedReader = new BufferedOutputStream(fileOutputStream);
//3.使用BufferedOutputStream对象中的write方法,把数据写入到内部缓冲区中
bufferedReader.write("hallojava".getBytes());
//4.使用BufferedOutputStream对象中的flush方法,把内存缓冲区的数据刷新到新的目的地中。
bufferedReader.flush();
//5.释放资源
bufferedReader.close();
}
/*
BufferedInputStream extends InputStream
字节缓冲输入流
它里面继承从父类继承过来的api方法:close(),flush(),read(int b),read(byte[] bytes)...
构造方法:
public BufferedInputStream(InputStream input):创建一个新的缓冲输入流,将数据写入到指定的字节输出流中
使用步骤:
1.创建一个FileInputStream流对象,构造方法中绑定需要写入数据的数据源
2.创建BufferedInputStream对象,构造方法中传递FileInputStream流对象
3.使用BufferedInputStream对象中的read方法,把数据读取到内部中
4.释放资源
*/
public static void demo2() throws Exception {
//1.创建一个FileInputStream流对象,构造方法中绑定需要写入数据的数据源
final FileInputStream fileInputStream = new FileInputStream("day29--IO\\one.txt");
// 2.创建BufferedInputStream对象,构造方法中传递FileInputStream流对象
final BufferedInputStream bufferedReader = new BufferedInputStream(fileInputStream);
//3.使用BufferedInputStream对象中的read方法,把数据读取到内部中
//int read()
// int l = 0;
// while ((l = bufferedReader.read()) != -1) {
// System.out.println((char) l);
// }
byte[] bytes=new byte[2];
int l=0;
while ((l=bufferedReader.read(bytes))!=-1){
System.out.println(new String(bytes,0,l));
}
//4.释放资源
bufferedReader.close();
}
字符缓冲流:
构造方法:
public BufferedWriter(Writer out):创建一个新的字符缓冲输出流
public BufferedReader(Reader in):创建一个新的字符缓冲输入流
特有方法:
BufferedReader :public String readLine():读取整行的文本信息
BufferedWriter:public void newLine():写入一行的分隔符,
/*
使用步骤:
1.创建一个字符缓冲输出流的对象,构造方法中传递一个字符输出流
2.调用字符缓冲输出流对象的write,把数据写入到内存缓冲区中
3.调用字符缓冲输出流对象的flush方法,把内存缓冲区中的数据刷新到文件中。
4.释放资源
*/
static void demo() throws IOException {
// 1.创建一个字符缓冲输出流的对象,构造方法中传递一个字符输出流
final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("day29--IO\\two.txt"));
// 2.调用字符缓冲输出流对象的write,把数据写入到内存缓冲区中
bufferedWriter.write("今天看到了索大");
bufferedWriter.newLine();
bufferedWriter.write("少了两把刀");
bufferedWriter.newLine();
bufferedWriter.write("不知道跑哪了");
bufferedWriter.newLine();
// 3.调用字符缓冲输出流对象的flush方法,把内存缓冲区中的数据刷新到文件中。
bufferedWriter.flush();
// 4.释放资源
bufferedWriter.close();
}
/*
特有的方法:
String readLine():读取一个文本行,读取一整行的数据
返回值:
包含该行内容的字符串,不包含任何行的终止符号,如果已经读到文件末尾。返回null
使用步骤:
1.创建一个字符缓冲输入流对象,构造方法中传递一个字符输入流
2.使用字符缓冲输入流对象中的read/readLine(),读取文本信息
3.释放资源
*/
static void demo2() throws Exception {
//1.创建一个字符缓冲输入流对象,构造方法中传递一个字符输入流
final BufferedReader bufferedReader = new BufferedReader(new FileReader("day29--IO\\abc.txt"));
//2.使用字符缓冲输入流对象中的read/readLine(),读取文本信息
//final String string = bufferedReader.readLine();//读取单行
String s=null;
while ((s=bufferedReader.readLine())!=null){//读取多行
System.out.println(s);
}
//3.释放资源
bufferedReader.close();
}
文件复制练习:
/不使用缓冲流的操作
static void demo3()throws Exception {
long start=System.currentTimeMillis();
//1.构建字节输入流对象
final FileInputStream filterInputStream = new FileInputStream("C:\\Users\\1024\\Desktop\\1.gif");
//2.构建一个字节输出流对象
final FileOutputStream fileOutputStream = new FileOutputStream("day29--IO\\1.gif");
//3.调用字节输入流对象中的方法read(byte[] b)读取文件
byte[] bytes=new byte[1024];
int l=0;
while ((l=filterInputStream.read(bytes))!=-1){
//4.把读取到的字节内容写入到目的地文件中,调用write(byte[] b,int off,int len)
fileOutputStream.write(bytes, 0, l);
}
//5.释放资源
fileOutputStream.close();
filterInputStream.close();
long end=System.currentTimeMillis();
System.out.println(end-start+"ms");
}
//使用缓冲流完成文件的赋值
static void demo4()throws Exception {
long start=System.currentTimeMillis();
//1.构建字节缓冲输入流对象
final BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("C:\\Users\\1024\\Desktop\\1.gif"));
//2.构建一个字节缓冲输出流
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("day29--IO\\1.gif"));
//3.使用字节缓冲输入流对象的方法read(byte[] b),读取文件
byte[] bytes=new byte[1024];
int l=0;
while ((l=bufferedInputStream.read(bytes))!=-1){
//4.把读取到的字节内容再次写入到目的地文件中,调用write(byte[] b,int off,int len)
bufferedOutputStream.write(bytes,0,l);
}
//5.释放资源
bufferedOutputStream.close();
bufferedInputStream.close();
//获取结束的时间
long end=System.currentTimeMillis();
System.out.println((end-start)+" ms");
}
}
转换流【字节<->字符】
字符编码:
按照某种规则,将字符存储到计算机中,称为编码;反之,将存储在计算机的二进制数按照某种规则解析显示出来,成为解码。在进行编码和节码过程中,我们必须采用同一种规则,才能数据正常,否则,会导致乱码现象
字符编码:就是一套自然语言中的字符与二进制数之间的对应规则。
字符集:是一个系统可支持的所有字符的集合,包括各国文字,标点符号,图形编号,数字等,也叫编码表。
计算机中要准确的存储和识别各种文字的字符符号,需要经进行字符编码,一套字符至少有一套字符编码
常见的字符编码集有ASCII字符集,GBK字符集,Unicode字符集。
ASCII字符集:
ASCII是基于拉丁字母的一套编码系统。用于显示现代英语。
基本的ASCII字符表,使用7位(bit)表示一个字符,共128个字符。ASCII的扩展字符集使用8个(bit)表示一个字符。共256个字符
ISO-8859-1字符集:
拉丁码表:别名:--Lantin--,用于显示欧洲使用的语言,包括荷兰,丹麦,德语,意大利语,西班牙语等。
ISO-8859-1使用单字节编码,兼容ASCII编码
GBK字符集
GB2312:称为简体中文码表,里面大概含有7000多个简体汉字,此外数学符号,罗马希腊的子母。日本的假名都编进去了,连在ASCII里的原来就与数字,标点。字母都统统重新用的两个字节编写进去了。
GBK:最常用的中文编码,是在原来GB2312码表基础上进行扩展,使用双字节编码,共收录了21000多个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。
GB18030:最新的中文码表,共收录了7万多个汉字。 采用多字节编码,每个字可以由一个字节,两个字节或者4个字节,支持国内少数民族的文字,同时也支持繁体字以及日韩汉字等。
Unicode字符集:
Unicode编码系统为表达任意语言的任意字符设计的,是业界的一种标准,也成为统一编码,标准万国码表。
它最多使用四个字节的数字来表示每个字母,符号,或者文字,有三种常见的编码方案,UTF-8,UTF-16,UTF-32
UTF-8编码表,用来表示Unicode标准中的任意字符。编码规则:
1.128个US-ASCII字符,使用的是一个字节编码
2.拉丁字的字母,需要两个字节编码
3.大部分常见的汉字,使用的是三个字节编码
4.其他极少数的辅助字符,采用的四个字节编码。
编码引发的问题:
由于编码规则不一致,导致引发乱码现象。
那么如何读取GBK编码的文件呢?
InputStreamReader类
转换流java.io.InputStreamReader是Reader的子类,它是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符,它的字符集可以由名称指定,或者可以使用平台默认的字符集。
构造方法
public InputStreamReader(InputStream in):创建一个使用默认的字符集的字符流
public InputStreamReader(InputStream in,String charsetName):创建一个指定子符集的字符流.
/*
在UTF-8环境中去读取一个GBK编码的文件,会发生乱码现象。
*/
public static void demo() throws Exception {
//1.new
final FileReader fr = new FileReader("day29--IO\\one.txt");
int l = 0;
while ((l = fr.read()) != -1) {
System.out.println((char) l);//你哈呀
}
fr.close();
}
/*
InputStreamReader extends Reader
构造方法:
public InputStreamReader(InputStream in):创建一个使用默认的字符集的字符流
public InputStreamReader(InputStream in,String charsetName):创建一个指定子符集的字符流.
参数:
InputStream in:字节输入流,用于读取文件中保存的字节
String charsetName:指定编码表名称:UTF-8/utf-8,GBK/gbk,不区分大小写,不指定默认使用UTF-8
使用步骤:
1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码名称
2.使用InputStreamReader对象中的方法read读取文件中的信息
3.释放资源
*/
//读取一个使用GBK编码的文件
public static void demo1() throws Exception {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码名称
final InputStreamReader reader = new InputStreamReader(new FileInputStream
("day29--IO\\two.txt"), "GBK");
//2.使用InputStreamReader对象中的方法read读取文件中的信息
int l = 0;
while ((l = reader.read()) != -1) {
System.out.println((char) l);
}
// 3.释放资源
reader.close();
}
//读取一个使用utf-8编码的文件
public static void demo2() throws Exception {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码名称
final InputStreamReader reader = new InputStreamReader(new FileInputStream
("day29--IO\\two.txt"), "Utf-8");
//2.使用InputStreamReader对象中的方法read读取文件中的信息
int l = 0;
while ((l = reader.read()) != -1) {
System.out.println((char) l);
}
// 3.释放资源
reader.close();
}
OutputStreamReader类
转换流java.io.OutputStreamReader是Writer的子类,它是字符流到字节流的桥梁,使用指定的字符集将字符编码为字节,它的字符集可以手动指定,也可以使用平台默认的字符集
构造方法:
public OutputStreamReader(OutputStream in):创建一个使用默认的字符集的字符流
public OutputStreamReader(OutputStream in,String charsetName):创建一个指定子符集的字符流.