前言:
Java中对数据进行持久化操作
转换流:
字节流与字符流之间转换的桥梁,可以用于改变字符的编码格式,编码统一,解决乱码问题
-
1 转换流OutputStreamWriter的写入(字节转字符)
OutputStreamWriter类的构造方法.png
public class OutputStreamWriterDemo throws IOException{
public static void main(String[] args){
writeGBK();//UTF-8编码写入方法相同
}
//使用GBK编码形式写入
public static void writeGBK() throws IOException{
//创建字节输出流
FileOutputStream fos = new FileOutputStream("c"\\gbk.txt");
//创建转换流对象,构造方法,绑定字节输出流,指定GBK编码格式
OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
//转换流写入数据
osw.write("你好");
osw.flush();
osw.close();
}
}
- 2 转换流InputStreamReader的读取(字符转字节)
public class InputStreamReaderDemo throws IOException{
public static void main(String[] args){
readGBK();//UTF-8编码读取方法相同
}
//使用GBK编码形式读取
public static void readGBK() throws IOException{
//创建字节输出流
FileInputStream fis = new FileInputStream("c"\\gbk.txt");
//创建转换流对象,构造方法,绑定字节输入流,指定GBK编码格式
InputStreamReader isr = new InputStreamReader(fis,"GBK");
int len = 0;
char[] ch = new char[1024];
while((len = isr.read(ch)) != -1){
System.out.println(new String(len));
}
isr.close();
}
}
- 3 转换流和其子类的区别
发现有如下继承关系:
OutputStreamWriter:
|--FileWriter:
InputStreamReader:
|--FileReader;
OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。
FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。
FileReader fr = new FileReader("a.txt");
这三句代码的功能是一样的,其中第三句最为便捷。
注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?
条件:
1、操作的是文件。2、使用默认编码。
总结:
字节--->字符 : 看不懂的--->看的懂的。 需要读。输入流。 InputStreamReader
字符--->字节 : 看的懂的--->看不懂的。 需要写。输出流。 OutputStreamWriter
缓冲流:
内部包含了缓冲区,提高了IO流读写效率
- 1 字节输出缓冲流BufferedOutputStream
public class BufferedOutputStreamDemo{
public static void main(String[] args) throws IOException{
//创建字节输出流,绑定文件
FileOutputStream fos = new FileOutputStream("c:\\test.txt");
//创建字节输出流缓冲流的对象,构造方法中,传递字节输出流(OutputStream的子类)
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写入字节和字节数组
bos.write("65");//显示"A"
bos.write("hello".getBytes());//显示"Ahello"
//关闭缓冲流
bos.close();
}
}
- 2 字节输入缓冲流BufferedInputStream
public class BufferedIntputStreamDemo{
public static void main(String[] args) throws IOException{
//创建字节输入流,绑定文件
FileInputStream fis = new FileInputStream("c:\\test.txt");
//创建字节输入流缓冲流的对象,构造方法中,传递字节输入流(InputStream的子类)
BufferedOutputStream bis = new BufferedOutputStream(fis);
//读取字节
byte[] bytes = new byte[1024];
int len = 0;
while((len = bis.read(bytes)) != -1){
System.out.println(new String(bytes,0,len));
}
//关闭缓冲流
bis.close();
}
}
- 3 四种使用字节流文件复制的效率比较:
public class Copy{
/*
* 按效率排名:缓冲流读字节数组>字节流读字节数组>缓冲流读单个字节>字节流读单个字节
*/
//使用字节流,读取单个字节
public static void copy_1(File address1,File address2){
FileInputStream fis = new FileInputStream(address1);
FileOutputStream fos = new FileOutputStream(address2);
int len = 0;
while((len = fis.read()) != -1){
fos.write(len);
}
fos.close();
fis.close();
}
//使用字节流,读取字节数组
public static void copy_2(File address1,File address2){
FileInputStream fis = new FileInputStream(address1);
FileOutputStream fos = new FileOutputStream(address2);
int len = 0;
byte[] bytes = new bytes[1024]
while((len = fis.read()) != -1){
fos.write(bytes,0,len);
}
fos.close();
fis.close();
}
//使用缓冲字节流,读取单个字节
public static void copy_3(File address1,File address2){
BufferedInputStream bis = new BufferedInputStream(address1);
BufferedOutputStream bos = new BufferedOutputStream(address2);
int len = 0;
while((len = fis.read()) != -1){
fos.write(len);
}
bos.close();
bis.close();
}
//使用缓冲字节流,读取字节数组
public static void copy_3(File address1,File address2){
BufferedInputStream bis = new BufferedInputStream(address1);
BufferedOutputStream bos = new BufferedOutputStream(address2);
int len = 0;
byte[] bytes = new bytes[1024]
while((len = fis.read()) != -1){
fos.write(bytes,0,len);
}
bos.close();
bis.close();
}
}
- 4 字符输出缓冲流BufferedWriter
public class WriterDemo{
public static void main(String[] args){
//创建字符输出流,封装文件
FileWriter fw = new FileWriter("c:\\test.txt");
//创建字符输出流缓冲流的对象,构造方法中,传递字符输出流(Writer的子类)
BufferedWriter bw = new BufferedWriter(fw);
//写入字符
bw.write(100);
bw.flush();
bw.newLine();//换行的作用,BufferedWriter特有的方法,同"\r\n"作用相同,但其具有跨平台型,不用考虑操作系统中的换行符
bw.write("你好");
bw.flush();//显示"d你好"
}
}
- 5 字符输入缓冲流BufferedReader
public class ReaderDemo{
public static void main(String[] args){
//创建字符输入流,封装文件
FileReader fr = new FileReader("c:\\test.txt");
//创建字符输入流缓冲流的对象,构造方法中,传递字符输入流(Reader的子类)
BufferedReader br = new BufferedReader(fr);
//读取字符
String line = null;
while((line = br.readLine() != null){
//readLine()是BufferedReader的特有方法,读取一行的字符,但不包括换行符
System.out.println(line);
}
br.close();
}
}
- 4 字符缓冲流复制文件
public class Copy{
public static void main(String[] args){
BufferedReader br = new BufferedReader("c:\\test.txt");
BufferedWriter bw = new BufferedWriter("d:\\test.txt");
String line = null;
while((br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
IO流的操作规律:
- 1 明确一:要操作的数据是数据源还是数据目的。(先根据需求明确要读,还是要写)
源:
InputStream
Reader
目的:
OutputStream
Writer
- 2 明确二:要操作的数据是字节还是文本呢?
源:
字节:InputStream
文本:Reader
目的:
字节:OutputStream
文本:Writer
- 3 明确三:明确数据所在的具体设备。(完全可以明确具体要使用哪个流对象)
源设备:
硬盘:文件 File开头
内存:数组,字符串
键盘:System.in
网络:Socket
目的设备:
硬盘:文件 File开头
内存:数组,字符串
屏幕:System.out
网络:Socket
- 4 明确四:是否需要额外功能呢?(已经明确到了具体的体系上)
额外功能:
转换吗?转换流。InputStreamReader OutputStreamWriter
高效吗?缓冲区对象。BufferedXXX
网友评论