IO流基本内容

IO流


1.IO流:存储和读取数据的解决方案

I:input O:output

2.IO流的作用

用于读写数据(本地文件,网络)

3.IO流按照流向可以分类那两种流

输出流:程序->文件

输入流:文件->程序

4.IO流按照操作文件的类型可以分类那两种流?

字节流:可以操作所有类型的文件

字符流:只能操作纯文本文件

5.什么是纯文本文件?

用windows系统自带的记事本打开并且能读懂的文件?

用windows系统自带的记事本打开并且能读懂的文件

txt文件,md文件,xml文件,lrc文件等等

IO流的体系


IO流分为:字节流和字符流

字节流分为:inputStream:字节输入流

outputStream:字节输出流

字符类分为:Reader:字符类输入

Writer:字符输出流

FileOutputStream


FileOutputStream:操作本地文件的字节输出流,可以把程序中的数据写到本地文件中,是字节流的基本流

书写步骤:1.创建字节流对象

2.写数据

3.释放资源

packagecom.cjj.mybytestream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

publicclassByteStreamDemo01 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

FileOutputStream:操作本地文件的字节输出流,可以把程序中的数据写道本地文件中

书写步骤:

1.创建字节流对象

细节1:参数是字符串表示的路径或者是File对象都是可以的

细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径

细节3:如果文件已经存在,则会清空文件

2.写数据

细节1:write方法的是参数,但是实际上写到本地文件夹中的是整数ASCII上的字符

3.释放资源

每次使用完流之后都有释放资源

要求:写出一段文字到本地文件中

*/

//1.创建对象

//写出:输出流OutputStream

//本地文件 File

FileOutputStreamfos=newFileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\mybytestream\\a.txt");

//2.写出数据

fos.write(97);

//3.释放资源

fos.close();

}

}

FileOutputStream写数据的三种方法

方法名称

说明

void write(int b)

一次写一个字节数据

void write(byte[] b)

一次性写一个字节的数组

void write(byte[] b,int off,int len)

一次写一个字节数组的部分数据

packagecom.cjj.mybytestream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

publicclassByteStreamDemo03 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

换行写:

再写出一个换行符就可以了

Windows:\r\n

Linux: \n

Mac: \r

细节:

在windows操作系统中,Java对回车换行进行了优化

虽然完整的是\n\r,但是我们写其中一个\r或者\n

Java也可以实现换行,因为java会在底层补全

不过建议写全

续写:

如果想要续写,打开续写开关即可

开关位置,创建对象的第二个参数

默认false:表示关闭续写,此时创建对象会清空文件

手动传递true:表示打开续写,此时创建对象不会清空文件

*/

//1.创建对象

FileOutputStreamfos=newFileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\mybytestream\\a.txt",true);

//2.写出数据

Stringstr="cjjzuishuai";

byte[] bytes1=str.getBytes();

fos.write(bytes1);

//换行符

Stringwrap="\r\n";

byte[] bytes3=wrap.getBytes();

fos.write(bytes3);

//写出第二个数据

Stringstr2="666";

byte[] bytes2=str2.getBytes();

fos.write(bytes2);

//释放资源

fos.close();

}

}

FileInputStream


FileInputStream:操作本地文件输入流,可以把本地文件中的数据读取到程序中

书写步骤:

1.创建字节流输入对象

2.读取数据

3.释放资源

packagecom.cjj.mybytestream2;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.IOException;

publicclassByteStreamDemo02 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

字节输入流循环读取

*/

//1.创建对象

FileInputStreamfis=newFileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\mybytestream\\a.txt");

//2.循环读取

intb;

while ((b=fis.read()) !=-1) {

System.out.print((char)b);

}

//3.释放资源

fis.close();

}

}

拷贝文件

packagecom.cjj.mybytestream2;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

publicclassByteStreamDemo03 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

/*

文件拷贝

*/

//1。创建对象

FileInputStreamfis=newFileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\mybytestream\\a.txt");

