File类的使用
File类:表示文件和目录路径名的抽象表示形式。
File类可以实现文件创建、删除、重命名、得到路径、创建时间等是唯一与文件本身有关的操作类。
File类的操作方法
创建文件
File f1 = new File("D:\\test\\vince.txt");
此处文件目录表达形式有三种:
“D:\test\vince.txt”
“D:/test/vince.txt”
“D:”+File.separator+“test”+File.separator+“vince.txt”
File f1 = new File("D:\\test\\vince.txt");
if(!f1.exists()){
try {
f1.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
判断文件是否存在
f1.exists()
是否为文件
f1.isFile()
是否为文件夹
f1.isDirectory()
删除文件夹
f2.delete()
此时文件夹内部需为空,返回值为boolean类型,可以通过输出查看删除是否成功
File f2 = new File("D:\\test\\my");
boolean b = f2.delete();
System.out.println(b);
列出当前目录下所有文件名
f2.list()
以数组返回
f2.listFiles()
以file 对象返回
String[] name = f2.list();
System.out.print(Arrays.toString(name));
File[] fs = f2.listFiles();//列出当前目录下所有文件,以file 对象返回
for (File f :fs) {
System.out.println(f.length());
System.out.println(f.getName());
System.out.println(f.getAbsolutePath());
System.out.println(f.getPath());
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));//最后修改时间
}
新建文件夹
f4.mkdir()
f4.mkdirs()
创建文件夹下很多子目录都没有,统一创建
文件重命名和文件移位
f4.renameTo(new File(""D:\\test\\guo""))
重命名和移位都相当于新建文件,只是路径和名称不同
———————————————————————————————————————————————————————————————
示例:在指定文件夹中查找指定文件
文件夹有多层,需要逐层递归找到文件,并查看文件的格式是否为指定格式
1.创建Private方法,输入分别为文件类型及指定格式
2.判断文件是否为空
3.判断是否为文件夹,文件夹内布递归调用本方法
4.获取文件名并将其转为大写,判断是否以指定格式结尾
private static void findFile(File target,String ext) {
if(target == null)return;
if(target.isDirectory()) {
File[] files = target.listFiles();
if(files!=null) {
for(File f:files) {
findFile(f,ext);//递归调用
}
}
}else {
String name = target.getName().toLowerCase();
if(name.endsWith(ext)) {
System.out.print(target.getAbsolutePath());
}
}
}
———————————————————————————————————————————————————————————————
字节流
IO流:输入输出流
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输(数据传输)
分类斜体样式:字符流、字节流;输入流(文件到程序)、输出流(程序到文件)
字节输出输入流
输出流
OutputStream out = new FileOutputStream(file)
追加true,覆盖false
//选择一个文件
File file = new File("D:\\test\\vince.txt");
OutputStream out = new FileOutputStream(file,true);
//设置一段文字
String info ="小河流水哗啦啦";
out.write(info.getBytes());//需要以字节形式输入
out.close();
输入流
InputStream in = new FileInputStream(file)
//选择一个文件
File file = new File("D:\\test\\vince.txt");
//创造一个缓存空间
byte[] bytes = new byte[1024];
StringBuilder buf = new StringBuilder();//可变字符序列
int len = -1;
//读取文件
InputStream in = new FileInputStream(file);
while((len = in.read(bytes))!=-1) {//返回字节数
buf.append(new String(bytes));
}
//输出内容
System.out.println(buf);
关闭流
in.close();
———————————————————————————————————————————————————————————————
字符流
字符输入输出实现与分析
写入字符抽象类:Writer
读出字符抽象类:Reader
每次操作的单位为一个字符
输出流
File file = new File("D:\\test\\vince.txt");
Writer out = new FileWriter(file);
out.write("小河流水哗啦啦");
out.close();
输入流
File file = new File("D:\\test\\vince.txt");
Reader in = new FileReader(file);
char[] cs = new char[1];
StringBuilder buf = new StringBuilder();
int len = -1;
while((len = in.read(cs))!=-1){
buf.append(new String(cs,0,len));//???
}
in.close();
如何选择字节流和字符流
一般情况下,操作非文本文件(视频、图片),使用字节流;操作文本文件(txt文件),使用字符流。
字符流的内部实现还是字节流
———————————————————————————————————————————————————————————————
简单的文件复制示例
指定一个盘符下的文件,把该文件复制到指定目录下
1.从一个输入流中读取数据
2.同时通过输出流写入数据
private static void copy(String src,String target) {
File srcFile = new File(src);
File targetfile = new File(target);
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(srcFile);
out = new FileOutputStream(targetfile);
byte[] bytes = new byte[1024];
int len = -1;
//StringBuilder buf = new StringBuilder();
while((len = in.read(bytes))!=-1) {
//buf.append(new String(bytes));
out.write(bytes,0,len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(in!=null)in.close();
if(out!=null)out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
———————————————————————————————————————————————————————————————
字节字符转换流
将输出字符流转换为字节流的形式输出OutputStreamWriter
将输入的字节流转换为字符流的输入形式InputStreamReader
InputStreamReader
文件字节->InputStream->InputStreamReader->程序字符
此处代码先确定文件位置(字节流),再将字节流转化为字符流将为文字读出。
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
OutputStreamWriter
程序字符->OutputStreamWriter->OutputStream->文件字节
此处代码先确定文件位置,将字节转化为字符流将文字写入
public static void write(OutputStream out) {
Writer writer = new OutputStreamWriter(out);
try {
writer.write("哈哈哈哈哈");
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
———————————————————————————————————————————————————————————————
字节字符缓冲流
缓冲流:对文件或其他目标频繁的读写操作会造成效率低、性能差。
使用缓冲流的好处是:能够更高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来。
缓冲流不能单独使用,必须与字节字符流一起。
字节缓冲流
BufferedInputStream
字节输入缓冲流
BufferedOutputStream
字节输出缓冲流
1.确定文件
File file = new File("D:\\test\\vince.txt");
2.字节输出流
OutputStream out = new FileOutputStream(file);
3.字节缓冲流
BufferedOutputStream bos = new BufferedOutputStream(out);
4.写入数据
String info = "aaaaa"
bos.write(info.getBytes());
5.关闭缓冲流
bos.close();//自动关闭out,所以后面可以不用写out.close();
//关闭缓存是会刷新缓存,写入内容才会从缓存进入文件
File file = new File("D:\\test\\vince.txt");
InputStream in = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(in);
int len = -1;
byte[] bytes = new byte[1024];
while((len = bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
bis.close();
———————————————————————————————————————————————————————————————
字符缓冲流
BudderedReader
字符输入缓冲流
BufferedWriter
字符输出缓冲流
1.读取时加入字符缓存流会增强读取功能(readLine)
2.更高效的读取数据
FileReader:内部使用InputStreamReader(sun.nio.cs.StreamDecoder),解码过程,byte->char,默认缓存大小是8k。
BufferedReader:默认缓存大小是8k,但可以手动指定缓存大小,把数据拼接进读取到的缓存中,减少每次转换过程,效率更高。
File file = new File("D:\\test\\vince.txt");
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();
File file = new File("D:\\test\\vince.txt");
Writer writer = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(writer);
String info = "aaaaa";
bw.writer(info);
bw.flush();
bw.close();
———————————————————————————————————————————————————————————————
打印流
打印流的功能主要是用于输出,在整个IO包中打印流分为两种类型:
PrintStream
字节打印流,在字节输出时,可以增强输出功能
PrintWriter
字符打印流,在
打印流可以方便的进行输出
File file = new File("D:\\test\\vince.txt");
OutputStream out = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(out);//加缓存
PrintStream ps = new PrintStream(bos);//提高输出便利性增强打印功能
ps.printf("小河流水哗啦啦");
ps.close();
File file = new File("D:\\test\\vince.txt");
Writer out = new FileWriter(file);
BufferedWriter bos = new BufferedWriter(out);
PrintWriter pw = new PrintWriter(bos);
pw.println("xiaohe");
pw.close();
———————————————————————————————————————————————————————————————
对象流与序列化
ObjectOutputStream
将java对象的基本数据类型和图形写入OutputStream
ObjectInputSream
对以前使用ObiectOutputStream写入的基本数据和对象进行反序列化
序列化
在序列化的操作中,同时序列化多个对象,反序列化也必须按顺序操作.
序列化一组对象可采用对象数组的形式,因为对象数组可以向Object进行转型操作.
步骤Output
1.创建一个类.如果一个类创建的对象需要被序列化,那么该类必须实现Serializable接口(标记接口,无任何定义,为了告诉JVM虚拟机该类对象可以被序列化)
public class Dog implements Serializable
2.创建对象
Dog dog = new Dog("wang","mu",2);
3.对象序列化
File file = new File("D:\\test\\dog.obj");//扩展名可以随意定义
OutputStream out = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(dog);
oos.close();
步骤Input
File file = new File("D:\\test\\dog.obj");
InputStream in = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(in);
Dog dog = (Dog)ois.readObject();
ois.close();
System.out.println(dog);
注意:什么时候对象需要被序列化?(有且只有)
1.把对象保存到文件中(存储到物理介质)
2.对象需要在网络上传输
一组对象
Dog dog = new Dog("wang","mu",2);
Dog dog2 = new Dog("wa","mu",3);
Dog[] dogs = {dog,dog2};
...
oos.writeObject(dogs);
Dog[] dogs = (Dog[] )ois.readObject();
...
System.out.println(dogs[0]);
System.out.println(dogs[1]);
transient关键字
如果用transient声明一个实例变量,当对象存储时,它不需要维持(想要忽视某一个字段)
private String name;
private String sex;
private int age;
private transient int id;//当对象序列化时忽略此属性,同样反序列化时该属性为默认值eg:0
———————————————————————————————————————————————————————————————
字节数组流
ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪read方法要提供的下一个字节.关闭ByteArrayInputStream无效.此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException.
ByteArrayOutputStream此类实现了一个输出流,其中数据被写入一个byte数组.缓冲区会随着数据的不断写入而自动增长.可使用toByteArray()和toString()获取数据.关闭ByteArrayOutputStream无效.此类方法在关闭此流后仍可被调用,而不会产生任何IOException.
基于内存操作,内部维护一个字节数组,我们可以利用流的读取机制来处理字符串
//求字符串当中的所有字母,包括大小写。
String s = "1234asdfgh#$%%^&&*"
ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());//需要以字节为单位
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = -1;
while((len = bais.read())!=-1){
if((len>=65&&len<=90) || (len>=98&&len<=122)){
baos.write(len);
}
}//此时无需关闭,字节数组流是基于内存的操作流
System.out.println(baos.toString());
System.out.println(baos.size());
———————————————————————————————————————————————————————————————
数据流
DataInputStream数据输入流允许应用程序以与机器无关的方式从底层输入流中读取基本java数据类型.应用程序可以使用数据输出流写入稍后由数据输入流读取数据.DataInputStream多线程访问不一定安全.
DataOutputStream数据输出流允许应用程序以适当方式将基本java数据类型写入输出流中.然后,应用程序可以使用数据输入流将数据读入.
File file = new File("D:\\test\\vince.txt");
OutputStream out = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(out);
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(10);//写入4个字节(int基本数据类型占4个字节)
dos.writeByte(1);//一个字节
dos.writeUTF("中");//五个字节
dos.close();
File file = new File("D:\\test\\vince.txt");
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();
———————————————————————————————————————————————————————————————