File类与IO流 3
03-缓中流的使用.
1.基础I0流的框架
抽象基类 | 4个节点流〔也称为文件流) | 4个缓冲流(处理流的一种) |
---|---|---|
InputStream | FileInputStream | BufferedInputStream |
outputStream | FileOutputStream | BufferedOutputStream |
Reader | FileReader | BufferedReader |
Writer | FileWriter | BufferedWriter |
2.缓冲流的作用:
提升文件读写的效率。
3.
4个缓冲流 | 使用的方法 |
---|---|
处理非文本文件的字节流: | |
BufferedInputStream | read(byte[ ] buffer) |
BufferedOutputStream | write(byte[] buffer ,0,len) /flush() |
处理文本文件的字符流: | |
BufferedReader | read(char[] cBuffer)/readLine() |
BufferedWriter | write(char[] cBuffer,0,len) /write(String) /flush() |
try之前
//需求:使用BufferedInputStream \ BufferedOutputStream复制一个图片
public void test2() {
//1.创建File类的对象 2个
File srcFile = new File("playgirl.jpg");
File destFile = new File("playgirl_copy1.jpg");
//2.创建相关的字节流、缓冲流
FileInputStream fileInputStream = new FileInputStream(srcFile);
FileOutputStream fileOutputStream = new FileOutputStream(destFile);
BufferedInputStream bis = new BufferedInputStream(fileInputStream);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
//3.数据的读入和写出的过程
byte[] buffer = new byte[1024];//1kb
int len;//记录每次读入到buffer中的字节的个数
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);//写入byte[] buffer的从0到len字符,左闭右开
}
//4.关闭流资源
//外层的流的关闭
//由于外层流的关闭也会自动的对内层的流进行关闭操作。所以可以省略内层流的关闭。
bos.close();
bis.close();
//内层的流的关闭
// fileOutputStream.close();
// fileInputStream.close();
}
readLine()
//使用BufferedReader将hello.txt中的内容显式在控制台上。
public void test4() throws IOException {
File file = new File("hello.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
///读取的过程
///方式1: read(char[ ] cBuffer)
// char[] cBuffer = new char[1024];
// int len;
// while ((len=br.read(cBuffer))!=-1){
// //方法1
//// for (int i = 0; i < len; i++) {
//// System.out.print(cBuffer[i]);
//// }
// //方法2
// String s = new String(cBuffer, 0, len);
// System.out.print(s);
// }
//方式2: readLine(),:每次读取一行文本中的数据。返回的字符串是不包含换行符的。
String data;
while ((data=br.readLine())!=null){
System.out.println(data);
}
br.close();
}
//使用BufferedReader和BufferedWriter实现文本文件的复制
//注意:开发中,还是需要使用try-catch-finally来处理流的异常。
public void test5() throws IOException {
//1.造文件,造流
File file = new File("hello.txt");
File file1 = new File("hello_copy1.txt");
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file1));
//2. 文件的读写操作
String data;
while ((data=bufferedReader.readLine())!=null){
bufferedWriter.write(data+"\n");
//System.out.println();这是控制台换行
bufferedWriter.newLine();//表示换行操作
bufferedWriter.flush();//刷新的方法。每当调用此方法时,就会主动的将内存中的数据写出到磁盘文件中。
}
//3. 关闭资源,会自动刷新
bufferedWriter.close();
bufferedReader.close();
}
04-转换流的使用.
字符编码:字符、字符串、字符数组--->字节、字节数组(从我们能看得懂的--->我们看不懂的)
字符解码:字节、字节数组--->字符、字符串、字符数组(从我们看不懂的--->我们能看得懂的
2.如果希望程序在读取文本文件时,不出现乱码,需要注意什么?
- 解码时使用的字符集必须与当初编码时使用的字符集得相同。
- 拓展:解码集必须要与编码集兼容。比如:文件编码使用的是GBK,解码时使用的是utf-8。如果文件中只有abc等英文字符,此情况下
也不会出现乱码。因为GBK和utf-8都向下兼容了ASCII (或ascii)
3.转换流:
作用:实现字节与字符之间的转换
API:
InputStreamReader:将一个输入型的字节流转换为输入型的字符流。outputStreamWriter:将一个输出型的字符流转换为输出型的字节流。
public void test1(){
//
File file1 = new File( pathname: "dbcp_utf-8.txt" );
//
FileInputStream fis = new EileInputStneam(file1);InputStreamReader isr = new InputStreamReader(fis);//此时使用的是IDEA默认的UTF-8的字符集
char[ ] cBuffer = new char[1024];
int len;
while((len = isr.nead(cBuffer)) != -1){
String str = new String(cBuffer,offset: 0,len) ;
system.out.print(str);
//关闭资源
isr.close(;
读取到的数据出现了乱码。
因为dbcp_utf-8.txt文件使用的是utf-8的字符集进行的编码,所以在读取此文件时使用的解码集必须也是utf-8,否则会出现乱码!
需求:将gbk格式的文件转换为utf-8格式的文件存储。
public void test4(){
/ /1.造文件
File file1 = new File( pathname: "dbcp_gbk.txt" );
File file2 = new File( pathname: "dbcp_gbk_to_utf8.txt" );
//2.造流
FileInputStream fis = new Eil.eInputs.tneam(file1);/参数2对应的是解码集,必须与dbcp_gbk.txt的编码集一致。
InputStreamReader isr = new InputStreamReader(fis,charsetName: "GBK");
File0utputStream fos = new File0utputStneam(file2);
outputStreamWriter o0s = new 0utputStreamWriter(fos,charsetName: "utf8");//参数2指明内存中的字符存储到文件中的字节过程中使用的编码集。
//3.读写过程
char[] cBuffer = new char[ 1024];int len;
while((len = isr.nead(cBuffer)) != -1){
oos. write(cBuffer, off:0, len) ;
}
system.out.println("操作完成");
//4.关闭资源
oos.close();
isr.close();
4.关于字符集的理解
4.1在存储的文件中的字符:
- ascii:主要用来存储a、b、c等英文字符和1、2、3、常用的标点符号。每个字符占用1个字节。
- iso-8859-1:了解,每个字符占用1个字节。向下兼容ascii。
- gbk:用来存储中文简体繁体、a、b、c等英文字符和1、2、3、常用的标点符号等字符。
中文字符使用2个字节存储的。向下兼容ascii,意味着英文字符、1、2、3、标点符号仍使用1个字节。 - utf-8:可以用来存储世界范围内主要的语言的所有的字符。使用1-4个不等的字节表示一个字符。
中文字符使用3个字节存储的。向下兼容ascii,意味着英文字符、1、2、3、标点符号仍使用1个字节。
4.2在内存中的字符:
一个字符(char)占用2个字节。在内存中使用的字符集称为Unicode字符集。
1.数据流及其作用(了解)
DataOutputStream:可以将内存中的基本数据类型的变量、String类型的变量写出到具体的文件中。DataInputStream:将文件中保存的数据还原为内存中的基本数据类型的变量、String类型的变量。
2.对象流及其作用
2.1 API:
0bjectInputsteam
0bject0utputStream
2.2作用:
可以读写基本数据类型的变量、引用数据类型的变量。
3.对象的序列化机制是什么
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
4.如下两个过程使用的流:
- 序列化过程:使用ObjectoutputStream流实现。将内存中的Java对象保存在文件中或通过网络传输出去
- 反序列化过程:使用0bjectInputSteam流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
//序列号过程
public void test1() throws IOException {
//
File file = new File("object.txt");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
//
oos.writeUTF("江山如此多娇,引无数英雄竞折腰");
oos.flush();
oos.writeObject("轻轻的我走了,正如我轻轻的来");
oos.flush();
oos.close();
}
//反序列化过程:使用ObjectInputSteam流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
public void test2() throws IOException, ClassNotFoundException {
//
File file = new File("object.txt");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
//2.读取文件中的对象(或反序列化的过程)
String s1 = ois.readUTF();
System.out.println(s1);
Object o = ois.readObject();
System.out.println(o);
//
ois.close();
}
5.自定义类要想实现序列化机制,需要满足:
- 自定义类需要实现接口:Serializable
- 要求自定义类声明一个全局常量:static final long serialVersionUID = 42234234L; 用来唯一的标识当前的类。
- 要求自定义类的各个属性也必须是可序列化的。
- 对于基本数据类型的属性:默认就是可以序列化的
- 对于引用数据类型的属性:要求实现Serializable接口
6.注意点:
- 如果不声明全局常量serialVersionUID,系统会自动声明生成一个针对于当前类的serialVersionUID。如果修改此类的话,会导致serialVersionUID变化,进而导致反序列化时,出现InvalidClassException异常。
- 类中的属性如果声明为transient或static,则不会实现序列化。
package demo01;
import java.io.Serializable;
public class Person implements Serializable {// Serializable:属于一个标识接口,没有重写方法
static final long serialVersionUID = 42234234534L;
transient String name;
static int age;
Account account;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, Account account) {
this.name = name;
this.age = age;
this.account = account;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", account=" + account +
'}';
}
}
class Account implements Serializable {
static final long serialVersionUID = 422388834534L;
double balance;
public Account() {
}
public Account(double balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Account{" +
"balance=" + balance +
'}';
}
}
======
//演示自定义类的对象的序列化和反序列化过程
// 序列化过程:
public void test3() throws IOException {
File file = new File("object1.dat");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
//2.写出数据即为序列化的过程
Person p1 = new Person("tom", 22);
oos.writeObject(p1);
oos.flush();
Person p2 = new Person("mmm", 11,new Account(2000));
oos.writeObject(p2);
oos.flush();
oos.close();
}
//反序列化过程:使用ObjectInputSteam流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
public void test4() throws IOException, ClassNotFoundException {
//
File file = new File("object1.dat");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
//2.读取文件中的对象(或反序列化的过程)
Person person= (Person) ois.readObject();
System.out.println(person);
Person person1= (Person) ois.readObject();
System.out.println(person1);
//
ois.close();
}
06-其它流的使用
1.标准输入、输出流
system.in:标准的输入流,默认从键盘输入
system.out:标准的输出流,默认从显示器输出(理解为控制台输出)
通过调用如下的方法,修改输入流和输出流的位置
setIn(InputStream is)
setOut(PrintStream ps)
public void test1() throws FileNotFoundException {
PrintStream ps = new PrintStream("info.txt" );
ps.println( "hello" );
ps.println(1);
ps.println(1.5);
System.setOut(ps);
System.out.println("你好,atguigu " );
ps.close();
}
标签:字符,IO,File,new,序列化,public,String
From: https://www.cnblogs.com/xin-zhi-suo-xiang/p/17689401.html