FileOutputStreamfos=newFileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\mybytestream\\b.txt");

//2.拷贝文件

intb;

while (((b=fis.read()) !=-1)) {

fos.write(b);

}

//3.释放资源

fos.close();

fis.close();

}

}

FileInputStream一次读多个字节

方法名称

说明

public int read()

一次度一个字节数据

public int read(byte[] buffer)

一次度一个字节数组数据

一次读一个字节数组的数据,每次读取会尽可能把数组装满

字符集


在计算机中,任意数据都是以二进制的形式存储的

计算机中最小的存储单元是一个字节

ASCII字符集中,一个英文占一个字节

简体中文版Windows,默认使用GBK字符集

GBK字符集完全兼容ASCII字符集

一个英文占一个字节,二进制第一位是0

一个中文占两个字节,二进制高位字节的第一位是1

UTF-8是字符集的一种编码方式

Unicode字符集的UTF-8编码格式

一个英文占一个字节,二进制第一位是0,转成十进制是正数

一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数

如何不产生乱码?

1.不要用字节流读取文本文件

2.编码解码时使用同一个码表,同一个编码方式

Java中编码的方式

String类中的方法

说明

public byte[] getBytes()

使用默认方法进行编码

public byte][] getBytes(String charsetName)

使用指定方式进行编码

Java中的解码的方法

String类中的方法

说明

String(byte[] bytes)

使用默认方式进行解码

String(byte[] bytes,String charsetName)

使用指定方式进行解码

为什么会有乱码?

1.读取数据时未读完整整个汉字

2.编码和解码时的方式不统一

字符流:字符类的底层就是字节流

字符流=字节流+字符集

特点:输入流:一次读一个字节,遇到中文时,一次读多个字节

输出流:底层会把数据按照指定的编码方式进行编码,变成字节在写到文件中

使用场景:对于纯文本进行读写操作

FileReader


FileReader

1.创建字符输入流对象

构造方法

说明

public FileReader(File file)

创建字符输入流关联本地文件

public FileReader(String pathname)

创建字符输入流关联本地文件

2.读取数据

成员方法

说明

public int read()

读取数据,读到末尾返回-1

public int read(char[] buffer)

读取多个数据,读到末尾返回-1

细节1:按字节进行读取,遇到中文,一次读取多个字节,读取后解码,返回一个整数

细节2:读到文件末尾了,read方法返回-1

3.释放资源

关流:close

packagecom.cjj.mycharstream1;

importjava.io.FileNotFoundException;

importjava.io.FileReader;

importjava.io.IOException;

publicclassCharStreamDemo01 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

第一步:创建对象

public FileReader(File file) 创建字符输入流关联本地文件

public FileReader(String pathname)创建字符输入流关联本地文件

第二步:读取数据

public int read() 读取数据,读到末尾返回-1

public int read(char[] buffer)读取多个数据,读到末尾返回-1

第三步:释放资源

close

*/

//1.创建对象并关联本地文件

FileReaderfr=newFileReader("D:\\workplace\\hema\\myio\\src\\com\\cjj\\mybytestream\\a.txt");

char[] len=newchar[2];

/*int b;

while ((b=fr.read(len))!=-1) {

//read(len):读取数据,解码,强转三步合并了,并强转之后的字符放到数组当中

//空参read+强转类型转换

System.out.print(new String(len,0,b));

}*/

intb;

while ((b=fr.read())!=-1) {

//2.读取数据

//字符流的底层也是字节流,默认也是一个字节一个字节的读取的

//如果遇到一个中文就会一次读取多个,GBK一次读两个字节,UTF-8一次读三个字节

//read()细节

//1.read():默认也是一个字节一个字节读取的,如果遇到中文就会一次读取多个

//2.在读取之后,方法的底层还会进行解码并转成十进制

// 最终把这个十进制作为返回值

// 这个十进制的数据也表示在字符集上的数字

System.out.print((char)b);

}

//3.释放资源

fr.close();

}

}

FileWriter


