package IODemo;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
* 缓冲流
* 1.BufferedReader 提供了缓冲区,能够实现按行读取的效果
*
* 2.装饰设计模式: 利用FileReader来构建了BufferedReader,然后再BufferedReader对读取功能做了增强。
*
* 特点:利用了同类对象构建了自己对象本身,对对象身上的功能做了增强或者改善。
*
* 3.BufferedWriter只是比FileWriter提供了一个更大的缓冲区
*
*4.注意:Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
*
* 5.字节流和字符流比较:
* 1.字符流只能操作Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
* 字节流可以操作任意类型文件,但不能是目录,范围广
*
* 2.字符流输出流(out)write有缓冲区
* 字节流在输出流(out)Write没有缓冲区
* 字符输入流(in)Read 需要手动提供char[] 数组 char[] cs=new char[7];
* 字节输入流(in)Read 需要手动提供byte[] 数组 byte[] bs=new byte[10];
*/
public class IODemo05BufferedReader {
public static void main(String[] args) throws IOException {
//1.创建一个使用默认大小输入缓冲区的缓冲字符输入流。 BufferedReader(Reader in)
//在这个过程中,真正读取数据的是FileReader,而FileReader没有缓冲区
//FileReader将读取到的数据提供给BufferedReader(),BufferedReader()提供缓冲区
BufferedReader reader=new BufferedReader (new FileReader("D:\\A\\a.txt"));
//2.读取一个文本行。 String readLine()
//2.1读取一行数据
//String str=reader.readLine();
//2.2读取多行,读到最后为空
//定义一个变量来记录每一行的数据,最后一行为null
String str=null;
while((str=reader.readLine())!=null) {
System.out.println(str);
}
//3.关流 void close()
//只需要关闭最外层的流BuffererReader即可,那么这个时候底层会自动关闭底层FileReader的流
reader.close();
}
}
package IODemo;
public class IODemo05F_1_5Char6_7Byte {
}
/*
*1-5 FileWriter FileReader BufferWriter BufferReader 字符流char
*
*6-7 FileOutputStream FileInputStream 字节流Byte
*
*8 系统流/标准流 系统流都是字节流
System.in 标准输入流
System.out 标准输出流
System.err 标准错误流
*
*
*9-10 转换流: 字节流和字符流之间用的转换的流。
*
* 1.OutputStreamWriter
* 字符流->字节流
* FileWriter是它的子类
*
* 2.InputStreamWriter
* 字节流->字符流
* FileReader是它的子类
*
*
*11.合并流
SequenceInputStream
*
*12.序列化/反序列化流
将对象转化为字节之后进行存储 --- 序列化 --- 持久化
将字节转化为对象的过程 --- 反序列化
*
*
*字节流和字符流比较:
* 1.字符流只能操作Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
* 字节流可以操作任意类型文件,但不能是目录,范围广
*
* 2.字符流输出流(out)write有缓冲区
* 字节流在输出流(out)Write没有缓冲区
* 字符输入流(in)Read 需要手动提供char[] 数组 char[] cs=new char[7];
* 字节输入流(in)Read 需要手动提供byte[] 数组 byte[] bs=new byte[10];
*
* 字符输入流(in)BufferedReader read直接readLine()不用数组,最后一行为null,其他都为-1
*
*
*
*
*
*/
package IODemo;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* FileOutputStream----字节输出流,可以向文件中写入数据,不局限txt文件,可以操作任意文件不能是目录
*
* 注意:Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
*
* 字节流和字符流比较:
* 1.字符流只能操作Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
* 字节流可以操作任意类型文件,但不能是目录,范围广
*
* 2.字符流输出流(out)write有缓冲区
* 字节流在输出流(out)Write没有缓冲区
* 字符输入流(in)Read 需要手动提供char[] 数组 char[] cs=new char[7];
* 字节输入流(in)Read 需要手动提供byte[] 数组 byte[] bs=new byte[10];
*/
public class IODemo06FileOutputStream {
public static void main(String[] args) throws IOException {
//字节输出流FileOutputStream,不局限txt文件,可以操作任意文件
//之前是字符流
//1.创建向指定 File对象文件中写入数据的文件输出流。 FileOutputStream(File file)
FileOutputStream out=new FileOutputStream("D:\\A\\a.txt");
//2.将 b.length个字节从指定 byte数组写入此文件输出流中。 void write(byte[] b)
//字节输出流没有缓冲区
out.write("abcdada".getBytes());
//3.关闭输出流
out.close();
}
}
package IODemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* FileInputStream----字节输入流,可以从文件中读取数据,不局限txt文件,可以操作任意文件不能是目录
*
* 注意:Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
*
* 字节流和字符流比较:
* 1.字符流只能操作Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
* 字节流可以操作任意类型文件,但不能是目录,范围广
*
* 2.字符流输出流(out)write有缓冲区
* 字节流在输出流(out)Write没有缓冲区
* 字符输入流(in)Read 需要手动提供char[] 数组 char[] cs=new char[7];
* 字节输入流(in)Read 需要手动提供byte[] 数组 byte[] bs=new byte[10];
*/
public class IODemo07FileInputStream {
public static void main(String[] args) throws IOException {
//字节输入流FileInputStream,不局限txt文件,可以操作任意文件
//之前是字符流
FileInputStream in=new FileInputStream("D:\\A\\a.txt");
//手动提供一个缓冲区
byte[] bs=new byte[10];
//定义一个变量来记录每次读取的字节的数目
int len=-1;
while((len=in.read(bs))!=-1) {
System.out.println(new String(bs, 0, len));
}
//3.关闭输入流
in.close();
}
}
package IODemo;
import java.io.IOException;
/*
* 系统流/标准流,都是字节流
* System.in: 标准输入流
* System.out: 标准输出流
* System.err: 标准错误输出流
*/
public class IODemo08SystemStream {
public static void main(String[] args) throws IOException {
System.out.println("请输入一个数字");
//1.标准输入流 static InputStream in
//读取数据
int i=System.in.read();
//2.标准输出流 static PrintStream out
//打印正常结果,输出颜色为黑色
System.out.println(i);
//3.标准错误输出流 static PrintStream err
//打印异常,输出颜色为红色
System.err.println(i);
}
}
package IODemo;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/*
* 转换流:
* 字节流和字符流之间用的转换的流。
*
* 1.OutputStreamWriter
* 字符流->字节流
* FileWriter是它的子类
*
* 2.InputStreamWriter
* 字节流->字符流
* FileReader是它的子类
*
*/
public class IODemo09OutputStreamWriter {
public static void main(String[] args) throws IOException {
//1.构建了一个转化流对象
//真正写数据的是FileOutputStream
//OutputStreamWriter 字符流->字节流 //FileOutputStream字节输出流 真正写数据
OutputStreamWriter ow=new OutputStreamWriter(new FileOutputStream("D:\\A\\a.txt"),"utf-8");//如果不知道编码用的是默认编码
//2.写数据
ow.write("沈志恒");
//3.关闭流
ow.close();
}
}
package IODemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
/*
* 转换流:
* 字节流和字符流之间用的转换的流。
*
* 1.OutputStreamWriter
* 字符流->字节流
* FileWriter是它的子类
*
* 2.InputStreamWriter
* 字节流->字符流
* FileReader是它的子类
*
*/
public class IODemo10InputStreamReader {
public static void main(String[] args) throws IOException {
//1.构建了一个转化流对象
//真正读取数据的FileInputStream
//InputStreamReader 字节流->字符流 //FileInputStream 字节输入流
InputStreamReader iw=new InputStreamReader(new FileInputStream("D:\\A\\a.txt"),"utf-8");
//2.读取数据
char[] cs=new char[10]; //字符
int len=iw.read(cs); //字节流byte->字符流char
System.out.println(new String(cs,0,len));
//3.关闭流
iw.close();
// FileReader reader = new FileReader("a.txt");
// 上面代码的底层实际上是 reader = new InputStreamReader(new FileInputStream("a.txt"));
//FileReader是InputStreamWriter的子类 字节流->字符流
}
}
package IODemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/*
* 合并流:
* SequenceInputStream
*
* 1.创建输入流分别指向对应文件 reader
* 2.创建vector集合存储输入流
* 3.利用vector集合产生一个Enumeration对象
* 4.使用Enumeration对象来构造合并流SequenceInputStream 2,3给4提供参数Enumeration
* 5.6.7最后利用合并流来读取数据进行合并。
*
*
*
*/
public class IODemo11SequenceInputStream {
public static void main(String[] args) throws IOException {
//合并三个文件到一个文件
//1.创建输入流分别指向三个文件
FileInputStream in1=new FileInputStream("D:\\A\\a.txt");
FileInputStream in2=new FileInputStream("D:\\A\\b.txt");
FileInputStream in3=new FileInputStream("D:\\A\\c.txt");
///2.需要创建一个Vector对象存储这三个流对象
Vector<InputStream> v=new Vector<>();
v.add(in1);
v.add(in2);
v.add(in3);
//3.产生Enumeration对象
Enumeration<InputStream> e=v.elements();
//2.3两步是为了第4步构建合并流对象提供函数参数(参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数)。
//4.构建合并流对象
//public SequenceInputStream(Enumeration<? extends InputStream> e)
//通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。
//将按顺序读取由该枚举生成的输入流,以提供从此 SequenceInputStream 读取的字节。
//在用尽枚举中的每个输入流之后,将通过调用该流的 close 方法将其关闭。
SequenceInputStream sis=new SequenceInputStream(e);
//5.创建一个输出流对象指向要存放的文件
FileOutputStream out=new FileOutputStream("D:\\A\\d.txt");
//6.读取数据
byte[] bs=new byte[10];
//定义一个变量来记录每次读取的字节的数目
int len=-1;
while((len=sis.read(bs))!=-1) {
out.write(bs,0,len);
}
//7.关流
sis.close();//in的流合并到sis,只需关闭sis,其他一起关闭
out.close();
}
}
package IODemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/*
* 序列化/反序列化流
* Serializable
*
1.序列化: 将对象转化为字节之后进行存储 持久化(存储到硬盘等介质)
反序列化: 将字节转化为对象的过程
ObjectOutputStream 序列化流对象 Write
ObjectInputStream 反序列化流对象Reader
2.一个对象想要被序列化,必须要实现Serializable接口,这个接口中没有任何的方法和属性,仅仅起标志性作用
3.注意: 用static/transient修饰的属性不会被序列化 不用序列化 static
可有可无,内存珍贵,让其选择不被序列化 +transient 强制不会序列化 transient
4.如果一个类产生的对象允许被序列化,那么这个时候这个类在编译的时候会根据当前类中的属性自动计算一个版本号。
当反序列化的时候,拿着对象中的版本号和类中的版本号做比较,如果相等,则说明这个是这个类产生的,可以被反序列化。
如果没有手动指定版本号,自动计算版本号,那么就意味着类变动一次,版本号就会重新计算一次。
为了让序列化出去的对象反序列化回来,需要手动指定版本号-----private static final long serialVersionUID
*/
public class IODemo12Serializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建Person对象
Person p=new Person();
p.setName("szh");
p.setAge(21);
//-------------------------------序列化流对象 ObjectOutputStream Writer-------------------------------------------------------------------
//1.创建一个序列化流对象ObjectOutputStream
//ObjectOutputStream将对象转化为字节数据 //FileOutputStream 实际将字符数组写到文件中
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D:\\A\\e.data")); //写到e.data
//2.写对象 writeObject()
oos.writeObject(p);
//3.关流
oos.close();
//------------------------------反序列化流对象ObjectInputStream---Reader--------------------------------------------------------------------
//1.创建一个反序列化流对象ObjectInputStream
//ObjectInputStream将字节数组转化为对象 //FileInputStream 读取文件,读取到一个字节数组
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("D:\\A\\e.data"));
//2.读取对象 readObject()
Person p2=(Person) ois.readObject();
//3.关流
ois.close();
System.out.println(p2.getAge());
System.out.println(p2.getName());
//注意:
//错误,集合不能被整体序列化,只能遍历,一个个序列化
//List<Person> list=new LinkedList<>(); // ArrayList 不可以 //Vector可以,意义不大
//out. writeObject(list)
}
}
//2.一个对象想要被序列化,必须要实现implements Serializable接口,这个接口中没有任何的方法和属性,仅仅起标志性作用
class Person implements Serializable{
//版本号
private static final long serialVersionUID=536L;
//先序列化,再后面增添属性private String gender,不可以
//4.如果没有手动指定版本号,自动计算版本号,那么就意味着类变动一次,版本号就会重新计算一次。
//为了让序列化出去的对象反序列化回来,需要手动指定版本号-----private static final long serialVersionUID,这样就可以增加属性和方法,成功
private String name;
private int age;
static String classroom; //3.1注意:用static修饰的属性不会也不用被序列化
private transient double height; //3.2可有可无,内存珍贵,让其选择不被序列化 +transient
public String getName() {
return name;
}
public static String getClassroom() {
return classroom;
}
public static void setClassroom(String classroom) {
Person.classroom = classroom;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package IODemo;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* 字节流和字符流比较:
* 1.字符流只能操作Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件
* 字节流可以操作任意类型文件,但不能是目录,范围广
*
* 2.字符流输出流(out)write有缓冲区
* 字节流在输出流(out)Write没有缓冲区
* 字符输入流(in)Read 需要手动提供char[] 数组 char[] cs=new char[7];
* 字节输入流(in)Write 需要手动提供byte[] 数组 byte[] bs=new byte[10];
*/
public class IOExer {
public static void main(String[] args) throws IOException{
//1.复制文件,利用字符流 注意:Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件,而字节流可以操作任意类型文件不能是目录
//思想:一个输入流读取文件,然后将读取到内容写到新文件中
// 一个输出流写到新文件
//1.创建输入流对象Reader,输出流对象Writer
FileReader reader=new FileReader("D:\\A\\a.txt");
FileWriter writer=new FileWriter("D:\\A\\d.txt");
//2.不断read(),不断写write()
int len=-1; // 定义一个变量来记录每次读取的字符个数
char[] cs=new char[256]; // 创建有一个字符数组作为缓冲区
//读到末尾,返回-1
while((len=reader.read(cs))!=-1) {
writer.write(cs,0,len); //写入数据
}
//3.关闭操作
//writer.flush();
writer.close();
//writer=null;
reader.close();
//2.复制文件,利用字节流,并统计时间 注意:Java中的原生字符流只能操作字符类文件 txt,java,html,但不能读取office组件,而字节流可以操作任意类型文件不能是目录
//对于大文件,一般缓冲区的合适大小是10M-15M
long start=System.currentTimeMillis();
//1.创建一个字节输入流指向要读取文件
FileInputStream in=new FileInputStream("C:\\Users\\123\\Desktop\\0317笔记.docx");
FileOutputStream out=new FileOutputStream("C:\\Users\\123\\Desktop\\zzzzz.docx");
//创建一个字节数组作为缓冲区
byte[] bs=new byte[10]; //10个字节读一次 ,这里是byte,上面是char
//定义一个变量表示获取字符个数
int length=-1;
//读取数组
while((length=in.read(bs))!=-1) {
//写入数据
out.write(bs,0,length);
}
out.close();
in.close();
long end=System.currentTimeMillis();
System.out.println("复制docx文件成功,共花费"+(end-start)+"ms");
}
}
package IODemo;
import static org.junit.Assert.assertNotNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class IOExer2 {
private static int count = 0;
public static void main(String[] args) throws IOException {
//练习1:统计工作空间中Java代码的行数
//思想: 先创建File对象(文件操作),如果传入的是目录需要不断递归,递归文件获取
// 如果传入的是文件直接创建BufferReader对象(读取操作),不断循环遍历java文件,读到一行+1
File file=new File("E:\\ChenXunCode\\DaNeiBigDataCode");
countLine(file);
System.out.println("工作空间中Java代码的行数"+count);
}
private static void countLine(File file) {
// TODO Auto-generated method stub
//判断文件是否为空
if (file == null)
throw new NullPointerException();
// 判断是否是一个目录
if (file.isDirectory()) { //如果传入的是目录需要不断递归,递归文件获取
File[] fs = file.listFiles();
for (File f : fs) {
countLine(f); //递归
}
} else if (file.getName().endsWith(".java")) { //如果传入的是文件直接创建BufferReader对象(读取操作),不断循环遍历java文件,读到一行+1
// 读取Java文件,统计行数
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
while (reader.readLine() != null){
count++;
}
//上面那个是缓冲区还是字符流,这个是字节流byte
//FileInputStream in=new FileInputStream(file);
//byte[] bs=new byte[10];
//int len=-1;
//while((len=in.read(bs))!=-1){count++;}
//in.close();
//只需要关闭最外层的流BuffererReader即可,那么这个时候底层会自动关闭底层FileReader的流
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
下面是Properties
package Properties;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/*
* Properties
* 是一个可以被持久化的映射Map<key,value>,键和值的类型都是String
*
* properties文件默认编码是西欧编码
* 向properties文件中存放中文是会变成unicode编码
*/
public class PropertiesDemo01 {
public static void main(String[] args) throws FileNotFoundException, IOException {
//--------------------序列化----------------------------------
//1.创建Properties对象
Properties prop=new Properties();
//2.添加元素 .setProperty(key,value)
prop.setProperty("name", "WuYun");
prop.setProperty("年龄", "二十"); //properties出现\u5E74\u9F84=\u4E8C\u5341
//properties文件默认编码是西欧编码,向properties文件中存放中文是会变成unicode编码
//3.持久化 (序列化存到文件中) .store(字节输出流,向这个properties文件添加注释)
//只能存放到.properties结尾的文件
prop.store(new FileOutputStream("p.properties"), "That is a person");
//---------------------反序列化------------------------------
//1.创建Properties对象
Properties pr=new Properties();
//2.反序列化对象 .load(字节输入流)
pr.load(new FileInputStream("p.properties"));
//3.获取元素 .getProperty(key)
System.out.println(pr.getProperty("name"));
System.out.println(pr.getProperty("年龄"));
}
}
下面是单元测试
package UnitTest;
import java.io.FileWriter;
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
//单元测试
//导入单独的测试库。
//要求测试的方法做到 “三无”:没有参数、没有返回值、非静态方法
public class UnitTestDemo {
FileWriter writer;
@Before
// 在测试方法之前执行用于完成一些初始化的操作
public void init() throws IOException {
writer = new FileWriter("E:\\a.txt", true);
}
@Test
public void write1() throws IOException {
writer.write("abc");
}
@Test
public void write2() throws IOException {
writer.write("def");
}
@After
// 在测试方法之后执行用于完成一些善后的工作
public void destroy() throws IOException {
writer.close();
}
}