JAVA IO流小结
之前一直对JavaIO不太熟悉,在这里做个小结
Java是以流的方式抽象表示不同的输入、输出源。按流的流向分,可以分为输入流和输出流;按操作的数据单元分,可以分为字节流和字符流。
Java的IO流主要有以下四种抽象基类,无法直接创建实例
向文件中写入数据:
写入数据的原理(内存–>硬盘):
Java程序–>JVM–>OS–>OS调用写数据的方法–>把数据写入到文件中
向文件中写入数据一般常用FileOutputStream和FileWriter
FileOutputStream:文件字节输出流,继承了InputStream
使用步骤:
1、创建一个FileOutputStream对象,构造方法中传入写入数据的目的地
2、调用FileOutputStream对象中的方法write,将数据写入到文件中
3、释放资源
FileOutputStream的构造方法
write方法的用法如下:
//使用字节输出流
public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("E:\\java_repository\\123.txt");
String a="你好";
fos.write(a.getBytes());
fos.close();
}
FileWriter:文件字符输出流,继承了Writer
使用步骤:
1、创建FileWriter对象,构造方法中绑定要写入数据的目的地
2、使用FileWriter中的方法write,将数据写入到内存缓冲区中(把字节转换成字符)
3、使用FileWriter中的方法flush,把内存缓冲区的数据刷新到文件中
4、释放资源
write方法:
public static void main(String[] args) throws IOException
{
FileWriter fileWriter=new FileWriter("E:\\java_repository\\a.txt");
fileWriter.write("你好");
fileWriter.flush();
fileWriter.close();
}
flush和close的区别:
flush:刷新缓冲区,流对象可以继续使用
close:刷新缓冲区,再通知系统释放资源,流对象不能再使用了
从文件中读取数据
读取数据的原理(硬盘–>内存):
Java程序–>JVM–>OS–>OS读取数据的方法–>读取文件
从文件中读取数据一般常用FileInputStream和FileReader
FileInputStream:文件字节输入流,继承InputStream
使用步骤:
1、创建FileInputStream对象,构造方法中绑定要读取数据的目的地
2、使用FileWriter中的方法read,读取文件
3、释放资源
构造方法:
read方法:读取到文件的末尾返回-1
//一次读一个字节
private static void input1() throws IOException {
FileInputStream fileInputStream=new FileInputStream("E:\\java_repository\\a.txt");
int len=0;//记录读取到的字节
while((len=fileInputStream.read())!=-1)
System.out.println(len);
fileInputStream.close();
}
//一次读多个字节
private static void input2() throws IOException {
FileInputStream fileInputStream=new FileInputStream("E:\\java_repository\\a.txt");
byte[] b=new byte[100];
int len=fileInputStream.read(b);//从输入流读取一定量的字节,储存在缓存区数组b中
System.out.println(new String(b));
fileInputStream.close();
}
得到了文件中的字节数据,是以二进制码的形式表示的
FileReader:文件字符输入流,继承InputStreamReader和Reader
使用步骤:
1、创建FileReader对象,构造方法中绑定要读取数据的目的地
2、使用FileReader中的方法read,读取文件
3、释放资源
public static void main(String[] args) throws IOException {
FileReader fileReader=new FileReader("E:\\java_repository\\c.txt");
char[] c=new char[100];
fileReader.read(c);
System.out.println(new String(c));
fileReader.close();
}
普通IO流的效率
由于普通IO流需要反复对硬盘进行读取、写入,每次只操作一个字节,效率是比较低的
public static void main(String[] args) throws IOException {
long start=System.currentTimeMillis();
FileOutputStream fos=new FileOutputStream("E:\\java_repository\\2.jpg");
FileInputStream fis=new FileInputStream("E:\\java_repository\\1.jpg");
int len=0;
while((len=fis.read())!=-1)
{
fos.write(len);
}
fos.close();
fis.close();
long end=System.currentTimeMillis();
System.out.println("普通流复制时间:"+(end-start)+"ms");
}
复制一个800多K的图片需要花费12s
如果使用数组作为缓存区,一次存储多个字节、可以大大提高效率
private static void copy2() throws IOException {
long start=System.currentTimeMillis();
FileOutputStream fos=new FileOutputStream("E:\\java_repository\\2.jpg");
FileInputStream fis=new FileInputStream("E:\\java_repository\\1.jpg");
int len=0;
byte[] b=new byte[1024];
while((len=fis.read(b))!=-1)
{
fos.write(b,0,len);
}
fos.close();
fis.close();
long end=System.currentTimeMillis();
System.out.println("普通流复制时间:"+(end-start)+"ms");
}
缓冲流
Java还提供了缓冲流来减少系统IO次数,提高读写的效率
字节缓冲流:BufferedInputStream 、BufferedOutputStream
字符缓冲流:BufferedReader、BufferedWriter
原理:给基本的字节输入、输出流增加一个内置的缓冲区(数组),提高读写效率
字节缓冲输出流:
public static void output1() throws IOException {
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("E:\\java_repository\\c.txt"));
String a="你好";
bufferedOutputStream.write(a.getBytes());
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
字节缓冲输入流:
public static void input01() throws IOException {
BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("E:\\java_repository\\c.txt"));
int len=0;
while((len=bufferedInputStream.read())!=-1)
System.out.println(len);
bufferedInputStream.close();
}
public static void input02() throws IOException {
BufferedReader bufferedReader=new BufferedReader(new FileReader("E:\\java_repository\\123.txt"));
char[] c=new char[100];
bufferedReader.read(c);
System.out.println(c);
bufferedReader.close();
}
现在再使用缓冲流对文件进行复制操作,可以发现读写效率得到很大提升
//一次读取一个字节
private static void copy4() throws IOException {
long start=System.currentTimeMillis();
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("E:\\java_repository\\2.jpg"));
BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("E:\\java_repository\\1.jpg"));
int len=0;
while((len=bufferedInputStream.read())!=-1)
{
bufferedOutputStream.write(len);
}
bufferedInputStream.close();
bufferedOutputStream.close();
long end=System.currentTimeMillis();
System.out.println("缓冲流复制时间:"+(end-start)+"ms");
}
//一次读取多个字节
private static void copy3() throws IOException {
long start=System.currentTimeMillis();
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream("E:\\java_repository\\2.jpg"));
BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream("E:\\java_repository\\1.jpg"));
int len=0;
byte[] b=new byte[1024];
while((len=bufferedInputStream.read(b))!=-1)
{
bufferedOutputStream.write(b,0,len);
}
bufferedInputStream.close();
bufferedOutputStream.close();
long end=System.currentTimeMillis();
System.out.println("缓冲流复制时间:"+(end-start)+"ms");
}
对象的序列化
对象的序列化就是把对象以流的形式,写入到文件中保存
对象的序列化流:ObjectOutputStream
对象的反序列化
把文件中保存的对象,以流的形式读取出来
对象的反序列化流:ObjectIntputStream
一个对象要想实现序列化的条件:
1、该类必须实现Serializable接口
2、该类的所有属性必须是可序列化的,如果一个属性不需要可序列化,该对象必须注明是瞬态的,使用transient关键字
示例:
package io;
import java.io.*;
public class IoObjectStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
output();
input();
}
private static void input() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("E:\\java_repository\\e.txt"));
Object o=objectInputStream.readObject();
objectInputStream.close();
System.out.println(o);
}
private static void output() throws IOException {
FileOutputStream fileOutputStream=new FileOutputStream("E:\\java_repository\\e.txt");
ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(new Person("张三",23));
objectOutputStream.close();
}
}
问题:
每次修改类,都会给该类生成新的***,导致InvalidClassException
解决方法:
手动给该类增加***
static final long serialVersionUID=42L;
上一篇: 拼多多平台里双方无法协商一致时用户怎样去投诉商家呢?
下一篇: Redis持久化与主从复制的实践