FileWriter构造方法

构造方法

说明

public FileWriter(File file)

创建字符输出流关联本地文件

public FileWriter(String pathname)

创建字符输出流关联本地文件

public FileWriter(File file,boolean append)

创建字符输出流关联本地文件,续写

public FileWriter(String pathname,boolean append)

创建字符输出流关联本地文件,续写

FileWriter成员方法

成员方法

说明

void write(int c)

写出一个字符

void write(String str)

写出一个字符串

void write(String str,int off,int len)

写出一个字符串的一部分

void write(char[] cbuf)

写出一个字符数组

void write(char[] cbuf,int off,int len)

写出字符数组的一部分

FileWriter书写细节

1。创建字符输出流对象

细节1:参数是字符串表示的路径或者File对象都是可以的

细节2:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的

细节3:如果文件已经存在,则会清空文件,如果不像清空可以打开续写开关

2.写数据

细节:如果write方法的参数是整数,但是实际上写到本地文件中的整数在字符集上对应的字符

3.释放资源

细节:每次使用完流之后都要释放资源

字符流原理解析

1.创建字符输入流对象

底层:关联文件,并创建缓冲区(长度为8192的字节数组)

2.读取数据

底层:1.判断缓冲区中是否有数据可以领取

2.缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区

如果文件中也没有数据了,返回-1

3.缓冲区:就从缓冲区中读取

空参的read方法:一次读取一个字节,遇到中文一次读取多个字节,把字节解码并转成十进制返回

有参的read方法:把读取字节,解码,强转三步合并了,强转之后的字符放到数组中

字节缓冲流


方法名称

说明

public BufferedInputStream(InputStream is)

把基本流包装成高级流,提高读取数据的性能

public BufferedOutPutStream(OutputStream)

把基本流包装成高级流,提高写出数据的性能

原理:底层自带了长度为8192的缓冲区提高性能

字符缓冲流构造方法

方法名称

说明

public BufferedReader(Reader r)

把基本流变成高级流

public BufferedWriter(writer r)

把基本流变成高级流

字符缓冲流特有的方法

字符缓冲输入流特有方法

说明

public String readLine()

读取一行数据,如果没有数据可读了,会返回null

字符缓冲输出流特有方法

说明

public void newLine()

跨平台的换行

总结:

缓冲流有几种

字节缓冲输入流:BufferedInputStream

字节缓冲输出流:BufferedOutputStream

字符缓冲输入流:BufferedReader

字符缓冲输出流:BufferedWriter

缓冲流为什么能提高性能?

缓冲流自带长度为8192的缓冲区

可以显著提高字节流的读写性能

对于字符流提升不明显,对于字符缓冲流而言关键点是两个特有的方法

字符缓冲流两个特有方法是什么?

字符缓冲输入流:BufferedReader:readLine()

字符缓冲输出流:BufferWriter:newLine()

转换流


转换流:是字符流和字节流之间的桥梁

作用:字节流想要使用字符流中的方法

packagecom.cjj.myconvertstream;

importjava.io.*;

importjava.nio.charset.Charset;

publicclassConverStreamDemo01 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

利用转换流按照字符编码读取(了解)

*/

/*//1.创建对象并指定字符编码

InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt"), "UTF-8");

//2.读取数据

int ch;

while ((ch = isr.read()) != -1) {

System.out.print((char) ch);

}

isr.close();*/

FileReaderfr=newFileReader("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt", Charset.forName("UTF-8"));

//2.读取数据

intb;

while((b=fr.read())!=-1){

System.out.print((char)b);

}

}

}

packagecom.cjj.myconvertstream;

importjava.io.FileOutputStream;

importjava.io.FileWriter;

importjava.io.IOException;

importjava.io.OutputStreamWriter;

importjava.nio.charset.Charset;

publicclassConverStreamDemo02 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

利用转换流按照指定字符编码写出

*/

/*//1.创建转换流的对象

OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt"),"UTF-8");

//2.写出数据

osw.write("岳飞");

//3.释放资源

osw.close();*/

