1.内存流:ByteArrayOutputStream,内存流效率高.内存流关闭无效.
eg:public static void main(String[] args) throws IOException {
//1.创建流对象
ByteArrayOutputStream baos=new ByteArrayOutputStream();
//2.用流对象向内存中写入内容
baos.write("abdefefefeefefefeffef我是中国人,我爱中国.写个50个字符试试,试试就试试.我爱学习,学习爱我.我想静静,静静是谁".getBytes());
System.out.println("内容写入成功");
//3.关流
baos.close();
//第一种:获得内存输出流中数据toByteArray()
byte[] content=baos.toByteArray();
String s1=new String(content);
System.out.println("第一种:"+s1);
//第二种:获得内存输出流中数据toString()
String s2=baos.toString();
System.out.println("第二种:"+s2);
//第三种:获得内存输出流中数据,将数据写入到文件中writeTo()
baos.writeTo(new FileOutputStream("aa"+File.separator+"a1.txt"));
System.out.println("第三种获得数据写入文件成功");
/*第四种:用内存读取流来读取内存中数据*/
//创建流对象
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
//准备一个数组
byte[] b=new byte[1024];
//用流对象调用方法读取数据,返回读取的长度,读取的内容存在数组中
int len;
while ((len=bais.read(b))!=-1) {
//将读取的内容转换字符串输出
String s4=new String(b, 0, len);
System.out.println(s4);
}
System.out.println("第四种读取完毕");
//关流
bais.close();
}
2.打印流:
2.1:字节打印流:PrintStream
eg:public static void main(String[] args) {
//声明流对象
PrintStream ps1=null;
try {
//1.创建流对象
ps1=new PrintStream("aa"+File.separator+"a2.txt");
//2.用流对象向文件中写入内容
ps1.append("第一阶段Java注重规范和语法");
ps1.print("第二阶段Java注重项目综合能力及调试bug能力");
ps1.println("第三阶段Java注重企业级开发,框架使用及团队开发");
ps1.write("第四阶段Java注重分布式和微服务开发,注重项目性能".getBytes());
ps1.printf("%.2f", 3.1415926);
System.out.println("写入成功!");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (ps1!=null) {
ps1.close();
}
}
}
2.2:字符打印流:PrintWriter
eg:public static void main(String[] args) {
//声明流对象
PrintWriter pw=null;
try {
//1.创建流对象
pw=new PrintWriter("aa"+File.separator+"a3.txt");
//2.用流对象向文件中写入内容
pw.append("第一阶段Java注重规范和语法");
pw.print("第二阶段Java注重项目综合能力及调试bug能力");
pw.println("第三阶段Java注重企业级开发,框架使用及团队开发");
pw.write("第四阶段Java注重分布式和微服务开发,注重项目性能");
pw.printf("%.2f", 3.1415926);
pw.printf("%d%%", 50);
System.out.println("写入成功!");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (pw!=null) {
pw.close();
}
}
}
2.3:输出重定向(重新定义一个方向输出):将原来在控制台输出的内容,改变方向,写入到文件中.
eg:public static void main(String[] args) throws IOException {
//声明一个存原来打印输出流对象
PrintStream p1=System.out;
//输出重定向,输出到文件中
System.setOut(new PrintStream("aa"+File.separator+"a4.txt"));
//输出内容
System.out.append("别无我有");
System.out.print("别有我优");
System.out.println("无所畏惧");
System.out.write("别优我精".getBytes());
System.out.printf("%.3f", 3.141592631415927);
//输出重定向,重新输出到控制台
System.setOut(p1);
System.out.println("今天中午乌云散去了");
System.out.println("控制台,我又回来了");
}
2.4:输入重定向(重新定义一个方向来接收数据):将原来从控制台接收的数据,改变方向,从文件中接收数据.
eg:public static void main(String[] args) throws FileNotFoundException {
//声明一个变量存标准输入流
InputStream is=System.in;
//输入重定向,在文件中接收数据
System.setIn(new FileInputStream("aa"+File.separator+"a5.txt"));
//创建Scanner类的对象,输入一个输入流作为参数,调用方法从键盘上接收数据
Scanner input=new Scanner(System.in);
System.out.println("请输入姓名:");
String sname=input.next();
System.out.println("请输入爱好:");
String shobby=input.next();
System.out.println("接收姓名为:"+sname+",爱好为:"+shobby);
//输入重定向,重新在控制台接收数据
Scanner input2=new Scanner(is);
System.out.println("请输入一句话:");
String word=input2.next();
System.out.println("接收话为:"+word);
}
3.对象流:用来程序间交换数据.
3.1:序列化:将程序(内存)中对象存到磁盘的文件中,叫序列化.
持久化:将内存中短暂存储的数据存长久存储的磁盘上叫持久化.
反序列化:将磁盘上文件中对象读取到程序(内存)中,叫反序列化.
3.2:对象输出流:ObjectOutputStream
注意:对象输出流向文件中写入对象的过程,其实就是序列化.
eg:public static void main(String[] args) throws IOException {
//声明流对象
ObjectOutputStream oos=null;
try {
//1.创建流对象
oos=new ObjectOutputStream(new FileOutputStream("aa"+File.separator+"a6"+File.separator+"a11.txt"));
/*2.用流向文件中写入对象*/
//第一种:写入字符串对象
String word1="先死后活,死去活来";
//将字符串对象写入文件中
oos.writeObject(word1);
//第二种:写入自定义的对象
Student stu1=new Student("赵天", 18,"girl");
//将自定义对象写入文件中
oos.writeObject(stu1);
//第三种:写入多个对象存到集合中,再将集合写入到文件中
//创建一个集合
List<Student> stuList=new ArrayList();
stuList.add(new Student("张三", 11, "man"));
stuList.add(new Student("李四", 21, "man"));
stuList.add(new Student("王五", 31, "man"));
//将对象集合写入文件中
oos.writeObject(stuList);
System.out.println("写入成功");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (oos!=null) {
oos.close();
}
}
}
3.3:对象输入流:ObjectInputStream
注意:对象输入流将文件中数据读取到程序中过程,其实就反序列化.
eg:public static void main(String[] args) throws IOException {
//声明流对象
ObjectInputStream ois=null;
try {
//1.创建流对象
ois=new ObjectInputStream(new FileInputStream("aa"+File.separator+"a6"+File.separator+"a11.txt"));
/*2.用流来读取文件中对象*/
//第一种:读取一个字符串对象
Object word2=ois.readObject();
//System.out.println("读取的内容为:"+word2);
//第二种:读取写入的自定义的对象
Student stu2=(Student) ois.readObject();
System.out.println(stu2);
//第三种:读取,写入多个对象存到集合中,再将集合写入到文件中
List<Student> stulist2=(List<Student>) ois.readObject();
for (Student stu : stulist2) {
System.out.println(stu);
}
System.out.println("读取完毕");
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
if (ois!=null) {
ois.close();
}
}
}
3.4:对象输入流读取的方法与对象输出流写入的方法类型要一致,否则会报错EOFException.(write数据类型()和read数据类型()这两个方法的数据类型要一致)
3.5:只有实现序列化接口java.io.Serializable接口的类的对象,才能(序列化)用对象输出流写入到文件中.
3.6:版本号错误:local class incompatible: stream classdesc serialVersionUID = -1243946572963888417, local class serialVersionUID = 3821573340049539149
操作:先将学生类的一个对象进行序列化(用对象输出流存到文件中),再修改学生类,再将现在的学生类反序列化取数据,就报版本号错误.
原因:学生类只实现序列化接口,但是没有因定化序列化版本号,这样学生类每修改一次就会重新产生一个新的序列化版本号,如果你用原来序列化版本号对应类的对象存的数据,用新的序列化版本号就取不出数据.
解决:给每个序列化类固定版本号.
eg: private static final long serialVersionUID = -1243946572963888417L;
3.7:如果序列化类中属性不想实现序列化,就用static或transient来修饰就可以
eg:
private static String sex;
private transient String sex;
3.8:如果想用对象流存多个对象到文件中,可以先将多个对象存在集合中,再把集合存到文件中.
java代码实现复制一个文件夹(文件夹可以有子子孙孙文件或目录)
package com.qf.day28.zy;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 2.复制一个文件夹(文件夹可以有子子孙孙文件或目录)
* 分析:文件夹只能创建不能复制,想复制,用代码构造文件夹来创建
* 文件夹中文件的复制,用IO流复制
*/
public class Zy2 {
public static void main(String[] args) {
//原文件夹
File sourceFile=new File("aa");
//目录文件夹
File destFile=new File("bb");
//调用文件夹复制方法
if (sourceFile.isDirectory()&&destFile.isDirectory()) {
copyFold(sourceFile,destFile);
System.out.println("文件夹拷贝成功");
}else {
System.out.println("原文件夹或目标文件夹不是文件夹");
}
}
/**
* 复制文件夹
* @param sourceFile
* @param destFile
*/
public static void copyFold(File sourceFile, File destFile) {//sourceFile=aa,destFile=bb
//构造文件夹对象
File f1=new File(destFile, sourceFile.getName());//bb\\aa
if (!f1.exists()) {//如果文件夹不存在就创建
f1.mkdirs();
}
//获得原文件夹下面所子元素
File[] fileList=sourceFile.listFiles();
//遍历子元素
for (File f2 : fileList) {
if (f2.isDirectory()) {//文件夹,复制
copyFold(f2,f1);
} else {//文件复制
copyFile(f2,f1);
}
}
}
/**
* 复制文件
* @param f2 要复制文件
* @param f1 目录文件夹
*/
private static void copyFile(File f2, File f1) {
//声明流对象
FileInputStream fis=null;
FileOutputStream fos=null;
try {
//1.创建输入流和输出流对象
fis=new FileInputStream(f2);
fos=new FileOutputStream(new File(f1, f2.getName()));
/*用流边读取边写入*/
//准备一个数组
byte[] b=new byte[1024];
//先读取一次,返回读取的长度,读取的内容存到数组中
int len=fis.read(b);
//判断,接着读
while (len!=-1) {
//将读取的内容写入到文件中
fos.write(b, 0, len);
//接着读
len=fis.read(b);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//3.关流
try {
if (fis!=null) {
fis.close();
}
if (fos!=null) {
fos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}