IO流
开局一张图,内容详情请往下观看。
字节流:
OutputStream/InputStream类:
OutputStream类常用方法:
InputStream类构造方法:
InputStream类常用方法:
文件相关流:
循环读取某个磁盘路径下的所有数据:FileinputStream
public class FileinputStreamTest{
public static void mian (String [] arg){
try(//文件输入流
InputStream in = new FileinputStream("xxx.txt");
){
byte[] data = new byte[1024];
int length=0;
StringBuffer sb = new StringBuffer(5000);
//in.read(data);从磁盘中读取数据,读取的结果存储到data
//length:存储data数组的数据大小
while((length=in.read(data))!=-1){
String str = new String(data, 0 ,length);
sb.append(str);
}
System.out.println(sb.toString());
}
catch (Exception e) {
//err打印错误的信息,err通常在catch块中使用
System.err.println("从磁盘读取数据失败");
e.printStackTrace();
}
}
}
程序中的数据写入到磁盘: FileOutputStream
FileOutputStream的构造方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sHnPJU5b-1571386959751)(C:\Users\秋哥\Desktop\我的笔记\java\图片6.png)]
//FileOutputStream 磁盘相关的输出管道,能够将内存中的数据写入到磁盘中
public class TestFileOutputStream {
public static void main(String[] args) {
//要写入磁盘的数据
String str="Tomson";
try(
//参数1:磁盘路径
//参数2:true在原有数据的基础上追加数据,false覆盖之前的数据
OutputStream output = new FileOutputStream("abc.txt",true);
) {
//str.getBytes() 将字符串转换为byte[]
output.write(str.getBytes());
//强制性将管道数据刷新到目的地(abc.txt)
output.flush();
} catch (Exception e) {
System.err.println("写入磁盘失败");
e.printStackTrace();
}
}
}
字节缓冲流:
字节输入缓冲流BufferedInputStream:
作为装饰流,去装饰基础流FileInputStream,内部有一个缓冲区,该缓冲区默认大小 byte[] 8192 bytes。
BufferedInputStream的构造方法:
使用缓冲流读取数据:
public class BufferedInputStream{
public class void mian(String[] arg){
try(
InputStream in = new FileInputStream();
bufferedInputStream input = new bufferedInputStream(in);
){
StringBuffer sb = new StringBuffer();
int length=0;
byte[] data = new byte[1024];
while((length=input.read(data))!=-1){
String str = new String(data,0,length);
sb.append(str);
}
System.out.println(sb.toString());
}
catch(Exception e) {
System.err.println("读取失败");
e.printStackTrace();
}
}
}
字节输出缓冲流:BufferedOutputStream
文件的拷贝:
/**
* 拷贝文件
* 1 定义输入管道FileInputStream
* 2 定义缓冲区的输入管道BufferedInputStream,将基础流FileInputStream(管道)注入到装饰流BufferedInputStream(管道)
* 3 定义输出管道FileOutputStream
* 4 定义缓冲区的输出管道BufferedOutputStream,将基础流FileOutputStream(管道)注入到装饰流BufferedOutputStream(管道)
* 5 定义一个带有缓冲区的数组byte [] data
* 6 定义一个int类型的变量,用来存储每次读取的大小
* 7 使用带有缓冲区的输入管道BufferedInputStream读取磁盘数据
* 8 同时使用带有缓冲区的输出管道BufferedOutputStream,将读取的数据写入目的磁盘
* 9 强制刷新缓冲区的数据到磁盘 flush()
*/
public class TestCopy2 {
public static void main(String[] args) {
try {
copy("j0812.txt", "j0812_bak.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 文件的拷贝
* @param srcPath 原始路径
* @param destPath 拷贝的目的路径
* @throws Exception
*/
public static void copy(String srcPath,String destPath)throws Exception{
//try 只负责关闭资源,不负责处理异常
try(
//输出管道
BufferedOutputStream output =
new BufferedOutputStream(
new FileOutputStream(destPath));
//输入管道
BufferedInputStream input =
new BufferedInputStream(
new FileInputStream(srcPath));
){
byte [] data = new byte[1024];
int length =0;
while((length=input.read(data))!=-1) {
output.write(data, 0, length);
}
output.flush();
}
}
}
字符流:
FileReader/FileWriter:
Reader:字符输入流的根,也是一个抽象类。
FileReader:磁盘字符输入流。
Writer:字符输出流,也是一个抽象类。
FileWriter:磁盘字符输出流。
文件拷贝
public class IOUtils {
public static void copy(String srcPath,String destPath)throws Exception{
try(//创建字符流的输入管道
FileReader fr = new FileReader(srcPath);
//创建字符流的输出管道
FileWriter fw = new FileWriter(destPath);
){
//定义char数组,接受读取的数据
char [] data = new char[1024];
//定义一个int类型的变量length存储每次读取的长度
int length = 0;
//用输入流从原始路径读取数据,将读取的结果使用输出流写入到目的路径
while((length=fr.read(data))!=-1) {
fw.write(data, 0, length);
}
//刷新管道的数据到目的路径
fw.flush();
}
}
}
缓冲流:
BufferedReader/BufferedWriter:
BufferedReader:带有缓冲区的输入字符流( char [] data=new char[8192])。
BufferedWriter:带有缓冲区的输出字符流( char [] data=new char[8192])。
转换流:
InputStreamReader/OutputStreamWriter:
InputStreamReader是Reader的子类,将输入的字节流变为字符流,即:将一个字节流的输入对象变为字符流的输入对象。
OutputStreamWriter是Writer的子类,将输出的字符流变为字节流,即:将一个字符流的输出对象变为字节流的输出对象。
文件拷贝:
public static void copy2(String srcPath,String destPath)throws Exception{
try(//创建输入管道BufferedReader
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream(srcPath)));
//创建输出管道BufferedWriter
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(destPath)));
){
//存储每次读取的数据
String line = null;
//没有到达末尾的情况下读取数据,每次读取一行
//读取结果为null,表示到达文件末尾,停止读取
while(null != (line=br.readLine())) {
//读取的结果使用输出管道写入目的路径
bw.write(line);
//换行
bw.newLine();
}
//强制刷新缓冲区数据
bw.flush();
}
}
网络下载资源
内存流
ByteArrayOutputStream/ByteArrayInputStream:
ByteArrayOutputStream字节数组输出流在内存中创建一个byte数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中。
ByteArrayInputStream字节数组输入流就是把一个字节数组 byte[] 包装了一下,使其具有流的属性,可顺序读下去,还可标记跳回来继续读,主要的作用就是用来读取字节数组中的数据。
public class DownResourceTwo {
/**
* 从网络下载资源到内存中
*/
public static byte[] fromNetworkDownResource(String urlPath)throws Exception{
URL url = new URL(urlPath);
try(
//openStream()打开URL的输入流
InputStream input = url.openStream();
BufferedInputStream in = new BufferedInputStream(input);
//创建内存流对象,存储网络资源的数据
ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
){
byte [] data = new byte[1024];
int length = 0;
//读取网路资源,将网络资源写入内存流
while((length= input.read(data))!=-1) {
output.write(data, 0, length);
}
output.flush();
//将内存流的数据返回
return output.toByteArray();
}
}
/**
* 将内存中的数据写入本地磁盘
* */
public static void save2Disk(byte[]data,String destPath)throws Exception {
try(//创建输出管道FileOutputStream
FileOutputStream output =new FileOutputStream(destPath);
){
//调用write(byte)方法写入数据
output.write(data);
//强制刷新管道的数据到磁盘
output.flush();
}
}
/**
* 下载资源
* 1 网络的数据下载到内存中
* 2 将内存的数据写入磁盘
* @param path 网络资源对应的URL
* @throws Exception
*/
public static void downResource(String path)throws Exception{
//data:网络的数据
byte [] data = fromNetworkDownResource(path);
//获取url后缀名称的索引下标
int index = path.lastIndexOf(".");
//当前系统时间作为前缀
long currentTime = System.currentTimeMillis();
//目的路径
String destPath = currentTime+path.substring(index);
//保存到磁盘
save2Disk(data, destPath);
}
public static void main(String[] args) {
String path = "https://www.baidu.com/img/bd_logo1.png";
try {
downResource(path);
} catch (Exception e) {
e.printStackTrace();
}
}
}
对象的序列化和反序列化
对象流
ObjectInputStream/ObjectOutputStream
读写对象
对象流的使用场合实例:
定义一个User类[id,userName,password, nickName, age],创建User类型的对象,将其序列化到磁盘中。
//参与序列化的类型必须实现Serializable接口
public class User implements Serializable {
private static final long serialVersionUID = -4077631708943582472L;
private int id;
private String userName;
private String password;
private String nickName;
private int age;
...
}
序列化:
public class TestSerializable {
public static void main(String[] args) {
User tomson = new User(101,"Tomson", "`12qwe","Tomson", 18);
try {
writeObject(tomson, "tomson");
} catch (Exception e) {
System.err.println("序列化失败");
e.printStackTrace();
}
}
/**
* 对象序列化
* @param <T> 该方法支持泛型
* @param type 传入该方法的对象类型可以是任意的类型
* @param path 序列化到本地磁盘的路径
*/
public static <T> void writeObject(T type ,String path) throws Exception{
try(
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(path));
){
//NotSerializableException:不能序列化异常
output.writeObject(type);
}
}
}
反序列化:
public class TestSerializable {
public static void main(String[] args) {
try {
User user = readObject("tomson");
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反序列化:磁盘的对象读取到内存中
* @param <T> 支持泛型
* @param path 磁盘中需要反序列化对象的路径
* @return 磁盘对象到内存
* @throws Exception 反序列化失败
* 步骤:1定义一个ObjectInputStream作为反序列化对象
* 2调用 ObjectInputStream的readObject()方法反序列化
* 将磁盘中的对象读取到内存中
* @SuppressWarnings("unchecked") 不检查警告
*/
@SuppressWarnings("unchecked")
public static <T> T readObject(String path)throws Exception{
try(
ObjectInputStream input = new ObjectInputStream(
new FileInputStream(path));
){
return (T) input.readObject();
}
}
}
序列化 : 内存----->磁盘 反序列化:磁盘---->内存
eam作为反序列化对象
* 2调用 ObjectInputStream的readObject()方法反序列化
* 将磁盘中的对象读取到内存中
* @SuppressWarnings(“unchecked”) 不检查警告
*/
@SuppressWarnings(“unchecked”)
public static T readObject(String path)throws Exception{
try(
ObjectInputStream input = new ObjectInputStream(
new FileInputStream(path));
){
return (T) input.readObject();
}
}
}
序列化 : 内存----->磁盘 反序列化:磁盘---->内存