FileWriterfw=newFileWriter("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt", Charset.forName("UTF-8"));

fw.write("满江红\n"+

"怒发冲冠,凭阑处、潇潇雨歇。\n"+

"抬望眼,仰天长啸,壮怀激烈。\n"+

"三十功名尘与土,八千里路云和月。\n"+

"莫等闲、白了少年头,空悲切。\n"+

"靖康耻,犹未雪。\n"+

"臣子恨,何时灭。\n"+

"驾长车,踏破贺兰山缺。\n"+

"壮志饥餐胡虏肉,笑谈渴饮匈奴血。\n"+

"待从头、收拾旧山河,朝天阙。");

fw.close();

}

}

packagecom.cjj.myconvertstream;

importjava.io.FileReader;

importjava.io.FileWriter;

importjava.io.IOException;

importjava.nio.charset.Charset;

publicclassConverStreamDemo03 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

*/

//1.创建转换流对象

FileReaderfr=newFileReader("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt", Charset.forName("UTF-8"));

FileWriterfw=newFileWriter("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt",Charset.forName("UTF-8"));

intb;

while((b=fr.read())!=-1){

fw.write(b);

}

fw.close();

fr.close();

}

}

package com.cjj.myconvertstream;

import java.io.*;

public class ConverStreamDemo04 {

public static void main(String[] args) throws IOException {

/*

利用字节流读取文件中的数据,每次读取一整行,而且不能出现乱码

//1.字节流在读取中文的时候,是会出现乱码的,但是字符流可以搞定

//2.字节流里面是没有读取一整行的方法的,只有字符缓冲流才能搞定

*/

/*FileInputStream fis = new FileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt");

InputStreamReader isr = new InputStreamReader(fis);

BufferedReader br = new BufferedReader(isr);

String str = br.readLine();

System.out.println(str);

br.close();*/

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myconvertstream\\gbkfile.txt")));

String str = br.readLine();

System.out.println(str);

br.close();

}

}

总结:

1.转换流的名字是什么?

字符转换输入流:InputStreamReader

字符转换输出流:OutputStreamWriter

2.转换流的作用是什么?

指定字符集读写数据(JDK11之后以淘汰)

字节流想要使用字符流中的方法

序列化流/对象操作输出流


可以把java中的对象写到本地文件中

构造方法

说明

public ObjectOutputStream(OutputStream out)

把基本流包装成高级流

成员方法

说明

public final void writeObject(Object obj)

把对象序列化(写出)到文件中去

使用对象输出流将对象保存到文件时会出现NotSerializableException异常

解决方案:需要让Javabean类实现Serializable接口

packagecom.cjj.myobjectstream;

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.io.ObjectOutputStream;

publicclassObjectStreamDemo01 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

需求:

利用序列化流/对象操作输出流,把一个对象写道本地文件中

构造方法

public ObjectOutputStream(OutputStream out)把基本流包装成高级流

成员方法

public final void writeObject(Object obj)把对象序列化(写出)到文件中去

*/

//1.创建对象

Students1=newStudent("zhangsan",15);

//2.创建序列号流对象

ObjectOutputStreamos=newObjectOutputStream(newFileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myobjectstream\\c.txt"));

//3.写出数据

os.writeObject(s1);

//4.释放资源

os.close();

}

}

package com.cjj.myobjectstream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.ObjectInputStream;

public class ObjectStreamDemo02 {

public static void main(String[] args) throws IOException, ClassNotFoundException {

/*

反序列化流读取对象

*/

//1.创建反序列流对象

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myobjectstream\\c.txt"));

Object o = ois.readObject();

System.out.println(o);

ois.close();

}

}

private static final long serialVersionUID = -1398385231815634338L;//添加版本号

//transient:瞬态关键字

//作用:不会把当前属性序列号到本地文件当中

private transient String address;

序列化细节汇总

1.使用序列化流将对象写到文件时,需要让javabean类实现Serializable接口

