一、解压缩流
1、应用场景
-
文件、数据过大,可以先进行压缩然后再传输。
-
当接收到压缩包,先进行解压缩,这样就可以使用里面的所有文件、数据了。
2、解压缩流
- 压缩包里面的每一个文件在Java中都是一个
ZipEntry
对象。 - 解压本质:把压缩包里面的每一个
ZipEntry
对象按照层级拷贝到本地另一个文件夹中。
package com.app.demo37_io_zipstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/*
解压缩流:java实现解压zip格式的压缩包
*/
public class Demo1 {
public static void main(String[] args) throws IOException {
// 1.创建File对象src,表示要解压的压缩包
File src = new File("E:\\aaa.zip");
// 2.创建File对象dest,表示解压后的数据的去处
File dest = new File("E:\\");
// 3.解压
unzip(src, dest);
}
/**
* 解压zip格式的压缩包
*
* @param src 数据源:要解压的数据
* @param dest 目的地:解压后数据的去处
*/
public static void unzip(File src, File dest) throws IOException {
// 解压本质:把压缩包里面的每一个文件或文件夹读取出来,按照层级拷贝到目的地当中
// 0.先判断当前要解压的压缩包是否不存在
if (!(src.exists())) {
throw new IOException("您要解压的压缩包不存在~");
}
// 1.创建一个解压缩流对象,用于读取压缩包中的数据
ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
// 获取压缩包文件名(包括后缀)
String srcName = src.getName();
// 2.创建目的地目录
File destDir = new File(dest, srcName.substring(0, srcName.indexOf(".")));
destDir.mkdirs();
// 3.要先获取到压缩包中的每一个ZipEntry对象
// 表示在当前压缩包中获取到的文件或文件夹
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
// System.out.println(entry);
// 3.判断zipEntry是否为文件夹
if (entry.isDirectory()) {
// 文件夹:需要在目的地dest处创建一个同样的文件夹
File file = new File(dest, entry.toString());
file.mkdirs();
}else {
// 文件:需要读取到压缩包中的文件,并将该文件存放到目的地dest文件夹中(按照层级目录进行存放)
FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString()));
// 按照1个字节数组读取文件中的数据
byte[] suffer = new byte[4096];
int len;
while ((len = zip.read(suffer)) != -1) {
// 写到目的地
fos.write(suffer, 0, len);
}
fos.close();
// 表示在压缩包中的一个文件处理完毕了!
zip.closeEntry();
}
}
// 压缩包中所有的文件或文件夹处理完毕!关闭
zip.close();
System.out.println("解压完成~");
}
}
解压完成~
Process finished with exit code 0
3、压缩流
- 将多个文件或多个文件夹压缩成一个压缩包。
- 压缩包里面的每一个文件在Java中都是一个
ZipEntry
对象。 - 压缩本质:把每一个文件或文件夹看成
ZipEntry
对象,并放到压缩包中。
(1)压缩单个文件
- 需求:将 E:\a.txt 打包成一个压缩包。
package com.app.demo37_io_zipstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/*
压缩流:压缩单个文件
需求:将 E:\a.txt 打包成一个压缩包。
*/
public class Demo2 {
public static void main(String[] args) throws IOException {
// 1.创建File对象src表示要压缩的文件路径
File src = new File("E:\\a.txt");
// 2.创建File对象dest表示压缩包的目的地
File dest = new File("E:\\");
// 3.压缩
toZip(src, dest);
}
/**
* 压缩单个文件
*
* @param src 要压缩的文件路径
* @param dest 压缩包的目的路径
*/
public static void toZip(File src, File dest) throws IOException {
// 压缩本质:把文件或文件夹的数据放到压缩包中
// 0.判断要压缩的文件是否不存在
if (!(src.exists())) {
throw new IOException("您要压缩的文件不存在~");
}
// 1.创建压缩流关联压缩包
// 创建File对象zipPath,表示压缩包路径
File zipPath = new File(dest, "a.zip");
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath));
// 2.创建ZipEntry对象,表示压缩包里的每一个文件或文件夹
ZipEntry entry = new ZipEntry("a.txt");
// 3.把ZipEntry对象放到压缩包中
zos.putNextEntry(entry);
// 4.把要压缩的文件的数据写到压缩包中
FileInputStream fis = new FileInputStream(src);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) != -1) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
zos.close();
System.out.println("压缩完成~");
}
}
压缩完成~
Process finished with exit code 0
(2)压缩文件夹
- 需求:把 E:\aaa 文件夹压缩成一个压缩包
package com.app.demo37_io_zipstream;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/*
压缩流:压缩文件夹
需求:把 E:\aaa 文件夹压缩成一个压缩包
*/
public class Demo3 {
public static void main(String[] args) throws IOException {
// 1.创建File对象表示要压缩的文件或文件夹
File src = new File("E:\\aaa");
// 2.创建File对象表示压缩包的在哪里(压缩包的父级路径)
File destParent = new File("E:\\");
// 3.创建File对象表示压缩包的路径
File dest = new File(destParent, src.getName() + ".zip");
// 4.创建压缩流关联压缩包
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
// 5.获取src中的每一个文件或文件夹,使之变成ZipEntry对象,并放入压缩包当中
toZip(src, zos, src.getName());
// 6.释放资源
zos.close();
}
/**
* 将文件或文件夹打包成一个压缩包
*
* @param src 要压缩的文件或文件夹
* @param zos 压缩流
* @param name 压缩包内部的路径
*/
public static void toZip(File src, ZipOutputStream zos, String name) throws IOException {
// 压缩本质:把每一个文件或文件夹放到压缩包中
// 0.判断要压缩的文件或文件夹是否不存在
if (!(src.exists())) {
throw new IOException("您要压缩的文件或文件夹不存在~");
}
// 1.获取所有文件或文件夹
File[] files = src.listFiles();
// 2.遍历files数组,依次得到每个文件或文件夹
for (File file : files) {
// 3.判断file是否为文件
if (file.isFile()) {
// 文件:将该文件变成ZipEntry对象,并放到压缩包中
ZipEntry entry = new ZipEntry(name + "\\" + file.getName()); // 例:aaa\aa.txt
zos.putNextEntry(entry);
// 读取该文件的数据,写入到压缩包中
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) != -1) {
zos.write(buffer, 0, len);
}
fis.close();
// 表示一个文件的已处理完毕!
zos.closeEntry();
} else {
// 文件夹:递归
toZip(file, zos, name + "\\" + file.getName());
}
}
}
}
Process finished with exit code 0
二、常用工具包
0、jar包的使用步骤
- 在项目中创建一个文件夹:lib
- 将 jar包 复制粘贴到 lib文件夹
- 右键点击 jar包,选择 Add as Library —> 点击OK
- 在类中导包使用
1、Commons-io
- 是apache开源基金组织提供的一组有关IO操作的开源工具包。
- apache:是专门为支持开源软件项目而办的一个非盈利性组织。
- 作用:提高IO流的开发效率。
(1)IOUtils(数据相关)
拷贝方法:
copy方法有多个重载方法,满足不同的输入输出流
IOUtils.copy(InputStream input, OutputStream output)
IOUtils.copy(InputStream input, OutputStream output, int bufferSize)//可指定缓冲区大小
IOUtils.copy(InputStream input, Writer output, String inputEncoding)//可指定输入流的编码表
IOUtils.copy(Reader input, Writer output)
IOUtils.copy(Reader input, OutputStream output, String outputEncoding)//可指定输出流的编码表
拷贝大文件的方法:
// 这个方法适合拷贝较大的数据流,比如2G以上
IOUtils.copyLarge(Reader input, Writer output) // 默认会用1024*4的buffer来读取
IOUtils.copyLarge(Reader input, Writer output, char[] buffer)//可指定缓冲区大小
将输入流转换成字符串:
IOUtils.toString(Reader input)
IOUtils.toString(byte[] input, String encoding)
IOUtils.toString(InputStream input, Charset encoding)
IOUtils.toString(InputStream input, String encoding)
IOUtils.toString(URI uri, String encoding)
IOUtils.toString(URL url, String encoding)
将输入流转换成字符数组:
IOUtils.toByteArray(InputStream input)
IOUtils.toByteArray(InputStream input, int size)
IOUtils.toByteArray(URI uri)
IOUtils.toByteArray(URL url)
IOUtils.toByteArray(URLConnection urlConn)
IOUtils.toByteArray(Reader input, String encoding)
字符串读写:
IOUtils.readLines(Reader input)
IOUtils.readLines(InputStream input, Charset encoding)
IOUtils.readLines(InputStream input, String encoding)
IOUtils.writeLines(Collection<?> lines, String lineEnding, Writer writer)
IOUtils.writeLines(Collection<?> lines, String lineEnding, OutputStream output, Charset encoding)
IOUtils.writeLines(Collection<?> lines, String lineEnding, OutputStream output, String encoding)
从一个流中读取内容:
IOUtils.read(InputStream input, byte[] buffer)
IOUtils.read(InputStream input, byte[] buffer, int offset, int length) IOUtils.read(Reader input, char[] buffer)
IOUtils.read(Reader input, char[] buffer, int offset, int length)
把数据写入到输出流中:
IOUtils.write(byte[] data, OutputStream output)
IOUtils.write(byte[] data, Writer output, Charset encoding)
IOUtils.write(byte[] data, Writer output, String encoding)
IOUtils.write(char[] data, Writer output)
IOUtils.write(char[] data, OutputStream output, Charset encoding)
IOUtils.write(char[] data, OutputStream output, String encoding)
IOUtils.write(String data, Writer output)
IOUtils.write(CharSequence data, Writer output)
从一个流中读取内容,如果读取的长度不够,就会抛出异常:
IOUtils.readFully(InputStream input, int length)
IOUtils.readFully(InputStream input, byte[] buffer)
IOUtils.readFully(InputStream input, byte[] buffer, int offset, int length) IOUtils.readFully(Reader input, char[] buffer)
IOUtils.readFully(Reader input, char[] buffer, int offset, int length)
比较:
IOUtils.contentEquals(InputStream input1, InputStream input2) // 比较两个流是否相等
IOUtils.contentEquals(Reader input1, Reader input2)
IOUtils.contentEqualsIgnoreEOL(Reader input1, Reader input2) // 比较两个流,忽略换行符
其他方法:
IOUtils.skip(InputStream input, long toSkip) // 跳过指定长度的流
IOUtils.skip(Reader input, long toSkip)
IOUtils.skipFully(InputStream input, long toSkip) // 如果忽略的长度大于现有的长度,就会抛出异常
IOUtils.skipFully(Reader input, long toSkip)
(2)FileUtils(文件/文件夹相关)
复制文件夹:
FileUtils.copyDirectory(File srcDir, File destDir) // 复制文件夹(文件夹里面的文件内容也会复制)
FileUtils.copyDirectory(File srcDir, File destDir, FileFilter filter) // 复制文件夹,带有文件过滤功能
FileUtils.copyDirectoryToDirectory(File srcDir, File destDir) // 以子目录的形式将文件夹复制到到另一个文件夹下
复制文件:
FileUtils.copyFile(File srcFile, File destFile) // 复制文件
FileUtils.copyFile(File input, OutputStream output) // 复制文件到输出流
FileUtils.copyFileToDirectory(File srcFile, File destDir) // 复制文件到一个指定的目录
FileUtils.copyInputStreamToFile(InputStream source, File destination) // 把输入流里面的内容复制到指定文件
FileUtils.copyURLToFile(URL source, File destination) // 把URL 里面内容复制到文件(可以下载文件)
FileUtils.copyURLToFile(URL source, File destination, int connectionTimeout, int readTimeout)
把字符串写入文件:
FileUtils.writeStringToFile(File file, String data, String encoding)
FileUtils.writeStringToFile(File file, String data, String encoding, boolean append)
把字节数组写入文件:
FileUtils.writeByteArrayToFile(File file, byte[] data)
FileUtils.writeByteArrayToFile(File file, byte[] data, boolean append) FileUtils.writeByteArrayToFile(File file, byte[] data, int off, int len) FileUtils.writeByteArrayToFile(File file, byte[] data, int off, int len, boolean append)
把集合里面的内容写入文件:
// encoding:文件编码,lineEnding:每行以什么结尾
FileUtils.writeLines(File file, Collection<?> lines)
FileUtils.writeLines(File file, Collection<?> lines, boolean append)
FileUtils.writeLines(File file, Collection<?> lines, String lineEnding)
FileUtils.writeLines(File file, Collection<?> lines, String lineEnding, boolean append)
FileUtils.writeLines(File file, String encoding, Collection<?> lines)
FileUtils.writeLines(File file, String encoding, Collection<?> lines, boolean append)
FileUtils.writeLines(File file, String encoding, Collection<?> lines, String lineEnding)
FileUtils.writeLines(File file, String encoding, Collection<?> lines, String lineEnding, boolean append)
往文件里面写内容:
FileUtils.write(File file, CharSequence data, Charset encoding)
FileUtils.write(File file, CharSequence data, Charset encoding, boolean append)
FileUtils.write(File file, CharSequence data, String encoding)
FileUtils.write(File file, CharSequence data, String encoding, boolean append)
文件移动:
FileUtils.moveDirectory(File srcDir, File destDir) // 文件夹在内的所有文件都将移动FileUtils.moveDirectoryToDirectory(File src, File destDir, boolean createDestDir) // 以子文件夹的形式移动到另外一个文件下
FileUtils.moveFile(File srcFile, File destFile) // 移动文件
FileUtils.moveFileToDirectory(File srcFile, File destDir, boolean createDestDir) // 以子文件的形式移动到另外一个文件夹下
FileUtils.moveToDirectory(File src, File destDir, boolean createDestDir) // 移动文件或者目录到指定的文件夹内
清空和删除文件夹:
FileUtils.deleteDirectory(File directory) // 删除文件夹,包括文件夹和文件夹里面所有的文件
FileUtils.cleanDirectory(File directory) // 清空文件夹里面的所有的内容
FileUtils.forceDelete(File file) // 删除,会抛出异常
FileUtils.deleteQuietly(File file) // 删除,不会抛出异常
创建文件夹:
FileUtils.forceMkdir(File directory) // 创建文件夹(可创建多级)
FileUtils.forceMkdirParent(File file) // 创建文件的父级目录
获取文件输入/输出流:
FileUtils.openInputStream(File file)
FileUtils.openOutputStream(File file)
读取文件:
FileUtils.readFileToByteArray(File file) // 把文件读取到字节数组
FileUtils.readFileToString(File file, Charset encoding) // 把文件读取成字符串
FileUtils.readFileToString(File file, String encoding)
FileUtils.readLines(File file, Charset encoding) // 把文件读取成字符串集合
FileUtils.readLines(File file, String encoding)
测试两个文件的修改时间:
FileUtils.isFileNewer(File file, Date date)
FileUtils.isFileNewer(File file, File reference)
FileUtils.isFileNewer(File file, long timeMillis)
FileUtils.isFileOlder(File file, Date date)
FileUtils.isFileOlder(File file, File reference)
FileUtils.isFileOlder(File file, long timeMillis)
文件/文件夹的迭代:
FileUtils.iterateFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter)
FileUtils.iterateFiles(File directory, String[] extensions, boolean recursive)
FileUtils.iterateFilesAndDirs(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter)
FileUtils.lineIterator(File file)
FileUtils.lineIterator(File file, String encoding)
FileUtils.listFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter)
FileUtils.listFiles(File directory, String[] extensions, boolean recursive)
FileUtils.listFilesAndDirs(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter)
其他:
FileUtils.isSymlink(File file) // 判断是否是符号链接
FileUtils.directoryContains(File directory, File child) // 判断文件夹内是否包含某个文件或者文件夹
FileUtils.sizeOf(File file) // 获取文件或者文件夹的大小
FileUtils.getTempDirectory()// 获取临时目录文件
FileUtils.getTempDirectoryPath()// 获取临时目录路径
FileUtils.getUserDirectory()// 获取用户目录文件
FileUtils.getUserDirectoryPath()// 获取用户目录路径
FileUtils.touch(File file) // 创建文件
FileUtils.contentEquals(File file1, File file2) // 比较两个文件内容是否相同
(3)FilenameUtils(文件名/后缀名相关)
FilenameUtils.concat(String basePath, String fullFilenameToAdd) // 合并目录和文件名为文件全路径
FilenameUtils.getBaseName(String filename) // 去除目录和后缀后的文件名
FilenameUtils.getExtension(String filename) // 获取文件的后缀
FilenameUtils.getFullPath(String filename) // 获取文件的目录
FilenameUtils.getName(String filename) // 获取文件名
FilenameUtils.getPath(String filename) // 去除盘符后的路径
FilenameUtils.getPrefix(String filename) // 盘符
FilenameUtils.indexOfExtension(String filename) // 获取最后一个.的位置
FilenameUtils.indexOfLastSeparator(String filename) // 获取最后一个/的位置
FilenameUtils.normalize(String filename) // 获取当前系统格式化路径
FilenameUtils.removeExtension(String filename) // 移除文件的扩展名
FilenameUtils.separatorsToSystem(String path) // 转换分隔符为当前系统分隔符
FilenameUtils.separatorsToUnix(String path) // 转换分隔符为linux系统分隔符
FilenameUtils.separatorsToWindows(String path) // 转换分隔符为windows系统分隔符
FilenameUtils.equals(String filename1, String filename2) // 判断文件路径是否相同,非格式化
FilenameUtils.equalsNormalized(String filename1, String filename2) // 判断文件路径是否相同,格式化
FilenameUtils.directoryContains(String canonicalParent, String canonicalChild) // 判断目录下是否包含指定文件或目录
FilenameUtils.isExtension(String filename, String extension) // 判断文件扩展名是否包含在指定集合(数组、字符串)中
FilenameUtils.wildcardMatch(String filename, String wildcardMatcher) // 判断文件扩展名是否和指定规则匹配
2、Hutool(糊涂包)
- GitHub:国际性的代码托管平台。(戏称:最大的同性交友网站)
- Hutool 在GitHub平台上就是最受欢迎的开源项目之一。
Hutool如何使用?
先进入看中文使用文档,找你想用的工具包:
https://hutool.cn/docs/#/
接着到API文档中找对应的方法:
https://apidoc.gitee.com/dromara/hutool/
官网地址:
https://hutool.cn/