十一、IO流
1)文件的读写(字符流) 适用于 txt doc wps
①.FileWriter文件写②.FileReader文件读③.BufferedWriter+FileWriter 缓冲区的出现提高了对流的操作效率。原理:其实就是将数组进行封装(StringBuilder缓存)。④.BufferedReader+FileReader 缓冲区的出现提高了对流的操作效率。原理:其实就是将数组进行封装(StringBuilder缓存)。
2)文件的读写(字节流) 适用于 图片、声音、影像等文件。
①.FileInputStream文件的读
②.FileOutputStream文件的写
3)文件的读写(转换流)
①.InputStreamReader 用于文件字节与缓存字符的更好转换 文件读
②.OutputStreamWriter 用于文件字节与缓存字符的更好转换 文件写
FileUtils工具类:
package net.itaem.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.servlet.http.HttpServletRequest;
/**
*
* @Description:文件操作工具类
* 文件的增删
* 1.文件以及文件目录的级联创建
* 2.文件目录的级联创建
* 3.文件的删除(限制,有子文件则删除失败)
* 4.文件的级联删除(级联,把子文件一起删除)
*
* 文件的读写(字符流) 适用于 txt doc wps
* 1.FileWriter文件写
* 2.FileReader文件读
* 3.BufferedWriter+FileWriter文件写
* 4.BufferedReader+FileReader文件读
*
* 文件的读写(字节流) 适用于 图片、声音、影像等文件。
* 1.FileInputStream文件的读
* 2.FileOutputStream文件的写
*
* 文件的读写(转换流)
* 1.InputStreamReader文件读
* 2.OutputStreamWriter文件写
*
* 工具方法
* 1.文件的复制 (使用BufferedInputStream与BufferedOutputStream)
* 2.键盘内容读取(使用InputStreamReader)
* 3.检查正确文件路径
* 4.判断正确的文件编码(已在FileEncodes设置的编码)
* 5.获取程序当前路径
* 6.显示文件剩余的大小
* @operate:
* @author sen
* @date 2014-3-12
*/
public class FileUtils {
/**
* 实现具有防御型单例
*/
private static final FileUtils fileUtils = new FileUtils() ;
/**
* 私有构造函数防止多次实例化
*/
private FileUtils(){
if(fileUtils==null){
}else{
//被反射攻击了
throw new RuntimeException("FileUtils被反射攻击了") ;
}
}
/**
* 设置文件可设置的编码类型
*/
private static final String[] fileEncodes =
{"UTF-8","GBK","GB2312","ISO-8859-1","ASCII","Unicode"} ;
/**
* @description 创建文件
* @param filePath
* 文件路径
* @return 创建成功为ture 创建失败为false
* @author sen
*/
public static boolean createFile(String filePath) throws IOException {
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
// 判断文件是否存在
if (!file.exists()) {
String dirPath = file.getParent(); // 获取文件的上一级
File fileDir = new File(dirPath);
if (!fileDir.exists()) { // 目录不存在的情况下
fileDir.mkdirs();// 创建目录列表。
}
return file.createNewFile();// 创建文件
}
return false;
}
/**
* @description 创建文件夹
* @param fileFolderPath
* 文件夹路径
* @return 创建成功为true 创建失败为false
* @author sen
*/
public static boolean createFileFolder(String fileFolderPath) {
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(fileFolderPath)) {
return false;
}
File file = new File(fileFolderPath);
// 判断文件夹是否存在
if (!file.exists()) { // 目录不存在的情况下
return file.mkdirs(); // 创建目录列表。
}
return false;
}
/**
* @description 删除文件 注意:只能删除1级文件,不能实现级联删除
* @param filePath
* @return 删除成功为true 删除失败为false
* @author sen
*/
public static boolean deleteFileRestrict(String filePath) {
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
if(file.exists()){ //如果文件存在
return file.delete(); //删除文件
}
return false;
}
/**
*
* @description 删除文件目录 能够级联删除
* @param fileDirectoryPath
* @return 删除成功为true
* 删除失败为false
* @author sen
*/
public static boolean deleteFileCascade(String filePath) {
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return false ;
}
// 删除目录或文件,如果目录不为空返回false
if (file.delete()) {
} else {
//取出文件目录的子文件或文件夹
File[] fileChilds = file.listFiles();
for(File f :fileChilds){
//递归调用
deleteFileCascade(f.getAbsolutePath()) ;
}
//删除父类文件夹
file.delete() ;
}
return true ;
}
/**
* FileWriter,FileReader特点:
* 1.用于处理文本文件;
* 2.该类中有默认的编码表;
* 3.该类中有临时缓冲。
*/
/**
* @description 使用FileWriter进行文件的写 专门适用于纯文本 txt doc wps
* @throws IOException
* @param 1.pattern标志位,选择写的模式
* pattern=true代表文件往后追加,pattern=false代表文件覆写
* 2.filePath文件路径
* 3.content文件内容
* @return 写入成功为true
* 写入失败为false
*
* @author sen
*/
public static boolean writerFileByFileWriter(String filePath,String content,boolean pattern) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return false ;
}
//实例化FileWriter
FileWriter fileWriter = new FileWriter(file,pattern) ;
//把内容写入文件
fileWriter.write(content) ;
//刷新文件内容
fileWriter.flush() ;
//关闭流通道
fileWriter.close() ;
return true ;
}
/**
* @description 使用FileReader进行文件的读 专门适用于纯文本 txt doc wps
* @param 1.filePath文件路径
* 2.pattern文件模式
* pattern=true代表 小文本上传
* pattern=false代表 大文件上传
* @return 如果文件路径错误或者文件不存在 返回null
* 成功,则返回文件内容
* @author sen
* @throws IOException
*/
public static String readerFileByFileReader(String filePath) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return null ;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return null ;
}
//内容存储
StringBuilder builder = new StringBuilder() ;
//实例化fileReader
FileReader fileReader = new FileReader(filePath) ;
//设定文件内容结束标志位
int ch = 0 ;
/*if(!pattern){
* 一次读取一个字符
* 缺点:由于次读取一个字符,而每个字符需要int转char转型
* 大文件比耗费大量的执行时间和资源
while((ch=fileReader.read())!=-1){
builder.append((char)ch);
}
}else{*/
/*
* 一次读取多个字符(默认1024个)
* 优点:免去了转型消耗,以及减少了存储次数,提高了性能和效率
* 缺点:需要创建1024个char字符数组(1KB,1个英文字符1B,1个中文汉字字符2B),浪费了资源
*/
//缓存字符数组
char[] charArray = new char[1024] ; //1024B=1KB
//读满或者读完则存放到bulider里面
while((ch=fileReader.read(charArray))!=-1){
builder.append(charArray, 0, ch) ;
}
//}
//一次读取多个字符
fileReader.close() ;
return builder.toString() ;
}
/**
* BufferedWriter,BufferedReader特点: 比FileWriter更快
* 缓冲区的出现提高了对流的操作效率。
* 原理:其实就是将数组进行封装(StringBuilder缓存)。
*
* 1.在使用缓冲区对象时,要明确,缓冲的存在是为了增强流的功能而存,
* 所以在建立缓冲区对象时,要先有流对象存在。
* 2.其实缓冲内部就是在使用流对象的方法,
* 只不过加入了数组对数据进行了临时存储。
* 提高操作数据的效率。
*
*/
/**
* @description 使用BufferedWriter进行文件的写 专门适用于纯文本 txt doc wps
* @throws IOException
* @param 1.pattern标志位,选择写的模式
* pattern=true代表文件往后追加,pattern=false代表文件覆写
* 2.filePath文件路径
* 3.content文件内容
* @return 写入成功为true
* 写入失败为false
*
* @author sen
*/
public static boolean writerFileByBufferedWriter(String filePath,String content,boolean pattern) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return false ;
}
//实例化bufferedWriter(缓冲区对象)
// 特有方法newLine() 跨平台换行符
BufferedWriter bufferWriter = new BufferedWriter(new FileWriter(file,pattern)) ;
//写入内容
bufferWriter.write(content) ;
//刷新文件内容
bufferWriter.flush() ;
//关闭通道
bufferWriter.close() ;
return true ;
}
/**
* @description 使用BufferedReader进行文件的写 专门适用于纯文本 txt doc wps
* @throws IOException
* @param 1.pattern标志位,选择写的模式
* pattern=true代表文件往后追加,pattern=false代表文件覆写
* 2.filePath文件路径
* 3.content文件内容
* @return 写入成功为true
* 写入失败为false
*
* @author sen
*/
public static String readerFileByBufferedReader(String filePath) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return null;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return null ;
}
//内容存储
StringBuilder builder = new StringBuilder() ;
//读取缓冲区对象
/* 特有方法 readLine() 一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。
* 原理:readerLine()实质也是调用read()方法,不过在read()(一次读取一个字符)上进行封装,
* 只有读取到换行符或者文件结束的时候才进行统一的返回,功能与read(Array)数组类似。
* 注意:按照行的形式取出数据,取出的每一行数据不包含回车符
*/
BufferedReader bufferReader = new BufferedReader(new FileReader(filePath)) ;
//缓冲字符串
String line = null ;
//注意:按照行的形式取出数据,取出的每一行数据不包含回车符
while((line=bufferReader.readLine())!=null){
builder.append(line);
builder.append("\r\n") ; //手动添加换行符
}
//关闭缓冲区对象(内置关闭流对象)
bufferReader.close() ;
//内容返回
return builder.toString() ;
}
/**
* @description 使用FileInputStream进行文件的读。 用于读二进制文件,如图片、声音、影像等文件。
* 注意:本方法仅用于 小于1KB 的文件,故该方法仅用于学习使用
* @param filePath文件路径
*
* @return 成功byte[]
* 失败null
* @throws IOException
*
* @author sen
*/
public static byte[] inputFileByFileInputStream(String filePath) throws IOException {
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return null;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return null;
}
//实例化FileInputStream
FileInputStream fileInputStream = new FileInputStream(file);
//获取文件大小
int lenght = fileInputStream.available() ;
//判断文件大小 大于1K
/*if(lenght>1024){
return null ;
}*/
//以字节为单位读取文件内容,一次读全部内容 默认为文件总大小
//如果文件体积不是很大。
//可以这样操作byte[] buf = new byte[fileInputStream.available()]。
//但是这有一个弊端,就是文件过大,大小超出jvm的内容空间时,会内存溢出。
//缺点:注意缓存可能会爆掉
byte[] bytesRead = new byte[lenght];
//读入多个字节到字节数组中,byteread为一次读入的字节数
fileInputStream.read(bytesRead) ;
fileInputStream.close() ;
return bytesRead;
}
/**
* @description 使用FileOutputStream进行文件的读。 用于读二进制文件,如图片、声音、影像等文件。
*
* @param String filePath文件路径
* byte[] content文件内容
* @return 成功true
* 失败false
* @throws IOException
*
* @author sen
*/
public static boolean outputFileByFileOutputStream(String filePath,byte[] content) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return false;
}
//实例化FileOutputStream文件流对象
FileOutputStream fileOutputStream = new FileOutputStream(file);
//直接将数据写入到了目的地。
fileOutputStream.write(content);
//只关闭资源。
fileOutputStream.close();
return true ;
}
/**
* @description 使用BufferedInputStream与BufferedOutputStream进行文件的复制
*
* @param sourceFilePath源文件路径
* destinFilePath目标文件路径
* pattern模式 ①pattern=true大文件复制
* ②pattern=false小文件复制
* @return 成功true
* 失败false
* @throws IOException
*
* @author sen
*/
public static boolean copyFileByBufferedInputOutputStream(String sourceFilePath,
String destinFilePath,boolean pattern) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(sourceFilePath)
||!FileUtils.checkFile(destinFilePath)) {
return false;
}
//创建源文件
File sourceFile = new File(sourceFilePath);
//创建目标文件
File destinFile = new File(destinFilePath) ;
// 判断源文件或目录是否存在
if (!sourceFile.exists()) {
return false;
}
// 如果没有目标文件目录 则 创建
// 获取目录
File destinParentFile = destinFile.getParentFile() ;
if(!destinParentFile.exists()){
//创建目录
destinParentFile.mkdirs() ;
}
//创建源文件输入流对象
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream(sourceFilePath));
//创建目标文件输出流对象
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream(destinFilePath));
//缓存对象
int byteRead = 0;
if(!pattern){
//一次读取一个字节
while((byteRead=bufis.read())!=-1){
bufos.write(byteRead);
}
}else{
//一次读取多个字节(1024个字节数=1024B)
byte[] tempBytes = new byte[1024] ;
while((byteRead=bufis.read(tempBytes))!=-1){
bufos.write(tempBytes, 0, byteRead) ;
}
}
//关闭输出流
bufos.close();
//关闭输入流
bufis.close();
return true ;
}
/**
* InputStreamReader和OutStreamWriter的使用
*
* 用处:1.用于文件字节与缓存字符的更好转换
* 2.添加编码
*/
/**
*
* @description 使用InputStreamReader进行文件读 用于编码读取
* @param 1.filePath文件路径
* 2.encode文件编码
* @return 成功true
* 失败false
* @throws IOException
*/
public static String readerFileByBufferedReaderEncode(String filePath,String encode) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return null ;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return null ;
}
//存储数据
StringBuilder builder = new StringBuilder() ;
//读取缓冲区对象
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(
new FileInputStream(file),encode)) ;
//缓冲字符串
String line = null ;
//注意:按照行的形式取出数据,取出的每一行数据不包含回车符
while((line=bufferReader.readLine())!=null){
builder.append(line);
builder.append("\r\n") ; //手动添加换行符
}
//关闭缓冲区对象(内置关闭流对象)
bufferReader.close() ;
//内容返回
return builder.toString() ;
}
/**
*
* @description 使用OutputStreamWriter进行文件写 用于编码存储
* @param 1.filePath文件路径
* 2.content文件内容
* 3.pattern模式 pattern=true文件往后添加内容
* pattern=false文件覆写
* 4.encode文件编码
* @return 成功true
* 失败false
* @throws IOException
*/
public static boolean writerFileByBufferedWriterEncode(String filePath,String content,
boolean pattern,String encode) throws IOException{
// 判断是否是正确的文件路径
if (!FileUtils.checkFile(filePath)) {
return false;
}
File file = new File(filePath);
// 判断文件或目录是否存在
if (!file.exists()) {
return false ;
}
//读取缓冲区对象
BufferedWriter bufferWriter = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(file,pattern),encode)) ;
//写入内容
bufferWriter.write(content) ;
//刷新文件内容
bufferWriter.flush() ;
//关闭通道
bufferWriter.close() ;
return true ;
}
/**
*
* @description 键盘录入
* @return 键盘输入的内容
* @throws IOException
*
* @author sen
*/
public static String readerSystemInByInputStreamReader() throws IOException{
System.out.println("请输入信息,退出输入exit:");
//存储内容
StringBuilder builder = new StringBuilder() ;
//缓冲区对象
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(System.in));
//缓冲字符串
String line = null ;
//注意:按照行的形式取出数据,取出的每一行数据不包含回车符
while(!"exit".equals(line=bufferReader.readLine())){
builder.append(line);
builder.append("\r\n") ; //手动添加换行符
}
//关闭缓冲区对象(内置关闭流对象)
bufferReader.close() ;
//内容返回
return builder.toString() ;
}
/**
*
* @description 检验文件路径是否正确
* @param filePath文件路径
* @return 正确文件路径true 不是文件路径false
* @author sen
*/
public static boolean checkFile(String filePath) {
// 替换掉双斜杠
// 把双斜杠\\替换为/
if (filePath.contains("\\")) {
filePath = filePath.replace("\\", File.separator);
}
/*
* 判断路径是否正确
* 只能检测 / 或 \(File.separator)文件分隔符
* 正则解析:
* 1.[a-z|A-Z]:代表盘符 例如c:
* 2.([\\\\|/]\\w+){0,} 代表0个或多个文件目录 例如/aaa/bbb 或 \aaa\bbb
* 3.[\\\\|/]\\w*(.\\w*|) 代表文件名 例如/test.txt 或\test(小w代表字母或数字。大W代表非字母或数字)
*/
if (!filePath
.matches("^[a-z|A-Z]:([\\\\|/]\\w+){0,}[\\\\|/]\\w*(.\\w*|)$")) {
System.out.println("文件路径不正确!路径:"+filePath);
return false;
}
return true;
}
/**
*
* @description 判断是否是正确的编码值
* @param 在fileEncodes设置的编码值
* @return 成功true
* 失败false
*
* @author sen
*/
public static boolean checkEncode(String encode){
//替换掉对应的空字符
encode = encode.replace(" ", "") ;
//与fileEncodes设置的编码进行匹配
for(String tempEncode:FileUtils.fileEncodes){
//忽略大小进行匹配
if(tempEncode.equalsIgnoreCase(encode)){
return true ;
}
}
return false ;
}
/**
* @description 获取程序当前路径
* @param request!=null(web路径)
* request==null
* @return 程序路径
* @author sen
*/
public static String getProjectPath(HttpServletRequest request) {
if(request!=null){
return request.getSession().getServletContext().getRealPath("/") ;
}
// 获取程序路径
return System.getProperty("user.dir").replace("\\", File.separator)+File.separator;// user.dir指定了程序当前路径
}
/**
* @description 显示输入流中还剩的字节数
* @throws IOException
* @author sen
*/
@SuppressWarnings("unused")
private static void showAvailableBytes(InputStream inputStream) throws IOException {
System.out.println("当前字节输入流中的字节数为:" + inputStream.available());
}
}<span style="font-family:微软雅黑;"><span style="font-size: 14px; line-height: 21px;">
</span></span>