Java文件与IO
File类
代表计算机各个文件,目录的抽象表现形式,可以实现文件的创建,删除等
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class FileDemo {
public static void main(String[] args) {
//File类表示一个文件或目录
//指定在哪里创建
//第一种使用方法
File f1 = new File("/home/xiaoming/音乐/java/vince.text");
//第二种使用方法,使用类中的常量separator表示斜杠
File f2 = new File(File.separator+"home"
+File.separator+"xiaoming"
+File.separator+"音乐"+File.separator
+"java"+File.separator+"tey.text");
//判断文件是否已经存在
if(!f1.exists()) {
try {
f1.createNewFile();//创建文件
System.out.println("文件创建成功");
} catch (IOException e) {
// 基本上IO操作都报这个错误
e.printStackTrace();
}
}
//判断对象是否是文件
System.out.println(f1.isFile());
//判断该对象是否为文件夹
System.out.println(f1.isDirectory());
//删除文件夹(前提文件夹里无文件)
File f3 = new File("/home/xiaoming/音乐/java");
boolean b = f3.delete();
System.out.println(b);
//列出所有文件名,若是文件夹,则列出文件夹名
String[] name = f3.list();
System.out.println(Arrays.toString(name));
//列出当前目录下的所有文件,以file对象返回
File[] f4 = f3.listFiles();
for(File f:f4) {
System.out.println(f.length());
System.out.println(f.getName());
System.out.println(f.getPath());//相对路径
System.out.println(f.getAbsolutePath());//绝对路径
System.out.println(f.isHidden());//是否隐藏文件
System.out.println(f.canRead());
Date date = new Date(f.lastModified());//最后修改时间
DateFormat df = new SimpleDateFormat("HH:mm:ss");
System.out.println(df.format(date));
}
//创建文件夹
File f5 = new File("/home/xiaoming/音乐/java1");
f5.mkdir();
f5.mkdirs();//一次性创建所有指定文件夹
//重命名与移动文件
f5.renameTo(new File("/home/xiaoming/音乐/Text1"));
//过滤器
File[] files = f5.listFiles(new FileFilter() {
//从写此方法,用于查找出指定文件
public boolean accept(File pathname) {
return pathname.getName().endsWith(".text");
}
});
//第二种写法
File[] files_s = f5.listFiles((pathname)->pathname.getName().endsWith(".text"));
for(File f:files) {
System.out.println(f.getName());
}
}
}
字节输出,输入流
输出输入是从程序的角度看的OutputStream
,InputStream
是所有类的超类,要向文件中进行操作,使用子类FileOutputStream
,FileInputStream
write
,read
的具体实现都是一个字节一个字节进行读取的
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class IOStreamDemo {
public static void main(String[] args) {
out();
in();
}
//文件输出流(写入文件)
private static void out() {
//确定目标文件
File file = new File("/home/xiaoming/音乐/java/vince.text");
//构建一个文件输出流对象
try {
OutputStream out = new FileOutputStream(file,true);//第二个参数append默认为false,true时表示追加
//输出(写入)的内容
String info = "小桥流水人家\n";
//把内容写入文件
out.write(info.getBytes());//write方法接收byte类型参数
//关闭流
out.close();
System.out.println("输出成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//文件写入流(输出文件内容)
private static void in() {
//确定目标文件
File file = new File("/home/xiaoming/音乐/java/vince.text");
//构建一个文件输入流对象
try {
InputStream in = new FileInputStream(file);
byte[] bytes = new byte[1024];//单数用中文会造成乱码,解决办法使用字符流
StringBuilder buf = new StringBuilder();
int len = -1;//表示每次读取的长度
//把数据读入数组中,并返回每次读取的字节数,当不等于-1时表示读取到数据,等于-1表示读取不到数据
/*
* @Return
* the total number of bytes read into the buffer,
* or -1 if there is no more data
* because the end of the stream has been reached.
*/
while((len = in.read(bytes))!=-1) {
//根据读取到的字节数组,再转换为字符串内容,添加到StringBuilder中
//当读取的字符数多余字符数组大小时,新读的内容会自动替换掉从头已读的内容,但后面的原有已读内容任然保留,这时候需要加入len指定读取到的位置,避免最后读出的内容与前面重复
buf.append(new String(bytes,0,len));
}
//打印内容
System.out.println(buf);
//关闭输入流
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符输出,输入流
字符流的内部实现还是字节流
字符输出流:Writer
,对文件的操作使用子类FileWriter
字符输入流:Reader
,对文件的操作使用子类FileReader
每次操作都是一个字符
文件字符操作流会自带缓存,默认大小为1024字节,在缓存满或手动刷新或关闭流时会写入文件,但是字节操作流没有缓存,直接写入
一般操作非文本文件时,使用字节流,操作文本文件时,使用字符流
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
//字符流
public class CharStreamDemo {
public static void main(String[] args) {
out();
in();
}
// 字符输出流
private static void out() {
File file = new File("/home/xiaoming/音乐/java/vince.text");
try {
Writer out = new FileWriter(file, true);
out.write("小桥流水人家,古道西风瘦马\r\n");
System.out.println("写入文件成功");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 字符输入流
private static void in() {
File file = new File("/home/xiaoming/音乐/java/vince.text");
try {
Reader in = new FileReader(file);
char[] cs = new char[5];
int len = -1;
StringBuilder buf = new StringBuilder();
while((len = in.read(cs))!=-1) {
buf.append(new String(cs,0,len));
}
System.out.println(buf);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节字符转换流
OutputStreamWriter
:可以将输出的字符转换成字节流的输出形式InputStreamReader
:可以将输入的字节流转化为字符形式的输入流
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
//字节字符转换流
public class StreamChangeDemo {
public static void main(String[] args) {
File file = new File("/home/xiaoming/音乐/java/vince.text");
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(file);
out = new FileOutputStream(file,true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
read(in);
write(out);
}
//输入流:字节转字符
private static void read(InputStream in) {
//将字节输入流转换成字符输入流,可以指定编码方法
Reader reader = new InputStreamReader(in,Charset.defaultCharset());
char[] cs = new char[1024];
int len = -1;
try {
while((len = reader.read(cs)) != -1) {
System.out.println(new String(cs,0,len));
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//输出流:字符转字节
private static void write(OutputStream out) {
Writer writer = new OutputStreamWriter(out);
try {
writer.write("新年快乐!!!");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节字符缓冲流
先将数据缓冲起来,再一起写入或者读取出来,提高效率BufferedInputStream
,BufferedOutputStream
为两个字节缓冲流的类
内部默认缓存大小为8KB,每次写入时存储到缓存中的byte数组,当数组存满时,会把数组中的数据写入文件,并且缓存下标归零BufferedReader
BufferedWriter
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.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
public class BufferStreamDemo {
public static void main(String[] args) {
byteWriter();
byteReader();
charWriter();
charReader();
}
//缓冲字节输出
private static void byteWriter() {
File file = new File("/home/xiaoming/音乐/java/vince.text");
try {
OutputStream out = new FileOutputStream(file,true);
//构造一个字节缓冲流
BufferedOutputStream bos = new BufferedOutputStream(out);
String info = "枯藤老树昏鸦\r\n";
bos.write(info.getBytes());
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//缓冲字节输入
private static void byteReader() {
File file = new File("/home/xiaoming/音乐/java/vince.text");
try {
InputStream in = new FileInputStream(file);
//构造缓冲流
BufferedInputStream bis = new BufferedInputStream(in);
byte[] bytes = new byte[1024];
int len = -1;
while((len = bis.read(bytes))!=-1) {
System.out.println(new String(bytes,0,len));
}
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//缓冲字符输出
private static void charWriter() {
File file = new File("/home/xiaoming/音乐/java/vince.text");
try {
Writer writer = new FileWriter(file,true);
//构造缓存器
BufferedWriter bw = new BufferedWriter(writer);
bw.write("夕阳西下\r\n");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//缓冲字符输入
private static void charReader() {
File file = new File("/home/xiaoming/音乐/java/vince.text");
try {
Reader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader);
char[] cs = new char[1024];
int len = -1;
while((len=br.read(cs))!=-1) {
System.out.println(new String(cs,0,len));
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
打印流
便利输出PrintStream
PrintWriter
File file = new File("xxxx");
OutputStream out = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(out);//加缓存
PrintStream ps = new PrintStream(bos);//增强打印流
ps.println("xxxxx");
ps.close;
对象流和序列化
序列化:将对象的状态信息转化为可以存储或传输的形式
反序列化:将已经序列化的对象重新转换成对象的状态信息
对象流的两个类:ObjectOutputStream
将java对象的基本数据类型和图形写入OutputStream,ObjectInputStream
对写入ObjectOutputStream的基本数据和对象进行反序列化
需要序列化的情况:
- 把对象保存到文件中
- 对象需要在网络中传输时
import java.io.Serializable;
//继承标记接口表示该类需要进行序列化,否则会报java.io.NotSerializableException错误
public class Dog implements Serializable{
/**
* 定义版本号,防止两个不同对象因属性一样造成混乱
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String sex;
//可以使用关键字transient声明一个变量在存储时不需要维持其具体值(默认0或null)
private transient int id;
public Dog() {
super();
}
public Dog(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String toString() {
return "Dog [name=" + name + ", age=" + age + ", sex=" + sex + ", getName()=" + getName() + ", getAge()="
+ getAge() + ", getSex()=" + getSex() + "]";
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class ObjectStreamDemo {
public static void main(String[] args) {
writeObject();
readObject();
}
//对象序列化
public static void writeObject() {
Dog dog = new Dog("猪猪",6,"girl");
//当要读取多个对象时,使用数组
//Dog[] dogs = {dog1,dog2};
File file = new File("/home/xiaoming/音乐/java/ObjectStream.text");
try {
OutputStream out = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(dog);//多个时改为dogs
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//对象反序列化
public static void readObject() {
Dog dog = new Dog("猪猪",6,"girl");
File file = new File("/home/xiaoming/音乐/java/ObjectStream.text");
try {
InputStream in = new FileInputStream(file);
ObjectInputStream ois= new ObjectInputStream(in);
Dog dog2 = (Dog)ois.readObject();
//多个时:Dog[] dog = (Dog[])ois.readObject();
System.out.println(dog2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
字节数组流
基于内存操作,内部维护着一个字节数组,可以利用流的读取机制来处理字符串
与文件操作无关,无需关闭ByteArrayInputStream
ByteArrayOutputStream
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public class ByteArrayStreamDemo {
public static void main(String[] args) {
byteArray();
}
private static void byteArray() {
String s = "123456789sljtiegrgGRGFRTGAFWER(*&*^&%%$@#)";
ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int curr = -1;//每次读取的字节
while((curr = bais.read())!=-1) {
if((curr>=65 && curr<=90) || (curr>=97 && curr<=122)) {
baos.write(curr);
}
}
//此时无需关闭,因为字节数组流是基于内存的操作流
System.out.println(baos.toString());
}
}
数据流
应用程序以与机器无关的方式从底层输出或输入java基本数据类型DataInputStream
DataOutputStream
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class DataStreamDemo {
public static void main(String[] args) {
write();
read();
}
private static void write() {
File file = new File("/home/xiaoming/音乐/java/vince.data");
try {
OutputStream out = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(out);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(15);//4个字节
dos.writeByte(1);//写入1个字节
dos.writeUTF("花花卡");
dos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void read() {
File file = new File("/home/xiaoming/音乐/java/vince.data");
try {
InputStream in = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(in);
DataInputStream dis = new DataInputStream(bis);
int num = dis.readInt();
byte b = dis.readByte();
String s =dis.readUTF();
System.out.println(num+","+b+","+s);
dis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件分割与合并
合并流SequenceInputStream
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/*
* 文件的分割和合并
*/
public class FileDivisionMergeDemo {
public static void main(String[] args) {
//分割
File file = new File(
"/media/M_fM__VM__GM_fM_!M_#/编程语言/Java/课程/千锋Java基础教程-Java基础(完结-217集)/千锋java基础教程:第10章 多线程与并发(12集)/第10章 多线程与并发_12_线程生命周期与线程池_小结.mp4");
division(file, 1024 * 1024 * 10);
System.out.println("分割成功");
//合并
Vector<InputStream> v = new Vector<InputStream>();
for(int i=1;i<=59;i++) {
try {
InputStream in = new FileInputStream(new File("/home/xiaoming/音乐/java/花花卡" + i + ".mp4"));
v.add(in);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Enumeration<InputStream> es = v.elements();
merge(es);
}
/**
* 文件切割
*
* @param file 要切割的文件
* @param cutSite 切割后每份文件的大小
*/
private static void division(File targetFile, long cutSize) {
if (targetFile == null)
return;
// 计算文件的总分割数
int num = (targetFile.length() % cutSize == 0) ? (int) (targetFile.length() / cutSize)
: (int) ((targetFile.length() / cutSize) + 1);
try {
// 构造一个文件输入流
BufferedInputStream in = new BufferedInputStream(new FileInputStream(targetFile));
BufferedOutputStream out = null;
byte[] bytes = null;// 每次希望读取的最大字节数
int len = -1;// 每次读取的字节数
int count = 0;// 每一个文件要读取的次数
for (int i = 1; i < num; i++) {
out = new BufferedOutputStream(new FileOutputStream("/home/xiaoming/音乐/java/花花卡" + i + ".mp4"));
if (cutSize <= 1024) {
bytes = new byte[(int) cutSize];
count = 1;
} else {
bytes = new byte[1024];
count = (int) cutSize / 1024;
}
// 边读边写入,不然会刷新数组,写入不了
// 判断条件应该把读放在后面,防止多读一次
while (count > 0 && (len = in.read(bytes)) != -1) {
out.write(bytes);
out.flush();
count--;
}
// 如果余数不为零,数组不整除就需要多读一遍
if ((int) cutSize % 1024 != 0) {
bytes = new byte[(int) cutSize % 1024];
len = in.read(bytes);
out.write(bytes, 0, len);
out.flush();
}
out.close();// 关闭本次输出流
}
in.close();// 最后才关闭输入流
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void merge(Enumeration<InputStream> es) {
//构造一个合并流
SequenceInputStream sis = new SequenceInputStream(es);
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("/home/xiaoming/音乐/java/花花卡.mp4"));
byte[] bytes = new byte[1024];
int len = -1;
while((len=sis.read(bytes))!=-1) {
bos.write(bytes,0,len);
bos.flush();
}
bos.close();
sis.close();
System.out.println("合并完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符串流
StringReader
以一个字符串为数据源,来构造一个字符流StringWriter
无需关闭
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
//字符串流
public class StringStreamDemo {
private static void stringReader() {
String info = "中 大 奖,花 呗 免 单!";
StringReader sr = new StringReader(info);
//流标记器
StreamTokenizer st = new StreamTokenizer(sr);
int count = 0;//计算总数
//TT_EOF表示读到流的末尾,ttype是每一次读取返回的类型
while(st.ttype != StreamTokenizer.TT_EOF) {
try {
//TT_WORD表示读取的内容是文字
if(st.nextToken()==StreamTokenizer.TT_WORD) {
count++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
sr.close();
System.out.println("count="+count);
}
public static void main(String[] args) {
stringReader();
}
}
RandomAccessFile
直接继承Object类,只可以对文件进行操作,有两种模式(r,rw)
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) {
try {
RandomAccessFile r = new RandomAccessFile("/home/xiaoming/音乐/java/vince.text", "r");
RandomAccessFile w = new RandomAccessFile("/home/xiaoming/音乐/java/vince2.text","rw");
byte[] bytes = new byte[1024];
int len = -1;
while((len = r.read(bytes))!= -1) {
w.write(bytes,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("copy success");
}
}
Properties文件操作类
主要用于读取配置文件
//properties配置文件
#update config
#Sun Feb 03 10:58:41 CST 2019
db.password=987654321
db.username=xiaoming
app.version=2
//对配置文件的操作
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
public class PropertiesDemo {
public static String version = "";
public static String username = "";
public static String password = "";
//静态代码块,在创建对象时执行一次
static {
readConfig();
}
/**
* 输出操作
*/
private static void readConfig() {
Properties p = new Properties();
try {
InputStream inStream = new FileInputStream("config.properties");
//当文件不在当前项目根目录下时,使用如下方式指定路径
// InputStream inStream1 = Thread.currentThread().getContextClassLoader()
// .getResourceAsStream("com/res/config.properties");
p.load(inStream);//加载文件
//从properties中获取数据
version = p.getProperty("app.version");
username = p.getProperty("db.username");
password = p.getProperty("db.password");
inStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写入操作
* @param version
* @param username
* @param password
*/
private static void writeConfig(String version,String username,String password) {
Properties p = new Properties();
//把属性写入变量p
p.put("app.version",version);
p.put("db.username", username);
p.put("db.password",password);
try {
OutputStream outStream = new FileOutputStream("config.properties");
//写入文件,第二个参数是注释
p.store(outStream, "update config");
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//readConfig();
writeConfig("2", "xiaoming", "987654321");
System.out.println(PropertiesDemo.version);
System.out.println(PropertiesDemo.username);
System.out.println(PropertiesDemo.password);
}
}
文件压缩和解压缩
压缩:ZipOutputStream
ZipOutputStream(OutputStream out)
:创建新的ZIP输出流void putNextEntry(ZipEntry e)
:开始写入新的ZIP文件条目并将流定位到条目数据的开始处ZipEntry(String name)
:使用指定名创建新的ZIP条目
解压:ZipInputStream
ZipInputStream(InputStream in)
:创建新的ZIP输入流ZipEntry getNextEntry()
:读取写一个ZiP文件条目并将流定位到该条目数据的开始处
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* 压缩和解压缩实例
*
* @author xiaoming
*
*/
public class CompressionAndDecompressionDemo {
public static void main(String[] args) {
File file = new File("/home/xiaoming/音乐/12345");
compression("/home/xiaoming/音乐/123456789.zip", file);
decompression("/home/xiaoming/音乐/123456789.zip", "/home/xiaoming/音乐");
}
/**
* 压缩
*
* @param zipFileName 希望压缩后的文件名(路径)
* @param targetFile 目标文件
* @return
*/
private static void compression(String zipFileName, File targetFile) {
System.out.println("正在压缩...");
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName));
// 添加缓存加快效率
BufferedOutputStream bos = new BufferedOutputStream(out);
// 进行压缩
zip(out, targetFile, targetFile.getName(), bos);
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("压缩完成!!!");
}
/**
* 执行具体的压缩操作
*
* @param out 对文件进行压缩的类
* @param targetFile 目标文件
* @param targetFileName 要压缩文件的文件名
* @param bos 缓存流
* @throws IOException
*/
private static void zip(ZipOutputStream out, File targetFile, String targetFileName, BufferedOutputStream bos)
throws IOException {
// 判断是目录还是文件夹
if (targetFile.isDirectory()) {
// 如果是空目录
if (targetFile.length() == 0) {
out.putNextEntry(new ZipEntry(targetFileName));// 处理空目录
}
File[] files = targetFile.listFiles();
for (File f : files) {
zip(out, f, targetFileName + "/" + f.getName(), bos);
}
} else {
out.putNextEntry(new ZipEntry(targetFileName));
FileInputStream in = new FileInputStream(targetFile);
BufferedInputStream bis = new BufferedInputStream(in);
byte[] bytes = new byte[1024];
int len = -1;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
bis.close();
}
}
/**
* 解压
*
* @param targetFileName 要解压的文件名
* @param parent 解压到的位置
*/
private static void decompression(String targetFileName, String parent) {
// 构造解压的输入流
ZipInputStream zIn;
try {
zIn = new ZipInputStream(new FileInputStream(targetFileName));
ZipEntry entry = null;
File file = null;
while ((entry = zIn.getNextEntry()) != null && !entry.isDirectory()) {
file = new File(parent, entry.getName());
if (!file.exists()) {
new File(file.getParent()).mkdirs();// 创建此文件的上级目录
}
OutputStream out = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(out);
byte[] bytes = new byte[1024];
int len = -1;
while ((len = zIn.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
bos.close();
System.out.println(file.getAbsolutePath() + "解压成功");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
New IO(NIO)
原来的IO采用流的方式处理数据,为NIO以块的方式处理数据,效率更高,在NIO中,所有的数据都是在缓冲区处理,缓冲区实际上是一个数组
缓冲区
缓冲区的类型:
- ByteBuffer
- CharBuffer
- ShortBuffer
- LongBuffer
- DoubleBuffer
- IntBuffer
- FloatBuffer
package nio;
import java.nio.ByteBuffer;
public class NIODemo {
public static void main(String[] args) {
//创建一个字节缓冲区,申请内存空间为8字节,参数为申请的内存空间
ByteBuffer buf = ByteBuffer.allocate(8);
//查看其内部属性值
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
//向缓冲区写入数据
buf.put((byte)10);
buf.put((byte)20);
buf.put((byte)30);
buf.put((byte)40);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
//缓冲区反转(把limit设置为position的值,并把positon置零),在取值前使用
buf.flip();
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
//取值
//判断当前位置与限制元素之间是否有元素
if(buf.hasRemaining()) {
//返回当前位置与限制之间的元素数
for(int i=0;i<buf.remaining();i++) {
byte b = buf.get(i);//取值
System.out.println(b);
}
}
}
}
通道:Channel
数据通过通道进出缓冲区,Channel是一个类
/**
* 文件复制实例
*/
package nio;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
public class CopyFileDemo {
public static void main(String[] args) {
try {
copyFile();
randomAccessFileCopy();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//NIO方式
private static void copyFile() throws IOException {
//创建一个输入文件的通道
FileChannel in = new FileInputStream("/home/xiaoming/图片/v2-c4a14410a05ed4ddede728e6d467effc_r.jpg").getChannel();
//创建一个输出文件的通道
FileChannel out = new FileOutputStream("/home/xiaoming/音乐/background.jpg").getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
while(in.read(buf)!=-1) {
buf.flip();
out.write(buf);
buf.clear();
}
in.close();
out.close();
System.out.println("copy success");
}
//印射方式
private static void randomAccessFileCopy() throws IOException {
RandomAccessFile in = new RandomAccessFile("/home/xiaoming/图片/v2-c4a14410a05ed4ddede728e6d467effc_r.jpg","r");
RandomAccessFile out = new RandomAccessFile("/home/xiaoming/音乐/background1.jpg", "rw");
FileChannel fcIn = in.getChannel();
FileChannel fcOut = out.getChannel();
long size = fcIn.size();//输入流的字节大小
//输入流的缓冲区
MappedByteBuffer inBuf = fcIn.map(MapMode.READ_ONLY, 0, size);
//输出流的缓冲区
MappedByteBuffer outBuf = fcOut.map(MapMode.READ_WRITE, 0, size);
for(int i=0;i<size;i++) {
outBuf.put(inBuf.get());
}
fcIn.close();
fcOut.close();
in.close();
out.close();
System.out.println("copy success");
}
}
IO操作的性能比较:
- 内存印射最快
- NIO读写
- 使用缓存的IO流
- 普通无缓存IO
Path接口
Path表示一个目录名,表示具体路径
package nio;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
public class PathFileDemo {
public static void main(String[] args) {
File file = new File("/home/xiaoming/音乐/background.jpg");
//path,通过这种方式获取文件
Path p1 = Paths.get("/home/xiaoming/音乐","background.jpg");
System.out.println(p1);
Path p2 = file.toPath();
System.out.println(p2);
//toPath方法的具体实现方法
Path p3 = FileSystems.getDefault().getPath("/home/xiaoming/音乐","background.jpg");
//Files工具类
Path p4 = Paths.get("/home/xiaoming/音乐/工具类.text");
String info = "一闪一闪亮晶晶";
try {
Files.write(p4, info.getBytes("gb2312"), StandardOpenOption.CREATE_NEW);
} catch (IOException e) {
e.printStackTrace();
}
try {
byte[] bytes = Files.readAllBytes(p4);
System.out.println(new String(bytes));
} catch (IOException e) {
e.printStackTrace();
}
//复制(第三个参数可选)
try {
Files.copy(p3, Paths.get("/home/xiaoming/音乐/background2.jpg"),StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//移动文件
try {
Files.move(p3, Paths.get("/home/xiaoming/音乐/background2.jpg"),StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//删除文件
try {
Files.delete(p3);
Files.deleteIfExists(p3);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//创建目录文件
try {
Files.createDirectory(Paths.get("/home/xiaoming/音乐/abc"));//除了最后的一个部件,其他的必须是已存在的
Files.createDirectories(Paths.get("/home/xiaoming/音乐/abc"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//创建文件
try {
Files.createFile(Paths.get("/home/xiaoming/音乐/abc.txt"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//添加前后缀创建临时文件或临时目录
//Path newPath = Files.createTempFile(prefix, suffix, attrs);
//Path newPath = Files.createTempDirectory(dir, prefix);
}
}