否则,会出现NotSerializableException异常

2.序列化流写道文件中的数据是不能修改的,一旦修改就无法再次读回来了

3.序列化对象后,修改了Javabean类,再次反序列化,会不会有问题?

会出现问题,会抛出InvalidClassException异常

解决方法:给javabean类添加serialVersionUID(序列号,版本号)

4.如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?

解决方法:给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程

packagecom.cjj.myobjectstream;

importjava.io.*;

importjava.util.ArrayList;

importjava.util.Collections;

publicclassTest01 {

publicstaticvoidmain(String[] args) throwsIOException, ClassNotFoundException {

/*

需求:

将多个自定义对象序列化到文件中,但是对象个数不确定,该如何操作呢

*/

//1.序列化多个对象

Student s1=newStudent("zhangsan",19,"南京");

Student s2=newStudent("lisi",18,"上海");

Student s3=newStudent("wangwu",18,"北京");

ArrayList<Student>list=newArrayList<>();

Collections.addAll(list,s1,s2,s3);

//2.创建序列化对象

ObjectOutputStreamoos=newObjectOutputStream(newFileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myobjectstream\\c.txt"));

oos.writeObject(list);

oos.close();

//3.读取

ObjectInputStreamois=newObjectInputStream(newFileInputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myobjectstream\\c.txt"));

Objecto=ois.readObject();

System.out.println(o);

ois.close();

}

}

打印流


分类:打印流一般是指:PrintStream,PrintWrite两个类

特点1:打印流只操作文件的目的地

特点2:特有的写出方法可以实现,数据原样写出

特点3:特有是的写出方法,可以实现自动刷新,自动换行

打印一次数据=写出+换行+刷新

字节打印流

构造方法

说明

public PrintStream(OutputStream/File/String)

关联字节输出流/文件/文件路径

public PrintStream(String fileName,Charset charset)

指定字符编码

public PrintStream(OutputStream out,boolean autoFlush)

自动刷新

public PrintStream(OutputStream out,boolean autoFlush,String enconding)

指定字符编码且自动刷新

字节流底层没有缓冲区,开不开自动刷新都一样

成员方法

说明

public void write(int b)

常规方法:规则跟之前的一样,将指定的字节写出

public void println(Xxx xx)

特有方法:打印任意数据,自动刷新,自动换行

public void print(Xxx xx)

特有方法:打印任意数据,不换行

public void printf(String format,Object...args)

特有方法:带有占位符的打印语句,不换行

packagecom.cjj.myprintstream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.PrintStream;

importjava.io.UnsupportedEncodingException;

publicclassPrintStreamDemo01 {

publicstaticvoidmain(String[] args) throwsFileNotFoundException, UnsupportedEncodingException {

/*

字节打印流

构造方法

public PrintStream(OutputStream/File/String)关联字节输出流/文件/文件路径

public PrintStream(String fileName,Charset charset)指定字符编码

public PrintStream(OutputStream out,boolean autoFlush)自动刷新

public PrintStream(OutputStream out,boolean autoFlush,String enconding)指定字符编码且自动刷新

成员方法

public void write(int b)常规方法:规则跟之前的一样,将指定的字节写出

public void println(Xxx xx)特有方法:打印任意数据,自动刷新,自动换行

public void print(Xxx xx)特有方法:打印任意数据,不换行

public void printf(String format,Object...args)特有方法:带有占位符的打印语句,不换行

*/

//1.创建字节打印流对象

PrintStreamps=newPrintStream(newFileOutputStream("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myprintstream\\a.txt"),true,"UTF-8");

//2.写出数据

ps.println(97);

ps.println(true);

ps.printf("%s爱上了%s","阿珍","阿强");

//3.释放资源

ps.close();

}

}

字符打印流

字符流底层有缓冲区,想要自动刷新需要开启

构造方法

说明

public PrintWriter(Write/File/String)

关联字节输出流

public PrintWriter(String filename,Charset charset)

指定字符编码

public PrintWriter(Write w,boolean autoFlush)

自动刷新

public PrintWriter(OutputStream out,boolean autoFlush,Charset charset)

指定字符编码且自动刷新

成员方法

说明

public void write(...)

常规方法:规则跟之前的一样,写出字节或字符串

public void println(Xxx xx)

特有方法:打印任意类型的数据并且不换行

public void print(Xxx xx)

特有方法:打印任意类型的数据,不换行

public void printf(String format,Object...args)

特有方法:带有占位符的打印语句

package com.cjj.myprintstream;

import java.io.PrintStream;

public class PrintStreamDemo02 {

public static void main(String[] args) {

/*

打印流的应用场景

*/

System.out.println("123");

//获取打印流的对象,此打印流在虚拟机启动的时候,由虚拟机创建,默认指向控制台

//特殊的打印流。系统中的标准输出流,是不能关闭的,在系统中是唯一的

PrintStream ps = System.out;

//调用打印流中的方法println

//写出数据,自动换行,自动刷新

ps.println("123");

}

}

总结:

1.打印流有几种?各有什么特点?

有字节打印流和字符打印流两种

打印流不操作数据源,只能操作目的地

字节打印流:默认自动刷新,特有的println自动换行

字符打印流:自动刷新需要开启,特有的println自动换行

解压缩流/压缩流


解压本质:把每一个ZipEntry按照层级拷贝到本地另一个文件夹中

解压

packagecom.cjj.myzipstream;

importjava.io.*;

importjava.util.zip.ZipEntry;

importjava.util.zip.ZipInputStream;

publicclassZipStreamDemo01 {

publicstaticvoidmain(String[] args) {

//1.创建一个File表示要解压的压缩包

Filesrc=newFile("D:\\aaa.zip");

//2.创建一个File表示解压的目的地

Filedest=newFile("D:\\");

}

//定义一个方法用来解压

publicstaticvoidunzip(Filesrc, Filedest) throwsIOException {

//解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地当中

//创建一个解压缩流用来读取压缩包中的数据

ZipInputStreamzip=newZipInputStream(newFileInputStream(src));

//要先获取到压缩包里面的每一个zipentry对象

ZipEntryentry;

while ((entry=zip.getNextEntry()) !=null) {

System.out.println(entry);

//文件夹:需要在目的地dest处创建一个同样的文件夹

//文件:需要读取到压缩包中的文件,并把它存放到目的地dest文件夹中(按照层级目录进行存放)

if (entry.isDirectory()) {

//文件夹,需要在目的地dest处创建一个同样的文件夹

Filefile=newFile(dest, entry.toString());

file.mkdirs();

} else {

//文件:需要读取到压缩包中的文件,并把它存放到目的地dest文件夹中(按照层级目录进行存放)

FileOutputStreamfos=newFileOutputStream(newFile(dest, entry.toString()));

intb;

while ((b=zip.read()) !=-1) {

//写到目的地

fos.write(b);

fos.close();

}

}

zip.closeEntry();

}

zip.close();

}

}

压缩

压缩本质:把每一个(文件/文件夹)看成ZipEntry对象放到压缩包中

//压缩文件

packagecom.cjj.myzipstream;

importjava.io.*;

importjava.util.zip.ZipEntry;

importjava.util.zip.ZipInputStream;

importjava.util.zip.ZipOutputStream;

publicclassZipStreamDemo02 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

压缩流

需求:把D:\\a.txt打包成一个压缩包

*/

//1.创建File对象表示要压缩的文件

Filefile=newFile("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myzipstream\\a.txt");

//2.创建对象来表示压缩包的位置

Filedest=newFile("D:\\workplace\\hema\\myio\\src\\com\\cjj\\myzipstream\\");

//3.调用方法来压缩

toZip(file,dest);

}

publicstaticvoidtoZip(Filefile,Filedest) throwsIOException {

/*

作用:压缩

参数1:表示要压缩的文件

参数2:表示压缩包的位置

*/

//1.创建压缩流关联压缩包

ZipOutputStreamzos=newZipOutputStream(newFileOutputStream(newFile(dest,"a.zip")));

//2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹

ZipEntryentry=newZipEntry("a.txt");

//3.把entry对象放到压缩包

zos.putNextEntry(entry);

//4.把file文件中的数据写入压缩包

FileInputStreamfis=newFileInputStream(file);

intb;

while((b=fis.read())!=-1){

zos.write(b);

}

fis.close();

zos.closeEntry();

zos.close();

}

}

//压缩文件夹

packagecom.cjj.myzipstream;

importjava.io.*;

importjava.util.zip.ZipEntry;

importjava.util.zip.ZipOutputStream;

publicclassZipStreamDemo03 {

publicstaticvoidmain(String[] args) throwsIOException {

/*

压缩流

需求:把D:\\aaa文件夹压缩成一个压缩包

*/

//1.创建File对象表示要压缩的文件夹

Filesrc=newFile("D:\\aaa");

//2.创建File对象表示压缩包放在哪里(压缩包的父级路径)

FiledestParent=src.getParentFile();

//3.创建一个File对象表示压缩包路径

Filedest=newFile(destParent, src.getName() +".zip");

//4.创建压缩流关联压缩包

ZipOutputStreamzos=newZipOutputStream(newFileOutputStream(dest));

//5.获取src里面的每一个文件夹,变成zipEntry对象,放入到压缩包中

toZip(src, zos, src.getName());

//6.释放资源

zos.close();

}

publicstaticvoidtoZip(Filesrc, ZipOutputStreamzos, Stringname) throwsIOException {

/*

作用:获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包中

参数1:数据源

参数2:压缩流

参数3:压缩包内部的路径

*/

//1.进入src文件夹

File[] files=src.listFiles();

//2.遍历数组

for (Filefile : files) {

if (file.isFile()) {

//3.判断-文件,变成ZipEntry对象,放入到压缩包中

ZipEntryentry=newZipEntry(name+"\\"+file.getName());

zos.putNextEntry(entry);

//读取文件中的数据,写到压缩包

FileInputStreamfis=newFileInputStream(file);

intb;

while ((b=fis.read()) !=-1) {

zos.write(b);

}

fis.close();

zos.closeEntry();

} else {

//4.判断-文件夹,递归

toZip(file, zos, name+"\\"+file.getName());

}

}

}

}

