Java day20
字符流:
-
产生字符流的原因:
-
因为字节流读取字符太麻烦,容易出现乱码
输入字符流的基类:Reader,输出字符流的基类Writer
Reader
-
公有方法
-
abstract void close():关闭资源
public int read():一个一个字符读取
public int read(char[] cbuf):读取多个字符保存到char类型的数组里
public abstract int read(char[] cbuf,int off,int len):读取多个字符保存到 char类型的数组里,给定起点和长度
FileReader :
FileReader是用于读取字符的流
-
构造方法
-
public FileReader(String fileName) fileName 文件的路径
public FileReader(File file) file 文件对象
//构造过程:
//1. 实例化 FileReader对象
//2. 把FileReader 对象指向文件
Reader reader = new FileReader("1.txt"); //实例化FileReader对象
-
常规的方法与父类相同
-
public int read():一个一个字符读取
public int read(char[] cbuf):读取多个字符保存到 char类型的数组里
//FileReader读取数据的步骤:
//1. 实例化FileReader对象
//2. 调用读取的方法
//3. 关闭资源
Reader reader = new FileReader("1.txt"); //实例化
int i = reader.read(); //调用读方法
System.out.println((char)i); //输出
reader.close(); //关闭流
-
read()方法:
-
int read():一个一个字符读取,返回值是读取的具体的数据,使用char类型强转为字符
int read(char[] cbuf):读取多个字符,返回值是读取的有效字符数, 读取的数据保存在数组里
Writer
写数据的字符流的基类
-
常规的一些方法
-
close():关闭流,先刷新。
abstract void flush():刷新流。
void write(char[] cbuf):写入一个字符数组。
abstract void write(char[] cbuf, int off, int len):写入字符数组的一部分。
void write(String str):写一个字符
void write(String str, int off, int len):写一个字符串的一部分。
FileWriter:
用于写入的字符流
-
常规的构造方法
-
public FileWriter(File file):构造一个给定文件名的FileWriter对象
public FileWriter(File file,boolean append):构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据
public FileWriter(String fileName):给一个File对象,构造一个FileWriter对象。
public FileWriter(String fileName,boolean append):给一个File对象,构造一个FileWriter对象。 如果第二个参数是true ,则字符将写入文件的末尾而不是开头。
//FileWriter向文件写入数据的步骤
//1. 创建这个FileWriter
//2. 调用其写的方法
//3. 调用刷新缓冲区的方法flush()
//4. 关闭资源
public class Test {
public static void main(String[] args) throws IOException {
//构造方法:
//1. 创建FileWriter
//2. 创建一个空的文件
//3. 把FileWriter对象指向这个文件
Writer writer = new FileWriter("1.txt");
writer.write("abc\n");
writer.write(new char[]{'1','2','3','\n'});
writer.write("decghi",0,3);
writer.close();
}
}
如果仅仅是纯文件的复制,没有必要使用字符来进行读取操作,因为字符读取,底层也是转换成字节在读写操作,这样就会产生多余的转换,效率会变低
字符流,不能读写图片,音视频,因为读取图片的时候,会把图片的字节转换为字符,产生转换错误,导致图片打不开
BufferedReader
带缓冲区的输入字符流:
- 字符输入流读取文本,
- 缓冲字符,以提供字符,数组和行的高效读取。
-
常用的构造方法
-
public BufferedReader(Reader in):构造里需要传递一个Reader对象
public BufferedReader(Reader in,int sz):in为Reader对象,sz设置缓冲区的大小 , 一般使用默认的就够了
常规的方法
-
close():关闭流并释放与之相关联的任何系统资源
read():读一个字符
read(char[] cbuf, int off, int len):将字符读入数组的一部分。
readLine():读一行文字.最高效,一般就使用这种
//使用BufferedReader进行读取的一个步骤:
//1.实例化BufferedReader
//2.调用读的方法
//3.关闭资源
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("1.txt"));
String s = null;
while ((s=reader.readLine())!=null){
System.out.println(s);
}
reader.close();
}
}
BufferedWriter
带缓冲区的字符写入流
- 将文本写入字符输出流.
- 提供单个字符,数组和字符串的高效写入。
-
常用的构造
-
public BufferedWriter(Writer out):创建使用默认大小的输出缓冲区的缓冲字符输出流
public BufferedWriter(Writer out,int sz):创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。
常用的方法
-
close() 关闭流,先刷新。
void flush():刷新流。
void newLine():写一行行分隔符.
void write(char[] cbuf, int off, int len):写入字符数组的一部分。
void write(int c):写一个字符
write(String s, int off, int len):写一个字符串的一部分。
//使用BufferedWriter 向文件写数据的步骤:
//1.实例化
//2.调用写的方法
//3.刷新缓冲区
//4.关闭资源
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = null;
BufferedWriter writer = null;
reader = new BufferedReader(new FileReader("1.txt"));
writer = new BufferedWriter(new FileWriter("2.txt"));
String temp = null;
while((temp=reader.readLine())!=null){
writer.write(temp+"\n");
}
writer.close();
reader.close();
}
}
InputStreamReader
输入转换流
- InputStreamReader 是从字节流到字符流的桥
- 可以指定其编码格式(最重要的一个作用)
- 为了最大的效率,请考虑在BufferedReader中包装一个InputStreamReader
-
常用的构造方法
-
public InputStreamReader(InputStream in):构造传递了一个InputStream
public InputStreamReader(InputStream in,String charsetName):charsetName,设置其编码
常规的方法
-
public void close():关闭资源
int read():读一个字符
int read(char[] cbuf, int offset, int length):将字符读入数组的一部分。
//步骤
//1.实例化BufferedReader==>InputStreamReader==>FileInputStream
//2.调用其读的方法
//3,关闭资源
public class Test {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("1.txt"),"UTF-8"));
String str = null;
while ((str=reader.readLine())!=null){
System.out.println(str);
}
reader.close();
}
}
OutputStreamWriter
输出转换流
- 字符流转换成字节流的一个桥梁
- 可设置编码格式
- 为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换
-
常用的构造方法
-
public OutputStreamWriter(OutputStream out):构造中传递一个OutputStream
public OutputStreamWriter(OutputStream out,String charsetName):charsetName,设置编码格式
常规的方法
-
void close():关闭流,先刷新。
void flush():刷新流
String getEncoding():返回此流使用的字符编码的名称。
void write(char[] cbuf, int off, int len):写入字符数组的一部分
void write(int c):写一个字符
void write(String str, int off, int len):写一个字符串的一部分。
//步骤:
//1.实例化 BufferedWriter
//2.调用其写的方法
//3.刷新缓冲区
//4.关闭资源
public class Test {
public static void main(String[] args) {
BufferedReader reader = null;
BufferedWriter writer = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream("../day20/src/1.txt"),"UTF-8"));
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("../day20/src/2.txt"),"UTF-8"));
String temp = null;
while ((temp=reader.readLine())!=null){
writer.write(temp+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(reader != null){
reader.close();
}
if (writer!=null){
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对象流
ObjectOutputStream
对象输出流
- 借助OutputStream对象进行对象的输出
- 只有支持java.io.Serializable接口的对象才能写入流中
-
构造方法
- public ObjectOutputStream(OutputStream out) 传递了一个参数是OutputStream 常规的方法
- public final void writeObject(Object obj) 写对象到文件里 java.io.NotSerializableException:对象没有进行序列化.
- 序列化也就是让对象实现这个接口Serializable java.io.InvalidClassException: 产生的原因就是写对象到文件里产生的serialVersionUID与读的时候本地的serialVersionUID不一样
- public static final long serialVersionUID = 200;给对象序列化加一个标识,不加系统默认生成 java.io.EOFException:在读取对象的时候产生这个异常的原因,没有标识表示读取到了末尾
- 添加一个标识,比如null
//步骤:
//1.实例化
//2.调用writeObject(Object obj)
//3.刷新缓冲区
//4.关闭资源
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Student.obj"));
out.writeObject(new Student("Tom",18));
out.close();
}
}
ObjectInputStream
对象输入流
- 读取数据的时候,需要反序列化
-
构造方法
- public ObjectInputStream(InputStream in):需要传递一个InputStream 对象 常规的方法
- public final Object readObject():返回值是一个Object对象,还是使用final修饰,不能够被改变
//步骤:
//1.实例化ObjectInputStream InputStream对象
//2.调用其读的方法readObject()
//3.关闭资源
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("Student.obj"));
Student stu = (Student)in.readObject();
System.out.println(stu.name+":"+stu.age);
in.close();
}
}
//添加标识
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Student.obj"));
out.writeObject(new Student("Tom",18));
out.writeObject(new Student("Jack",19));
out.writeObject(null);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("Student.obj"));
Student stu = null;
while((stu=(Student)in.readObject())!=null){
System.out.println(stu.name+":"+stu.age);
}
in.close();
}
}
//使用集合
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream in = null;
ObjectOutputStream out = null;
out = new ObjectOutputStream(new FileOutputStream("Student.List"));
List<Student> list = new ArrayList<>();
list.add(new Student("Tom",18));
list.add(new Student("Jack",20));
out.writeObject(list);
out.close();
in = new ObjectInputStream(new FileInputStream("Student.List"));
List<Student> copy = (List<Student>) in.readObject();
for(Student stu:copy){
System.out.println(stu.name+":"+stu.age);
}
in.close();
}
}