当前位置: 代码迷 >> 综合 >> JAVAOOP-17 字符流
  详细解决方案

JAVAOOP-17 字符流

热度:61   发布时间:2023-11-27 11:03:48.0

  • 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);}}