Commons-io


Commons-io是apache开源基金组织提供的一组有关IO操作的开源工具包

作用:提高IO流的开发效率

Apache:专门为支持开源软件项目而办的一个非盈利性组织

使用步骤:

1.在项目中创建一个文件夹:lib

2.将jar包复制粘贴到lib文件夹

3.右键点击jar包,选择Add as Library->点击OK

4.在类中导包使用

FileUtils类(文件/文件夹相关)

说明

static void copyFile(File srcFile,File destFile)

复制文件

static void copyDirectory(File srcDir,File destDir)

复制文件夹

static void copyDirectoryToDirectory(File srcDir,File destDir)

复制文件夹

static void deleteDirectory(File directory)

删除文件夹

static void cleanDirectory(File directory)

清空文件夹

static String readFileToString(File file,Charset encoding)

读取文件中的数据变成字符串

static void write(File file,CharSequence data,String encoding)

写出数据

IOUtils类(流相关相关)

说明

public static int copy(InputStream input,OutputStream output)

复制文件

public static int copyLarge(Reader input,Writer output)

复制大文件夹

public static String readLines(Reader input)

读取数据

public static void write(String data,OutputStream output)

写出数据

Hutool工具包


相关类

说明

IOUtil

流操作工具类

FileUtil

文件读写和操作的工具类

FileTypeUtil

文件类型判断工具类

WatchMonitor

目录,文件监听

ClassPathResource

针对ClassPath中资源的访问封装

FileReader

封装文件读取

FileWriter

封装文件写入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼古拉斯安泽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值