字节流和字符流的区别:
字节流: 以字节为单位传输 不能处理中文问题 中文会出现乱码
字符流: 以字符为单位传输 一个字符两个字节 可以处理中文问题
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可以写入一个对象,对象在写入的过程中是以流的形式传输的,必须要序列化
序列化概念:
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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
文本数据太大,一个一个读写效率太低,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 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); } }