因为数组和变量等等储存数据只是暂时存在的程序结束后就会消失,所以就有了I/O,可以将文件存到本地磁盘文件中。
文章目录
- 输入输出流基本概念
- File类
- 文件输入输出流
- 带缓存的输入输出流
- 数据输入输出流
- Zip压缩输入输出流
1.输入输出流基本概念
流:流就是一组有序的数据序列,根据操作类型可以分为输入流和输出流
InputStream类是所有字节输入流的父类,于此类似的还有Reader类是所有字符输入流的父类,他们的方法都相似。
常用方法:
- read()方法,从输入流中读取数据的下一个字节,还回的是int值,如果没有就还回-1(意思就是还回输入流所有的字节数一共是多少)
- read(byte[]b),从输入流中读取一定长度的字节,一整数形式还回。
- mark(int readlimit)方法,在输入流当前位置做一个标记
- readlimit参数是告知输入流在标记失效强,允许读取的字节数reset()方法,将输入指针还回到当前标记处。
- skip(long n),跳过输入流上的n个字节并还回实际跳过的字节数
- markSupported(),如果当前流支持mark或者reset方法就还回true
- close()关闭输入流,并释放与之相关的资源
OutputStream类和Writer类与上面的两个输入类相对应,一个是字节,一个是字符。只不过是输出流。
常用方法:
- write(int b),将指定字节写入此输出流
- write(byte[] b),将b个字节从byte数组中写入此输出流
- write(byte[] b,int off,int len),将byte数组从偏移量off开始的len个字节写入输出流
- flush(),彻底完成输入,清空缓存区
- close,关闭输出流
2.File类
File类就是对文件进行操作的类
文件创建方法有很多种,
- File file=new File("要创建的文件的路径和文件名(如果没有路径就默认在项目文件夹中)")
- File file=new File("要创建的文件的路径(如果没有路径就默认在项目文件夹中),文件名")
方法 | 还回值 | 解释 |
---|---|---|
getName() | String | 获取文件名 |
canRead() | boolean | 文件是否可读 |
canWrite() | boolean | 文件是否可写 |
exits() | boolean | 文件是否存在 |
length() | iong | 文件的长度(以字节为单位) |
getAbsolutePath() | String | 文件的绝对路径 |
getParent() | String | 文件的父路径(就是没有文件名的路径) |
isFile() | boolean | 文件是否存在 |
isDirectory() | boolean | 文件是否为一个目录 |
isHidden() | boolean | 文件是否为隐藏文件 |
lastModified() | long | 获取文件最后被修改时间 |
例子:
代码;
package com.cn;
import java.io.File;
public class Dom{
public static void main(String[]args){
File file=new File("E:/","word.txt");
if (file.exists()) {
file.delete();
System.out.println("文件已删除");
}else {
try {
file.createNewFile();
System.out.println("文件已创建");
System.out.println("文件的路径:"+file.getAbsolutePath());
System.out.println("文件的父路径:"+file.getParent());
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3.文件输入输出流
文件输入输出主要有四个类:
- FileInputStream(继承InputStream)
- FileOutputStream(继承OutputStream)
- FileReader(继承Reader)
- FileWriter(继承Writer)
方法在上面基本上讲过了,因为是继承下来的方法基本上都一样。
例子:
package com.cn;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
public class Dom{
public static void main(String[]args)throws Exception{
//创建文件对象
File file=new File("E:/","word.txt");
//判断文件是否存在
if (file.exists()) {
file.delete();
System.out.println("文件已删除");//存在就删除
}else {
//不存在就创建文件
file.createNewFile();
System.out.println("文件已创建");
System.out.println("文件的路径:"+file.getAbsolutePath());
System.out.println("文件的父路径:"+file.getParent());
//创建FileOutputStream类对象
FileOutputStream fileOutputStream=new FileOutputStream(file);
byte b[]="你好,世界".getBytes(StandardCharsets.UTF_8);//创建数组
fileOutputStream.write(b);//写入
fileOutputStream.close();//关闭
//创建FileInputStream对象
FileInputStream fileInputStream=new FileInputStream(file);
byte b1[]=new byte[1024];
int len=fileInputStream.read(b1);
System.out.println("文本文件是;"+new String(b1,0,len));
fileInputStream.close();
}
}
}
结果:
文件已创建
文件的路径:E:\word.txt
文件的父路径:E:\
文本文件是;你好,世界
关与getBytes方法的解释请点击
4.带缓存的输入输出流
缓存就是对I/O的性能优化
同样有四个:
- BufferedInputStream(继承InputStream)
- BufferedOutputStream(继承OutputStream)
- BufferedReader(继承Reader)
- BufferedWriter(继承Writer)
BufferedInputStream和BufferedOutputStream都有两个构造方法类似:
1.BufferedInputStream(InputStream in)
2.BufferedInputStream(InputStream in,int size)
第一个是创建一个带有32个字节的缓存流,第二个是自定义的缓存区。BufferedOutputStream与之类似。
BufferedReader的常用方法:
read(),读取单个字符
readLine(),读取一个文本行,并还回字符串
BufferedWriter的常用方法:
write(String s,int off,int len),写入字符串的某一部分
flush(),刷新该流的缓存
newLine(),写入一个行分隔符
例子:
package com.cn;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Dom{
public static void main(String[]args)throws Exception{
//创建字符串数组
String str[]={"你好","我是李华","你是谁"};
//创建文件对象
File file=new File("E:/","word.txt");
FileWriter fileWriter=new FileWriter(file);
BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);
for (int k=0;k<str.length;k++){
bufferedWriter.write(str[k]);
bufferedWriter.newLine();//还行
}
bufferedWriter.close();
fileWriter.close();
FileReader fileReader=new FileReader(file);
BufferedReader bufferedReader=new BufferedReader(fileReader);
String s=null;
int i=0;
//如果文本不为空就一直循环
while ((s=bufferedReader.readLine())!=null){
i++;
System.out.println("第"+i+"行"+s);
}
bufferedReader.close();
fileReader.close();
}
}
结果:
第1行你好
第2行我是李华
第3行你是谁
5.数据输入输出流
数据输入输出流是DataInputStream类和DataOutputStream类,他允许应用程序以与机器无关的方式从底层输入流读取基本java数据类型,就是不用担心数值的字节类型了。
DataOutputStream类方法:
- writeBytes(String s)
- writeChars(String s)
- writeUTF(String s)
DataInputStream类的方法:
- readUTF()
readUTF()方法只能读取writeUTF()方法写入的。
例子:
package com.cn;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Dom{
public static void main(String[]args)throws Exception{
//创建字符串数组
String str[]={"你好","我是李华","你是谁"};
//创建文件对象
File file=new File("E:/","word.txt");
FileOutputStream fileOutputStream=new FileOutputStream(file);
DataOutputStream dataOutputStream=new DataOutputStream(fileOutputStream);
dataOutputStream.writeUTF(str[2]);
dataOutputStream.writeBytes(str[0]);
dataOutputStream.writeChars(str[1]);
dataOutputStream.close();
fileOutputStream.close();
FileInputStream fileInputStream=new FileInputStream(file);
DataInputStream dataInputStream=new DataInputStream(fileInputStream);
System.out.println(dataInputStream.readUTF());
dataInputStream.close();
fileInputStream.close();
}
}
结果:
你是谁
6.Zip压缩输入输出流
ZipOutputStream的构造方法:ZipOutputStream(OutputStream out);
方法 | 还回值 | 解释 |
---|---|---|
putNextEntry(ZipEntry e) | void | 开始写一个新的ZipEntry,并将流内的位置移至此entry所指数据地开头 |
write(byte b[],int off,int len) | void | 将字节数组写入当前ZIP条目数据 |
finish() | void | 完成写入ZIP输出流的内容,无需关闭它所配合的OutputStream |
setComment(String comment) | void | 可设置此ZIP文件的注释文字 |
例子:
package com.cn;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Dom{
private void zip(String zipFileName,File inputFile)throws Exception{
ZipOutputStream zipOutputStream=new ZipOutputStream(new FileOutputStream(zipFileName));
zip(zipOutputStream,inputFile,"");
System.out.println("压缩中。。。。");
zipOutputStream.close();
}
public void zip(ZipOutputStream zipOutputStream,File file,String bass)throws Exception{
//是否为一个目录
if(file.isDirectory()){
//获取路径数组
File[] files=file.listFiles();
if (bass.length()!=0){
//写入目录的entry
zipOutputStream.putNextEntry(new ZipEntry(bass+"/"));
}
//遍历数组中的文件
for (int i=0;i<file.length();i++){
zip(zipOutputStream,files[i],bass+files[i]);
}
}else {
zipOutputStream.putNextEntry(new ZipEntry(bass));//创建新的进入点
FileInputStream fileInputStream=new FileInputStream(file);//创建对象
int b;
System.out.println(bass);
while ((b=fileInputStream.read())!=-1){//如果没有到达流的底部
zipOutputStream.write(b);//将字节写入当前zip条目
}
fileInputStream.close();//关闭流
}
}
public static void main(String[]args)throws Exception{
Dom dom=new Dom();
dom.zip("E:/word.zip",new File("E:/word.txt"));
System.out.println("压缩完成");
}
}
结果:
ZipInputStream类构造方法ZipInputStream(InputStream in)
方法 | 还回值 | 解释 |
---|---|---|
read(byte[]b,int off,int len) | int | 读取目标b数组内off偏移量的位置,长度是len字节 |
available() | int | 判断是否读完目前的entry所指的数据。已读还回0,否则还回1 |
closeEntry() | void | 关闭当前zip条目并定位流以读下一个条目 |
skip(long n) | long | 跳过当前zip条目中指定的字节数 |
getNexEntry() | ZipEntry | 读取下一个ZipEntry,并将流内位置移至该entry所指的数据的开头 |
createZipEntry(String name) | ZipEntry | 以指定name参数新建一个ZipEntry对象 |
例子:
package com.cn;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class Dome {
public static void main(String[] args)throws Exception {
File file=new File("E:/","word.zip");//当前解压文件
ZipInputStream zipInputStream;//
ZipFile zipFile=new ZipFile(file);//创建解压文件对象
zipInputStream=new ZipInputStream(new FileInputStream(file));//实例化对象,指明解压文件
ZipEntry zipEntry=zipInputStream.getNextEntry();//跳过根目录,获取下一个ZipEntry
while (((zipEntry!=null)&&!zipEntry.isDirectory())&&!zipEntry.isDirectory()){//如果zipEntry不为空,并不在同一目录下
System.out.println("1");
System.out.println(zipEntry.getName());
File file1=new File("D:\\",zipEntry.getName());//解压文件路径
if (!file1.exists()){//如果文件不存在
file1.getParentFile().mkdirs();//创建文件父类文件夹路径
OutputStream outputStream=new FileOutputStream(file1);//将目录文件方入输出流
InputStream inputStream=zipFile.getInputStream(zipEntry);//用输入流读取压缩文件中制定目录中的文件
int count=0;
while ((count=inputStream.read())!=-1){//如果有输出流可以读到数值
outputStream.write(count);//输出流写入
}
outputStream.close();//关闭流
inputStream.close();//关闭流
}
zipInputStream.closeEntry();//
System.out.println(zipEntry.getName()+"解压成功");
break;
}
zipInputStream.close();
}
}
结果: