- JAVAOOP-17 字符流
-
- 一. 回顾
- 二. FileReader和FileWriter
- 二. ObjectOutputStream
-
- 三. BufferedReader和 PrintWriter
JAVAOOP-17 字符流
一. 回顾
?
字节流和字符流的区别:
? 字节流: 以字节为单位传输 不能处理中文问题 中文会出现乱码
? 字符流: 以字符为单位传输 一个字符两个字节 可以处理中文问题
二. FileReader和FileWriter
Reader: 抽象类
构造方法 | 说明 |
---|---|
protected Reader() | 创建一个新的字符流 reader,其重要部分将同步其自身的 reader。 |
?
方法 | 说明 |
---|---|
abstract void close() | 关闭该流并释放与之关联的所有资源。 |
int read() | 读取单个字符。 |
int read(char[] cbuf) | 将字符读入数组。 |
abstract int read(char[] cbuf, int off, int len) | 将字符读入数组的某一部分。 |
Writer: 抽象类
构造方法 | 说明 |
---|---|
protected Writer() | 创建一个新的字符流 writer,其关键部分将同步 writer 自身。 |
普通方法 | 说明 |
---|---|
Writer append(char c) | 将指定字符添加到此 writer。 |
Writer append(CharSequence csq) | 将指定字符序列添加到此 writer。 |
Writer append(CharSequence csq, int start, int end) | 将指定字符序列的子序列添加到此 writer.Appendable。 |
abstract void close() | 关闭此流,但要先刷新它。 |
abstract void flush() | 刷新该流的缓冲。 |
void write(char[] cbuf) | 写入字符数组。 |
abstract void write(char[] cbuf, int off, int len) | 写入字符数组的某一部分。 |
void write(int c) | 写入单个字符。 |
void write(String str) | 写入字符串。 |
void write(String str, int off, int len) | 写入字符串的某一部分。 |
FileReader:
方法 | 说明 |
---|---|
FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader。 |
FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader。 |
close, getEncoding, read, read, ready | 从类 java.io.InputStreamReader 继承的方法 |
mark, markSupported, read, read, reset, skip | 从类 java.io.Reader 继承的方法 |
?
?
?
FileWriter:
方法 | 说明 |
---|---|
FileWriter(File file) | 根据给定的 File 对象构造一个 FileWriter 对象。 |
FileWriter(File file, boolean append) | 根据给定的 File 对象构造一个 FileWriter 对象。 |
FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象。 |
FileWriter(String fileName, boolean append) | 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。 |
close, flush, getEncoding, write, write, write | 从类 java.io.OutputStreamWriter 继承的方法 |
append, append, append, write, write | 从类 java.io.Writer 继承的方法 |
代码:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;public class TestRAW {
public static void main(String[] args) throws IOException {
doWrite();doRead();}//写入字符到文件里面public static void doWrite() throws IOException{
Writer w=new FileWriter("D:/bb.txt");w.write("a");w.write("中");w.write("b");w.write("国");w.close();}//从文件里面循环读取数据public static void doRead() throws IOException{
Reader r=new FileReader("D:/bb.txt");int data=-1;while((data=r.read())!=-1){
System.out.println((char)data);}r.close();}}
二. ObjectOutputStream
ObjectOutputStream可以写入一个对象,对象在写入的过程中是以流的形式传输的,必须要序列化
序列化概念:
Java序列化就是指把Java对象转换为字节序列的过程
Java反序列化就是指把字节序列恢复为Java对象的过程。
作用:
? 序列化最重要的作用:在传递和保存对象时.保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。
? 反序列化的最重要的作用:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象
如何序列化: 实现一个序列化接口 implements Serializable
ObjectOutputStream类详解:
构造方法 | 说明 |
---|---|
protected ObjectOutputStream() | 为完全重新实现 ObjectOutputStream 的子类提供一种方法,让它不必分配仅由 ObjectOutputStream 的实现使用的私有数据。 |
ObjectOutputStream(OutputStream out) | 创建写入指定 OutputStream 的 ObjectOutputStream。 |
?
?
普通方法 | 说明 |
---|---|
void close() | 关闭流。 |
void flush() | 刷新该流的缓冲。 |
void reset() | 重置将丢弃已写入流中的所有对象的状态。 |
void write(byte[] buf) | 写入一个 byte 数组。 |
void write(byte[] buf, int off, int len) | 写入字节的子数组。 |
void write(int val) | 写入一个字节。 |
void writeBoolean(boolean val) | 写入一个 boolean 值。 |
void writeByte(int val) | 写入一个 8 位字节。 |
void writeBytes(String str) | 以字节序列形式写入一个 String。 |
void writeChar(int val) | 写入一个 16 位的 char 值。 |
void writeChars(String str) | 以 char 序列形式写入一个 String。 |
void writeDouble(double val) | 写入一个 64 位的 double 值。 |
void writeFloat(float val) | 写入一个 32 位的 float 值。 |
void writeInt(int val) | 写入一个 32 位的 int 值。 |
void writeLong(long val) | 写入一个 64 位的 long 值。 |
void writeObject(Object obj) | 将指定的对象写入 ObjectOutputStream。 |
void writeShort(int val) | 写入一个 16 位的 short 值。 |
void writeUTF(String str) | 以 UTF-8 修改版格式写入此 String 的基本数据。 |
ObjectInputStream类详解:
构造方法 | 说明 |
---|---|
protected ObjectInputStream() | 为完全重新实现 ObjectInputStream 的子类提供一种方式,让它不必分配仅由 ObjectInputStream 的实现使用的私有数据。 |
ObjectInputStream(InputStream in) | 创建从指定 InputStream 读取的 ObjectInputStream。 |
普通方法 | 说明 |
---|---|
void close() | 关闭输入流。 |
int read() | 读取数据字节。 |
int read(byte[] buf, int off, int len) | 读入 byte 数组。 |
boolean readBoolean() | 读取一个 boolean 值。 |
byte readByte() | 读取一个 8 位的字节。 |
char readChar() | 读取一个 16 位的 char 值。 |
double readDouble() | 读取一个 64 位的 double 值。 |
float readFloat() | 读取一个 32 位的 float 值。 |
int readInt() | 读取一个 32 位的 int 值。 |
long readLong() | 读取一个 64 位的 long 值。 |
Object readObject() | 从 ObjectInputStream 读取对象。 |
short readShort() | 读取一个 16 位的 short 值。 |
String readUTF() | 读取 UTF-8 修改版格式的 String。 |
实现将Student对象写到文件里面
import java.io.*;public class TestObject {
public static void main(String[] args) {
try {
//doWrite();doRead();} catch (Exception e) {
e.printStackTrace();}}//往文件里面写入Student对象public static void doWrite() throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("C:\\Users\\17909\\Desktop\\20201130班级\\1202\\3.txt"));Student s1=new Student("zhangsan",23);Student s2=new Student("lisi",28);oos.writeObject(s1);oos.writeObject(s2);oos.close();}//从文件中读取Student对象public static void doRead() throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("C:\\Users\\17909\\Desktop\\20201130班级\\1202\\3.txt"));Student s1=(Student) ois.readObject();Student s2=(Student) ois.readObject();System.out.println(s1);System.out.println(s2);ois.close();}
}class Student implements Serializable{
String name;int age;public Student() {
}public Student(String name, int age) {
this.name = name;this.age = age;}@Overridepublic String toString() {
return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
三. BufferedReader和 PrintWriter
文本数据太大,一个一个读写效率太低,BufferedReader可以实现逐行读取,PrintWriter可以实现逐行写入
注意: BufferedWriter里面没有逐行写入的方法
BufferedReader:
方法 | 说明 |
---|---|
BufferedReader(Reader in) | 创建一个使用默认大小输入缓冲区的缓冲字符输入流。 |
String readLine() | 读取一个文本行。 |
?
?
PrintWriter:
构造方法 | 说明 |
---|---|
PrintWriter(File file) | 使用指定文件创建不具有自动行刷新的新 PrintWriter。 |
PrintWriter(OutputStream out) | 根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。 |
PrintWriter(OutputStream out, boolean autoFlush) | 通过现有的 OutputStream 创建新的 PrintWriter。 |
PrintWriter(String fileName) | 创建具有指定文件名称且不带自动行刷新的新 PrintWriter。 |
PrintWriter(Writer out) | 创建不带自动行刷新的新 PrintWriter。 |
PrintWriter(Writer out, boolean autoFlush) | 创建新 PrintWriter。 |
?
? 实现逐行读取和逐行写入的操作:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;public class TestRWLine {
public static void main(String[] args) throws IOException {
testReadLine();testWriteLine();}public static void testReadLine() throws IOException{
BufferedReader br=new BufferedReader(new FileReader("D:\\day17\\主要内容.txt"));String line=null;while((line=br.readLine())!=null){
System.out.println(line);}br.close();}public static void testWriteLine() throws IOException{
PrintWriter pw=new PrintWriter(new FileWriter("D:/ccc.txt"));//PrintWriter里面有逐行写的方法,他可以包装字节流和字符流pw.println("jkfwog");pw.println("加快流入共和国");pw.println("你好啊!!!!!!!");pw.println("很好!!!!!!!!!!!!!!!!!!");pw.close();}}
四: Properties
Properties里面放的是键值对类型,extends HashTable,是可以将数据持久化到本地文件的流对象
类 Properties: 位于java.util包下
- Properties 类表示了一个持久的属性集。
- Properties 可保存在流中或从流中加载。
- 属性列表中每个键及其对应值都是一个字符串。
构造方法:
构造方法 | 说明 |
---|---|
Properties() | 创建一个无默认值的空属性列表。 |
Properties(Properties defaults) | 创建一个带有指定默认值的空属性列表。 |
普通方法:
方法 | 说明 |
---|---|
String getProperty(String key) | 用指定的键在此属性列表中搜索属性。 |
String getProperty(String key, String defaultValue) | 用指定的键在属性列表中搜索属性。 |
void list(PrintStream out) | 将属性列表输出到指定的输出流。 |
void list(PrintWriter out) | 将属性列表输出到指定的输出流。 |
void load(InputStream inStream) | 从输入流中读取属性列表(键和元素对)。 |
void load(Reader reader) | 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 |
Enumeration<?> propertyNames() | 返回属性列表中所有键的枚举,如果在主属性列表中未找到同名的键,则包括默认属性列表中不同的键。 |
Object setProperty(String key, String value) | 调用 Hashtable 的方法 put。 |
void store(OutputStream out, String comments) | 以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 |
void store(Writer writer, String comments) | 以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。 |
Set stringPropertyNames() | 返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。 |
?
实现Properties集合的读取和写入(存储)
在src下面创建name.properties文件
import java.io.*;
import java.util.Properties;public class TestProperties {
public static void main(String[] args) {
try {
mystore1();myLoad();} catch (IOException e) {
e.printStackTrace();}}//写入数据到本地public static void mystore1() throws IOException {
//创建Properties集合对象Properties prop=new Properties();prop.setProperty("张三","33");prop.setProperty("李四","29");//写入本地文件Writer w=new FileWriter("src\\name.properties");prop.store(w,"helloworld");//关闭流w.close();}//从本地文件加载数据public static void myLoad() throws IOException {
//创建Properties集合对象Properties prop=new Properties();//创建流对象Reader reader=new FileReader("src\\name.properties");//加载数据prop.load(reader);System.out.println("properties: "+prop);//关闭流reader.close();}
}
练习demo
import java.io.*;
import java.util.Enumeration;
import java.util.Properties;public class TestProperties2 {
public static void main(String[] args) {
try {
//testWrite();testRead();} catch (IOException e) {
e.printStackTrace();}}//从文件中读取public static void testRead() throws IOException {
//创建Properties对象Properties prop=new Properties();//创建流对象BufferedReader br=new BufferedReader(new FileReader("src\\demo.properties"));// void load(Reader reader) 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。prop.load(br);prop.list(System.out);//把prop对象中的名称值输出到控制台//显示数据 循环遍历Properties对象Enumeration keys = prop.keys();while(keys.hasMoreElements()){
String key = (String) keys.nextElement();String value = prop.getProperty(key);//String value = (String) prop.get(key);System.out.println(key+" = "+value);}//关闭流br.close();}//写入到文件里面public static void testWrite() throws IOException {
//创建Properties对象Properties prop=new Properties();//放入数据prop.put("111","aaa");prop.put("222","bbb");//创建流对象PrintWriter pw=new PrintWriter(new FileWriter("src\\demo.properties"));// void list(PrintWriter out) 将属性列表输出到指定的输出流。prop.list(pw);pw.close();}}
.实现复制一个目录中的所有内容到另一个目录
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;// 2.复制一个目录中的所有内容到另一个目录
public class Zy3 {
public void doCopy(File src,File tar) throws IOException{
BufferedInputStream in=new BufferedInputStream(new FileInputStream(src));BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(tar));int data=-1;while((data=in.read())!=-1){
out.write(data);}in.close();out.close();}public void doCopyDir(File src,File tar) throws IOException{
if(src==null||tar==null){
throw new RuntimeException("参数不能为null");}if(tar.isFile()){
throw new RuntimeException("目标目录不能是文件");}if(src.isFile()){
String fileName=src.getName();File newFile=new File(tar,fileName);doCopy(src, newFile);}else if(src.isDirectory()){
String srcPath=src.getName();File newFile=new File(tar,srcPath);if(!newFile.exists()){
newFile.mkdirs();}File[] children=src.listFiles();if(children!=null&&children.length>0){
for (File child : children) {
doCopyDir(child, newFile);}}}}public static void main(String[] args) throws IOException {
Zy3 zy=new Zy3();File src=new File("D:\\day20");File tar=new File("D:");zy.doCopyDir(src, tar);}}