day16【字节流、字符流、Properties】
反馈和复习
1.File类(了解)
2.递归(了解)
3.字节流(重点)
FileOutputStream: 写文件
构造方法:
public FileOutputStream(String path/File file);
/**
* 构造方法干了三件事!!
a.创建对象
b.判断文件是否存在,如果存在清空文件内容,如果不存在创建文件
c.流对象和文件绑定
*/
成员方法:
public void close();释放资源
public void flush(); 刷新缓冲区(对于字节流来说,我们不会用它)
public void write(int b);
public void write(byte[] bs);
public void write(byte[] bs,int startIndex,int len);
FileInputStream: 读文件
构造方法:
public FileInputStream(String path/File file);
/**
* 构造方法干了三件事!!
a.创建对象
b.判断文件是否存在,如果存在不会清空,如果不存在直接报错!!
c.流对象和文件绑定
*/
成员方法:
public void close();释放资源
public int read();
public int read(byte[] bs);
今日内容
1.字符流(重点)
2.IO流异常处理(标准处理代码)(重点)
3.Properties属性集(重点)
4.ResourceBundle工具类(专门用于属性集保存之后的文件)(重点)
第一章 字符流
1.为什么要用字符流
首先字节流也是可以读取文本文件的!!!但是可能会出现一种状况,读取中文时只读取其中一般,因为中文不只由一个字节组成.
为了解决这个问题,引入了字符流,以字符作为单位来操作!!
2.字符输入流
顶层父类: Reader(抽象类)
共性方法:
public void close(); 释放资源
public int read(); 一次读一个字符
public int read(char[] chs); 一次读取一个字符数组,返回值表示实际读取的字符个数
3.FileReader类的使用
文件的字符输入流(从文件中读取字符数据)
-
a.构造方法
public FileReader(String path); public FileReader(File file); public class TestFileReader01 { public static void main(String[] args) throws Exception { //1.创建一个FileReader对象 FileReader fr = new FileReader("1.txt"); // FileReader fr = new FileReader(new File("1.txt")); /** * 以上构造干了三件事!! * a.创建对象fr * b.判断文件是否存在 * 如果存在,不清空!!! * 如果不存在,报错! * c.绑定fr和1.txt文件 */ } }
-
b.读取一个字符
public class TestFileReader02 { public static void main(String[] args) throws Exception { //1.创建一个FileReader对象 FileReader fr = new FileReader("1.txt"); //2.一次读一个字符 //int ch = fr.read(); //System.out.println((char) ch); //===========一次读取一个字符的标准循环代码=========== int ch = 0; //用来保存读取到的字符 /** * (ch = fr.read()) != -1 * 以上代码干了三件事!! * a.读取 fr.read(); * b.赋值 ch = 读到的字符 * c.判断 ch != -1 */ while ((ch = fr.read()) != -1) { System.out.println((char) ch); } //3.释放资源 fr.close(); } }
-
c.读取一个字符数组
public class TestFileReader03 { public static void main(String[] args) throws Exception { //1.创建一个FileReader对象 FileReader fr = new FileReader("1.txt"); //2.一次读一个字符数组 //char[] chs = new char[4]; //int len = fr.read(chs); //System.out.println("实际读取到"+len+"个字符"); //System.out.println(new String(chs,0,len)); char[] chs = new char[4]; //保存字符数据的数组 int len = 0;//保存实际读取的个数 /** * (len = fr.read(chs)) != -1 * 以上代码也是干了三件事!!! * a.读取 fr.read(chs); * b.赋值 len = 实际读取的个数 * c.判断 len != -1 */ while ((len = fr.read(chs)) != -1) { System.out.println(new String(chs,0,len)); } //3.释放资源 fr.close(); } }
4.字符输出流
顶层父类:Writer(抽象类)
共性方法:
public void close();//释放资源
public void flush();//对于字符流来说有用!!
public void write(int ch); //写一个字符
public void write(char[] chs); //写一个字符数组
public void write(char[] chs,int startIndex,int len); //写一个字符数组的一部分
public void write(String str);// 直接写一个字符串
public void write(String str,int startIndex,int len);// 直接写一个字符串的一部分
5.FileWriter类的使用
文件的字符输出流(向文件中写字符数据)
-
a.构造方法
public FileWriter(String path); public FileWriter(File file); public class TestFileWriter01 { public static void main(String[] args) throws IOException { //1.创建一个FileWriter对象 FileWriter fw = new FileWriter("2.txt"); // FileWriter fw = new FileWriter(new File("2.txt")); /** * 以上构造干了三件事 * a.创建对象fw * b.判断文件是否存在 * 如果存在,清空文件内容 * 如果不存在,会创建文件 * c.绑定fw和2.txt */ } }
-
b.写出字符数据的三组方法
public void write(int ch); //写一个字符 public void write(char[] chs); //写一个字符数组 public void write(char[] chs,int startIndex,int len); //写一个字符数组的一部分 public void write(String str);// 直接写一个字符串 public void write(String str,int startIndex,int len);// 直接写一个字符串的一部分 public class TestFileWriter02 { public static void main(String[] args) throws IOException { //1.创建一个FileWriter对象 FileWriter fw = new FileWriter("2.txt"); //2.写数据 //a.写一个字符 fw.write('a'); fw.write('中'); //b.写一个字符数组 char[] chs = {'中','国','j','a','v','a','!'}; fw.write(chs); //c.写一个字符数组的一部分 fw.write(chs,3,2); //d.直接写一个字符串 fw.write("中国万岁我爱你Java,你爱我吗?"); //e.直接写一个字符串的一部分 fw.write("中国万岁我爱你Java,你爱我吗?",0,4); //3.释放资源 fw.close(); } }
-
c.关闭和刷新的区别
flush(); 只会刷新缓冲区,不关闭流,流可以继续使用 close(); 不仅会刷新缓冲区,还会关闭流,流不能继续使用 public class TestFileWriter03 { public static void main(String[] args) throws IOException { //1.创建一个FileWriter对象 FileWriter fw = new FileWriter("3.txt"); //2.写数据 fw.write("php"); //3.刷新缓冲 fw.flush(); //再次写数据,OK的 fw.write("python"); fw.flush(); //4.释放资源 fw.close(); //再次写数据,报错,流已经关闭 fw.write("python"); fw.flush(); } }
-
d.续写和换行
如何续写: 很简单!!! 只要使用下面这个两个构造即可 public FileWriter(String path,boolean append);//append表示是否需要续写 public FileWriter(File file,boolean append);//append表示是否需要续写 public class TestFileWriter04 { public static void main(String[] args) throws IOException { //1.创建一个FileWriter对象,保证续写 FileWriter fw = new FileWriter("3.txt", true); //2.续写 fw.write("python"); //3.释放资源 fw.close(); } } 如何换行: 很简单!!! 向文件中写一个换行符即可 windows: \r\n(windows系统必须使用\r\n) Linux: \n MacOS: \r (MacOSX以及以后的系统,也是\n) public class TestFileWriter05 { public static void main(String[] args) throws IOException { //1.创建一个FileWriter对象 FileWriter fw = new FileWriter("4.txt"); //2.写数据 for (int i = 0; i < 10; i++) { fw.write("c++\r\n"); // fw.write("\r\n"); } //3.释放资源 fw.close(); } }
第二章 IO流的异常处理
1.JDK7之前的标准IO处理
//IO流异常的标准处理方式(JDK1.7以前)
public static void method01() {
//1.创建FileReader
FileReader fr = null;
try {
fr = new FileReader("1.txt");
//2.读
int ch = fr.read();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
//写释放资源的代码
//3.释放资源
try {
if (fr != null) {
fr.close();
}
} catch (IOException ie) {
ie.printStackTrace();
}
}
}
2.JDK7引入的IO处理
try-with-resource(和资源一起try)
格式:
try(创建资源的代码;创建资源的代码;创建资源的代码){
}catch(XxxException e){
}
//IO流异常的标准处理方式(JDK1.7)
public static void method02() {
try (FileReader fr = new FileReader("1.txt")) {
int ch = fr.read();
System.out.println((char) ch);
} catch (IOException e) {
e.printStackTrace();
}
}
第三章 Properties类
1.Propertie类的介绍
a.Properties就是一个双列集合(Properties extends HashTable extends Dictionary implments Map)
b.Properties的键和值已经确定为String了
c.通过System类的静态方法.getProperties()可以获取系统先关的一些键值对
public static void main(String[] args) {
//1.学过System类
// System.exit(0); //退出JVM
// long timeMillis = System.currentTimeMillis();//获取当前时间的毫秒值
Properties ps = System.getProperties();//获取系统相关的一些键值对
System.out.println(ps);//
}
2.构造方法
public Properties(); //创建一个空的Properties对象
public static void main(String[] args) {
//1.创建一个空的Properties对象
Properties ps = new Properties();
System.out.println(ps);
}
3.基本保存数据的方法
回忆一下Map接口中定义的方法:
增: put(键,值)
删: remove(键)
改: put(键,值)
查: get(键)
遍历的两个方法:
Set<键的类型> keys = map.keySet();
Set<Map.Entry<K,V>> entrys = map.entrySet();
Properties也具有以上方法,但是我们一般使用其特有方法
public Object setProperty(String key, String value);添加/修改键值对, 和put功能是一样的
public String getProperty(String key); 以键找值,和get功能是一样
public Set<String> stringPropertyNames();获取所有属性名的集合,和keySet功能是一样
public class PropertiesDemo02 {
public static void main(String[] args) {
//1.创建一个空的Properties对象
Properties ps = new Properties();
System.out.println(ps);
//2.添加属性(键值对)
ps.setProperty("xiaomi","6888");
ps.setProperty("huawei","8888");
ps.setProperty("vivo","2222");
System.out.println(ps);
//3.修改
ps.setProperty("vivo","3333");
System.out.println(ps);
//4.获取
System.out.println(ps.getProperty("huawei"));
//5.获取所有的属性名(键!)
Set<String> propertyNames = ps.stringPropertyNames();// 和 keySet
System.out.println(propertyNames);
}
}
4.与流相关的方法
Properties有两个和流相关的方法,一个叫保存,一个加加载
public void store(OutputStream out,String 说明内容); //保存Properties对象中的数据
public void store(Writer write,String 说明内容);//保存Properties对象中的数据
public void load(InputStream in);//把Properties文件内容加到当前对象
public void load(Reader r);//把Properties文件内容加到当前对象
public class PropertiesDemo03 {
public static void main(String[] args) throws Exception {
//1.创建一个空的Properties对象
Properties ps = new Properties();
//2.添加
ps.setProperty("username","root");
ps.setProperty("password","123321");
//3.保存,规范,文件名建议使用.properties作为后缀
ps.store(new FileOutputStream("5.properties"),"this is a test file");
//4.加载
ps.load(new FileInputStream("5.properties"));
System.out.println(ps);
}
}
注意: 一般我们不会使用Properties文件来保存中文数据
第四章 ResourceBundle工具类
1.ResourceBundle类的介绍
ResourceBundle实际上是一个抽象类,他的子类PropertyResourceBundle,可以读取以.properties为后缀的文件中的内容
2.ResourceBundle类对象的创建
public static ResourceBundle getBundle(String baseName); 用于绑定指定的.properties资源文件
注意:
a.xxx.properties文件必须放在类的根路径下(src文件夹下)
b.给定参数时,我们只需要给文件名的名字,不需要写文件的后缀
public class ResourceBundleDemo {
public static void main(String[] args) {
//1.创建一个ResourceBundle实现类的对象
ResourceBundle resourceBundle = ResourceBundle.getBundle("data");
System.out.println(resourceBundle);
}
}
3.ResourceBundle读取配置文件操作
public String getString(String key);
public class ResourceBundleDemo {
public static void main(String[] args) {
//1.创建一个ResourceBundle实现类的对象
ResourceBundle resourceBundle = ResourceBundle.getBundle("data");
System.out.println(resourceBundle);
//2.根据键获取值
String password = resourceBundle.getString("password");
String username = resourceBundle.getString("username");
//3.打印
System.out.println(username);
System.out.println(password);
}
}
同学们提出的问题
1.打印是地址值和内容的都有哪些
a.数组(除了char数组)都是打印地址
b.集合(Collection还是Map)都是打印内容
c.其他类的对象,打印出来是地址还是内容,就看是否重写toString
2.排序的工具类
对数组进行排序: Arrays.sort(数组,new Comparator<数组的元素类型>(){});
对List集合排序: Collections.sort(List集合,new Comparator<集合中元素类型>(){})
对Set集合排序: 并不是所有的Set都能排序的,TreeSet才可以排序
TreeSet怎么排序: TreeSet set = new TreeSet(new 比较器对象())
写排序算法: 冒泡排序,选择排序,插入排序,希尔排序,快速排序,堆排序,归并排序...
3.Stream流和IO流没有关系
4.字节流 可以操作任意文件(一切皆字节)
字符流 只能操作文本文件(如果使用字符流操作图片,视频,那么必须看到的结果是乱码!!!)
5.线程池(保存线程的集合)
ExecutorService service = Executors.newFixedThreadPool(4);
线程池对象,底层实际上有一个集合:
LinkedList<Thread> list = new LinkedList<Thread>();
for(int i = 0;i < 4;i++){
list.add(线程对象);
}
service.submit(任务对象);
// list.removeFirst(): list.addLast(线程)