目录
四、FileInputStream和FileOutputStream
五、BufferedInputStream和BufferedOutputStream(BufferedReader和Bufferedwriter)
六、InputStreamReader和OutputStreamWriter
九、DataInputStream 和 DataOutputStream
十、对象流ObjectInputStream和OjbectOutputStream
一、流的分类:
1.操作数据单位:字节流、字符流 2.数据的流向:输入流、输出流 3.流的角色:节点流、处理流
二、流的体系结构
![](https://i-blog.csdnimg.cn/blog_migrate/8e6357e007a0839f4450f936bc0651dc.png)
三、FileReader和FileWriter
从内存中写出数据到硬盘的文件里
说明:
1.输出操作,对应的File可以不存在的。并不会报异常
2.File对应的硬盘中的文件如果不存在:在输出的过程中,会自动创建此文件。
FiLe对应的硬盘中的文件如果存在:
如果流使用的构造器是:Filewriter(file,false) / Filewriter(file):对原有文件进行覆盖
如果流使用的构造器是:Filewriter(file,true):在原有文件的内容基础上执行添加操作
*/
@Test
public void test3() {
FileWriter fw = null;
try {
//1.提供FiLe类的对象,指明写出到的文件
File file = new File("dream");
//2.提供FiLewriter的对象,用于数据的写出
fw = new FileWriter(file, true);
//3.写出的操作
fw.write("I have a dream");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.流资源的关闭
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//3.数据的读入和写出操作
char[] chars = new char[5];
int len;
while ((len = fr.read(chars)) != -1) {
fw.write(chars,0,len);//意思就是写出去len个
}
测试FileInputStream和FileOutputStream的使用结论:
*
* 1.对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
* 2.对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理
*
* @author haiyu
* @create 2022/2/7-11:28
*/
public class FileInputOutputStreamTest {
// 实现对图片的复制
@Test
public void test1(){
FileInputStream fis = null;
FileOutputStream fos =null;
try {
File file = new File("励志.png");
File file1 = new File("励志1.png");
fis = new FileInputStream(file);
fos = new FileOutputStream(file1);
byte[] b = new byte[5];
int len;
while ((len = fis.read(b)) != -1){
fos.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//我们发现都是固定格式的,所以自己定义一个copy()
public void copy(String srcFile,String destFile){//String类型的形参 这里是路径
FileInputStream fis = null;
FileOutputStream fos =null;
try {
File file = new File(srcFile);
File file1 = new File(destFile);
fis = new FileInputStream(file);
fos = new FileOutputStream(file1);
byte[] b = new byte[1024];
int len;
while ((len = fis.read(b)) != -1){
fos.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test2(){
String srcFile = "C:\\Users\\17391\\Desktop\\视频1.mp4";
String destFile = "C:\\Users\\17391\\Desktop\\视频2.mp4";
long start = System.currentTimeMillis();
copy(srcFile,destFile);
System.out.println("复制完成");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));//1327
}
}
四、FileInputStream和FileOutputStream
测试FileInputStream和FileOutputStream的使用结论:
*
* 1.对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
* 2.对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt,...),使用字节流处理
*
* @author haiyu
* @create 2022/2/7-11:28
*/
public class FileInputOutputStreamTest {
// 实现对图片的复制
@Test
public void test1(){
FileInputStream fis = null;
FileOutputStream fos =null;
try {
File file = new File("励志.png");
File file1 = new File("励志1.png");
fis = new FileInputStream(file);
fos = new FileOutputStream(file1);
byte[] b = new byte[5];
int len;
while ((len = fis.read(b)) != -1){
fos.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//我们发现都是固定格式的,所以自己定义一个copy()
public void copy(String srcFile,String destFile){//String类型的形参 这里是路径
FileInputStream fis = null;
FileOutputStream fos =null;
try {
File file = new File(srcFile);
File file1 = new File(destFile);
fis = new FileInputStream(file);
fos = new FileOutputStream(file1);
byte[] b = new byte[1024];
int len;
while ((len = fis.read(b)) != -1){
fos.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test2(){
String srcFile = "C:\\Users\\17391\\Desktop\\视频1.mp4";
String destFile = "C:\\Users\\17391\\Desktop\\视频2.mp4";
long start = System.currentTimeMillis();
copy(srcFile,destFile);
System.out.println("复制完成");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));//1327
}
}
五、BufferedInputStream和BufferedOutputStream(BufferedReader和Bufferedwriter)
处理流之一:缓冲流的使用 * 1.缓冲流: * BufferedInputStream * BufferedOutputStream * BufferedReader * Bufferedwriter * <p> * 2.作用:提供流的读取、写入的速度
public class BufferTest {
@Test
public void test1() {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
File srcFile = new File("励志.png");
File destFile = new File("励志2.png");
fileInputStream = new FileInputStream(srcFile);
fileOutputStream = new FileOutputStream(destFile);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] bytes = new byte[10];
int len;
while ((len = bufferedInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedInputStream != null) {
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
读写操作
// 方式一:
char[] c = new char[5];
int len;
while ((len = br.read(c)) != -1){
bw.write(c,0,len);
}
// 方式二:
String data;
while ((data = br.readLine()) != null){
//方法一:
// bw.write(data+"\n");//不带换行符,自己加一个就好了
//方法二:
bw.write(data);
bw.newLine();
六、InputStreamReader和OutputStreamWriter
1.转换流:属于字符流 * InputStreamReader:将一个字节的输入流转换为字符的输入流 * outputstreamwriter:将一个字符的输出流转换为字节的输出流 * * 2.作用:提供字节流与字符流之间的转换 * * 3.解码:字节、字节数组--->字符数组、字符串 * 编码:字符数组、字符串--->字节、字节数组 * * 4.字符集
/*
InputStreamReader:实现字节输入流到字符输入流的转化
*/
@Test
public void test1(){
InputStreamReader isr = null;
try {
FileInputStream fis = new FileInputStream("dream");
// InputStreamReader isr = new InputStreamReader(fis);
// 参数二表明类字符集,具体使用哪个字符集需要看文件当时按照哪个储存的。
isr = new InputStreamReader(fis,"UTF-8");
char[] c = new char[5];
int len;
while ((len = isr.read(c)) != -1){
String s = new String(c,0,len);
System.out.print(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
综合使用InputStreamReader 和 OutputStreamWriter
代码分析:
hello.txt在源文件中是以utf-8的编码表来储存的,我们这里将他读取在内存中的一个字符串中展示在控制台,
我们还想把读到内存中的字符以gbk的那个编码表存到hello.gbk.txt文件中,所以我们现在用idea的utf-8的编
码表不能正常阅读出hello.gbk.txt文件
*/
@Test
public void test2(){
InputStreamReader isr = null;
OutputStreamWriter osr = null;
try {
FileInputStream fis = new FileInputStream("hello.txt");
FileOutputStream fos = new FileOutputStream("hello.gbk.txt");
isr = new InputStreamReader(fis,"utf-8");
osr = new OutputStreamWriter(fos,"gbk");
char[] c = new char[20];
int len;
while ((len = isr.read(c)) != -1){
String s = new String(c, 0, len);
System.out.print(s);
osr.write(c,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (osr != null){
try {
osr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
七、System.in和System.out
标准的输入、输出流
1.1
System.in:标准的输入流,默认从键盘输入
System.out:标准的输出流,默认从挽制台输出
1.2
System类的setIn(InputStream is) / setOut(printStream ps)方式重新指定输入和输出的流。
1.3练习:
从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
直至当输入“e”或者“exit时,退出程序。
方法一:使用Scanner实现
方法二:使用system. in实现:System.in--->InputStreamReader--->BufferReader的readerLine()
*/
public static void main(String[] args) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("输入字符串");
String s = bufferedReader.readLine();
if ("e".equalsIgnoreCase(s) || "exit".equalsIgnoreCase(s)) {//这里这样写使得程序代码更健壮
System.out.println("结束");
break;
} else {
String s1 = s.toUpperCase();
System.out.println(s1);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
八、PrintStream 和PrintWriter
提供了-系列重载的print()和println()
九、DataInputStream 和 DataOutputStream
作用:用于读取或写出基本数据类型的变量或字符串
*/
// 练习:将内存中的字符串、基本数据类型写出到文件中
@Test
public void test3(){
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new FileOutputStream(new File("hello.txt")));
dos.writeInt(23);
dos.flush();//刷新操作,执行时会把数据写入到文件中 自己不是必须要写,writer都自带的
dos.writeBoolean(true);
dos.flush();
dos.writeUTF("我要15w");
dos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dos !=null){
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 练习:写到文件中的基本数据类型、字符串读取到内存中,保存在一个变量中。
// 注意点: 读取数据类型的顺序要和保存时一致
@Test
public void test4(){
DataInputStream dis = null;
try {
dis = new DataInputStream(new FileInputStream("hello.txt"));
int age = dis.readInt();
boolean isMale = dis.readBoolean();
String aim = dis.readUTF();
System.out.println("age = " + age + ",isMale = "+ isMale + ",aim = " + aim);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dis != null){
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
十、对象流ObjectInputStream和OjbectOutputStream
作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,
* 也能把对象从数据源中还原回来
*
* 要想一个对象满足序列化,有一定的要求:见Person.java
*/
public class ObjectInputStream {
/*
序列化过程:将内存中的java对象保存到磁盘中,或者通过网络的方式传输出去
使用ObjectOutputStream实现
*/
@Test
public void test1() {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new String("我爱人民币"));
oos.flush();
oos.writeObject(new Person(12,"haiyu"));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
反序列化过程:将磁盘文件中的对象还原为内存中的一个java对象。
注意:ObjectInputStream有java.io下的,居然还有java6下的,应该选前者,后者没有read方法。
*/
@Test
public void test2(){
java.io.ObjectInputStream ois = null;
try {
ois = new java.io.ObjectInputStream(new FileInputStream("object.dat"));
Object object = ois.readObject();
String s = (String)object;
Person p = (Person)ois.readObject();//对象的反序列化
System.out.println(s);
System.out.println(p);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Person需要满足如下的要求,方可序列化 *1.需要实现接口:Serializable * 2.需要当前类提供全局常量:serialVersionUID * 3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性 * 也必须是可序列化的。(默认基本数据类型是可以序列化的) * 如果自定义类中一个属性也是自定义类,那么这个属性的类也必须实现Serializable接口,并提供全局常量。 * * 补充: ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。
public class Person implements Serializable {
public static final long serialVersionUID = 416516L;
private int age;
private String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
十一、RandomAccessFiLe的使用
1.RandomAccessFile直接继承于java.Lang.0bject类,实现了DataInput和DataOutput接口 * 2.RandomAccessFiLe既可以作为一个输入流,又可以作为一个输出流 * 3.如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建 * 如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头履盖) * 4.可以通过相关的操作,实现RandomAccessFiLe*插入”数据的效果
方法:seek(int i):把角标调的i位置
@Test
public void test1(){
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile(new File("励志.png"),"r");
raf2 = new RandomAccessFile(new File("励志随机存取文件流.png"),"rw");
byte[] b = new byte[1024];
int len;
while ((len = raf1.read(b)) != -1){
raf2.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (raf2 != null){
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (raf1 != null){
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void test2(){
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(new File("hello.txt"),"rw");
raf.seek(3);//将指针调到角标为3的位置。 这里是英文字母的角标,(因为字母是一个字节,汉字是三个字节)
raf.write("xyz".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (raf != null){
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/*
使用RandomAccessFile实现插入的效果
*/
@Test
public void test3(){
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(new File("hello1.txt"),"rw");
raf.seek(3);
//保存指针后面的所有数据到sb中
StringBuilder sb = new StringBuilder("hello1.txt".length());
byte[] b = new byte[10];
int len;
while ((len = raf.read(b)) != -1){
sb.append(new String(b,0,len));
}
raf.seek(3);
raf.write("xyz".getBytes());
//sb里面的数据再写上。
raf.write(sb.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (raf != null){
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}