day11_面对对象(字节流、字符流)
一.字节流
4.字节输入流InputStream
字节输入流的顶层父类:InputStream(抽象类)
共性方法:
public int read(); 一次读取一个字节
public int read(byte[] bs); 一次读取一个字节数组, 返回值表示实际读取的长度
public void close(); 释放资源
5.FileInputStream类的使用(文件的字节输入流)
a.构造方法
public FileInputStream(String pathname);
public FileInputStream(File file);
public class FileInputStreamDemo01 {
public static void main(String[] args) throws FileNotFoundException {
//1.创建一个FileInputStream对象
FileInputStream fis = new FileInputStream("1.txt");
// FileInputStream fis = new FileInputStream(new File("1.txt"));
/**
* 以上构造干了三件事!!!
* a.创建对象fis
* b.判断文件是否存在
* 如果存在,不清空
* 如果不存在,会抛出FileNotFoundException文件找不到异常
* c.让fis对象和1.txt绑定
*/
}
}
b.读取一个字节**********************
public class FileInputStreamDemo02 {
public static void main(String[] args) throws IOException {
//1.创建一个FileInputStream对象
FileInputStream fis = new FileInputStream("1.txt");
//2.读数据
//一次读取单个字节
// int b = fis.read();
// System.out.println((char) b);
//一次读取一个字节的标准循环代码
int b = 0;//用来保存读取到字节
/**
* (b = fis.read()) != -1
* 以上代码干了三件事!!!
* a.先读 fis.read()
* b.赋值 b = 读取到的字节
* c.判断 b != -1
*/
while ((b = fis.read()) != -1) {
System.out.println((char)b);
}
//3.释放资源
fis.close();
}
}
c.读取一个字节数组*********************
public class FileInputStreamDemo03 {
public static void main(String[] args) throws IOException {
//1.创建一个FileInputStream对象
FileInputStream fis = new FileInputStream("1.txt");
//2.读数据
//一次读取一个字节数组的标准循环代码
int len = 0;//保存实际读取的字节个数
byte[] bs = new byte[4];//保存字节的数组
/**
* (len = fis.read(bs)) != -1
* 以上代码三个三件事!!
* a.先读 fis.read(bs)
* b.赋值 len = 实际读取的个数
* c.判断 len != -1
*/
while ((len = fis.read(bs)) != -1) {
System.out.print(new String(bs,0,len));
}
//3.释放资源
fis.close();
}
}
6.字节流练习:复制图片**********************
a.复制文件的过程(画图)
b.代码实现(代码演示)
public class CopyFileDemo {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
copy02();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "毫秒");
}
//一次复制一个字节
//耗时:37709毫秒
public static void copy01() throws Exception {
//1.创建文件的输入流
FileInputStream fis = new FileInputStream("G:\\upload\\1.png");
//2.创建文件的输出流
FileOutputStream fos = new FileOutputStream("copy.png");
//3.复制
//一次读一个字节 写一个字节
int b = 0;//保存读取到的字节
while ((b = fis.read()) != -1) {
fos.write(b);
}
//4.释放资源
fos.close();
fis.close();
}
//一次复制一个字节数组
//耗时:20毫秒
public static void copy02() throws Exception {
//1.创建文件的输入流
FileInputStream fis = new FileInputStream("G:\\upload\\1.png");
//2.创建文件的输出流
FileOutputStream fos = new FileOutputStream("copy.png");
//3.复制
//一次读取一个字节数组 写出一个字节数组
int len = 0;
byte[] bs = new byte[1024 * 8];
while ((len = fis.read(bs)) != -1) {
fos.write(bs, 0, len);
}
//4.释放资源
fos.close();
fis.close();
}
}
二.字符流
1.为什么要用字符流
因为中文或者其他文字,一个中文是由2-3字节组成的
如果我们使用字节流,很可能出现一种情况,读取文字时只读取一部分字节
public class WhyDemo {
public static void main(String[] args) throws IOException {
// 为什么要用字符流
// 因为中文或者其他文字,一个中文是由2-3字节组成的
// 如果我们使用字节流,很可能出现一种情况,读取中文时只读取一部分字节
//文件中的内容是:a中b国c万d岁e
FileInputStream fis = new FileInputStream("1.txt");
//读取
int b = fis.read();
System.out.println((char) b); //a
b = fis.read();
System.out.println((char) b);//中的一半 乱码
b = fis.read();
System.out.println((char) b);//中的另一半 乱码
b = fis.read();
System.out.println((char) b);//b
fis.close();
}
}
2.字符输入流
字符输入流顶层父类:Reader(抽象类)
共性方法:
public int read(); 一次读取一个字符
public int read(char[] chs); 一次读取一个字符数组,返回值表示实际读取的个数
public void clsoe(); 释放资源
3.FileReader类的使用
文件的字符输入流
a.构造方法
public FileReader(String pathname);
public FileReader(File file);
public class FileReaderDemo01 {
public static void main(String[] args) throws Exception {
//1.创建FileReader
FileReader fr = new FileReader("1.txt");
// FileReader fr = new FileReader(new File("1.txt"));
/**
* 以上构造干了三件事i!!
* a.创建对象fr
* b.判断文件是否存在
* 如果存在,不清空
* 如果不存在,直接抛出FileNotFoundException
* c.绑定fr和1.txt文件
*/
}
}
b.读取一个字符**********************
public class FileReaderDemo02 {
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.print((char) ch);
}
//3.释放资源
fr.close();
}
}
c.读取一个字符数组****************
public class FileReaderDemo03 {
public static void main(String[] args) throws Exception {
//1.创建FileReader
FileReader fr = new FileReader("1.txt");
//2.读字符数据
//一次读取一个字符数组的标准循环代码
int len = 0;//用来保存实际读取的字符个数
char[] chs = new char[4];//保存读取的字符数组
/**
* (len = fr.read(chs)) != -1
* a.先读 fr.read(chs)
* b.赋值 len = 实际读取的字符个数
* c.判断 len != -1
*/
while ((len = fr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
//3.释放资源
fr.close();
}
}
4.字符输出流
字符输出流顶层父类:Writer(抽象类)
共性方法:
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 void flush(); 刷新缓冲区(对于字符输出流来说是有用的!!!将缓冲区里的内容写进文件再进行刷新但流不关 闭)
public void close(); 释放资源
5.FileWriter类的使用
文件的字符输出流
a.构造方法
public FileWriter(String name);
public FileWriter(File file);
public class FileWriterDemo01 {
public static void main(String[] args) throws IOException {
//1.创建FileWriter对象
FileWriter fw = new FileWriter("2.txt");
// FileWriter fw = new FileWriter(new File(""));
/**
* 以上构造干了三件事
* 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 FileWriterDemo02 {
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 = {'中', '国', '我', '爱', '你'};
fw.write(chs);
fw.write(chs,2,3);
//c.写一个字符串(一部分)
fw.write("Java我爱你");
fw.write("Java我爱你", 3, 3);
//3.释放资源
fw.close();
}
}
c.关闭和刷新的区别
flush():将缓冲区数据刷到目标文件中,flush之后流依然可以继续使用
close():先flush,后释放资源,close之后流已经关闭不能再继续使用
public class FileWriterDemo03 {
public static void main(String[] args) throws IOException {
//1.创建FileWriter对象
FileWriter fw = new FileWriter("2.txt");
//2.flush方法,刷新缓冲区
fw.write("phpphp");
fw.flush();//刷新缓冲区
fw.write("javajava"); //flush之后流没有关闭,可以继续使用
fw.flush(); //刷新缓冲区
//3.释放资源
fw.close();
//fw.write("java"); //close之后流已经关闭不能继续使用
}
}
d.续写和换行
i.每次创建FileWriter对象文件都会清空,如何续写呢?
要使用下面构造即可
public FileWriter(String pathname, boolean append);
public FileWriter(File file, boolean append);
ii.如何换行
只要向文件中写一个换行符即可
windows --> "\r\n"
Linux --> "\n"
Mac --> "\r" (Max OS X之后用"\n")
public class FileWriterDemo04 {
public static void main(String[] args) throws IOException {
//1.创建FileWriter对象
FileWriter fw = new FileWriter("2.txt");
//2.换行
for (int i = 0; i < 10; i++) {
fw.write("php\r\n");
// fw.write("\r\n");
}
//3.释放资源
fw.close();
}
}
三.IO流的异常处理
1.JDK7之前的标准IO处理
/**
* JDK1.7引入新的IO流异常处理机制
* try-with-resource
*/
public static void method02() {
try (FileReader fr = new FileReader("2.txt")) {
int read = fr.read();
} catch (IOException e) {
e.printStackTrace();
}
}
2.JDK7引入的try-with-resource处理
/**
* JDK1.7之前的标准IO流异常处理代码
*/
public static void method01(){
//1.创建FileReader
FileReader fr = null;
try {
fr = new FileReader("2.txt");
int read = fr.read();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四.Properties类****************
1.Properties类的介绍
Prperties类表示一个持久的属性集
属性集:本质上就是Map集合,Properties已经确定键和值的具体类型
持久的:Properties可以有方法直接把数据保存到硬盘的某个文件中
2.构造方法
public Properties(); 创建一个空的属性集
3.基本保存数据的方法
public static void main(String[] args) {
//1.创建一个Properties对象
Properties ps = new Properties();
System.out.println(ps);
//2.添加
ps.setProperty("username","root");//相当于Map的put方法
ps.setProperty("password","1234");//相当于Map的put方法
System.out.println(ps);
System.out.println("===============");
//3.以键找值
String username = ps.getProperty("username");//相当于Map的get方法
System.out.println(username);
String password = ps.getProperty("password");//相当于Map的get方法
System.out.println(password);
System.out.println("===============");
//4.获取所有的键的集合
Set<String> propertyNames = ps.stringPropertyNames(); //相当于Map的keySet
System.out.println(propertyNames);
}
4.持久化的方法***********************
public void store(OutputStream out/Writer out, String 注释内容); 保存数据
public class PropertiesDemo02 {
public static void main(String[] args) throws Exception {
//1.创建一个Properties对象
Properties ps = new Properties();
//2.添加
ps.setProperty("username", "root");//相当于Map的put方法
ps.setProperty("password", "1234");//相当于Map的put方法
//3.要把ps中的数据保存到mysql.txt
ps.store(new FileWriter("mysql.properties"), null);
}
}
注意:如果使用Properties保存数据到文件中,该文件中的数据加载到当前Properties对象中
public class PropertiesDemo03 {
public static void main(String[] args) throws Exception {
//1.创建一个Properties对象
Properties ps = new Properties();
System.out.println(ps);
//2.加载
ps.load(new FileInputStream("mysql.properties"));
System.out.println(ps);
}
}
总结:
-[] 能够使用字节输入流读取数据到程序
-[] 能够理解读取数据ready(byte [])方法的原理
-[] 能够使用字节流完成文件的复制
-[] 能够使用FileWriter写数据到文件
-[] 能够说出FileWriter中关闭和刷新方法的区别
-[] 能够使用FileWriter写数据的5个方法
-[] 能够使用FileWriter写数据实现换行和追加写
-[] 能够使用FileReader读数据
-[] 能够使用FileReader读数据 一次一个字符数组
-[] 能够使用Properties的load方法加载文件中配置信息