通过本文,可以详细的了解JDK关于目录和文件API操作。关注公众号,输入“java-summary”即可获得源码。
一、java.io.File
java.io.File类用于描述文件系统中的一个文件或目录 该类可以:
1、访问文件或目录的属性信息
2、访问一个目录中的所有子项
3、操作文件或目录(创建、删除)
该不可以:
访问文件的具体内容
开发时注意不同操作系统的路径的表示方法的差异(如’/‘或’\’),使用File.separator可以屏蔽不同操作系统的路径的差异。
1.读取文件属性
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
import java
.text
.SimpleDateFormat
;
import java
.util
.Date
;
public class FileDemo1 {
public static void main(String
[] args
) {
File file
= new File("." + File
.separator
+ "test.txt");
System
.out
.println(file
);
String name
= file
.getName();
System
.out
.println("文件名:"+name
);
long length
= file
.length();
System
.out
.println("文件大小(字节):"+length
);
long time
= file
.lastModified();
System
.out
.println(time
);
Date date
= new Date();
date
.setTime(time
);
SimpleDateFormat sdf
= new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
String str
= sdf
.format(date
);
System
.out
.println(str
);
file
.canRead();
file
.canWrite();
file
.canExecute();
file
.isHidden();
System
.out
.println(file
.getPath());
}
}
2.创建文件
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
import java
.io
.IOException
;
public class FileDemo2 {
public static void main(String
[] args
) throws IOException
{
File file
= new File("." + File
.separator
+ "demo.txt");
if(! file
.exists()){
boolean flag
= file
.createNewFile();
System
.out
.println("创建成功" + flag
);
}else{
System
.out
.println("创建失败");
}
}
}
3.删除文件
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
public class FileDemo3 {
public static void main(String
[] args
) {
File file
= new File("demo.txt");
if(file
.exists()){
file
.delete();
System
.out
.println("已删除");
}else{
System
.out
.println("文件不存在");
}
}
}
4.创建一个目录
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
public class FileDemo4 {
public static void main(String
[] args
) {
File file
= new File("demo");
if(! file
.exists()){
file
.mkdir();
System
.err
.println("创建成功");
}else{
System
.out
.println("目录已经存在");
}
}
}
5.创建多级目录
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
public class FileDemo5 {
public static void main(String
[] args
) {
File file
= new File("a" + File
.separator
+"b" + File
.separator
+"c" + File
.separator
+"d" + File
.separator
+"e" );
if(! file
.exists()){
file
.mkdirs();
System
.out
.println("创建成功");
}else{
System
.out
.println("目录已存在");
}
}
}
6.删除目录
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
public class FileDemo6 {
public static void main(String
[] args
) {
File dir
= new File("demo");
if(dir
.exists()){
dir
.delete();
System
.out
.println("已删除");
}else{
System
.out
.println("不存在");
}
}
}
7.获取一个目录的所有子项
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
public class FileDemo7 {
public static void main(String
[] args
) {
File file
= new File(".");
if(file
.isDirectory()){
File
[] sub
= file
.listFiles();
for(File f
: sub
){
System
.out
.println(f
.getName());
}
}
}
}
8.过滤一个目录中的部分子项
package com
.wuxiaolong
.file
.directory
;
import java
.io
.File
;
import java
.io
.FileFilter
;
public class FileDemo8 {
public static void main(String
[] args
) {
File dir
= new File("." );
System
.out
.println(dir
);
File
[] sub
= dir
.listFiles(
new FileFilter(){
@Override
public boolean accept(File file
){
System
.out
.println("正在过滤:" +file
.getName());
return file
.getName().startsWith(".");
}
}
);
for(File tmp
: sub
){
System
.out
.println(tmp
.getName());
}
}
}
二、java.io.RandomAccessFile
java.io.RandomAccessFile类用于读写文件数据。其基于指针对文件进行读写。由于是基于指针,一个字节一个字节的读写,效率较低,一般用的少。
创建RandomAccessFile有两种方式:
1:“r”,即只读模式,仅仅对文件数据进行读取2:”rw“,即读写模式,对文件数据可以编辑。
1.一个字节一个字节写文件
package com
.wuxiaolong
.file
.directory
;
import java
.io
.FileNotFoundException
;
import java
.io
.IOException
;
import java
.io
.RandomAccessFile
;
public class RandomAccessFileDemo1 {
public static void main(String
[] args
) throws IOException
{
RandomAccessFile raf
= new RandomAccessFile("raf.dat", "rw");
int a
=1;
raf
.write(a
);
a
=98;
raf
.write(a
);
a
=99;
raf
.write(a
);
System
.out
.println("写入硬盘完毕");
raf
.close();
}
}
2.一个字节一个字节读文件
package com
.wuxiaolong
.file
.directory
;
import java
.io
.FileNotFoundException
;
import java
.io
.IOException
;
import java
.io
.RandomAccessFile
;
public class RandomAccessFileDemo2 {
public static void main(String
[] args
) throws IOException
{
RandomAccessFile raf
= new RandomAccessFile("raf.dat","r");
int d
= raf
.read();
System
.out
.println(d
);
d
= raf
.read();
System
.out
.println(d
);
d
= raf
.read();
System
.out
.println(d
);
d
= raf
.read();
System
.out
.println(d
);
raf
.close();
}
}
3.一个字节一个字节复制文件
package com
.wuxiaolong
.file
.directory
;
import java
.io
.IOException
;
import java
.io
.RandomAccessFile
;
public class CopyDemo1 {
public static void main(String
[] args
) throws IOException
{
RandomAccessFile raf
= new RandomAccessFile("abc.exe","r");
RandomAccessFile cp
= new RandomAccessFile("abc.exe","rw");
long start
= System
.currentTimeMillis();
int d
=-1;
while((d
=raf
.read()) != -1 ){
cp
.write(d
);
}
long end
= System
.currentTimeMillis();
System
.out
.println("复制完成,耗时:" + (end
- start
) + "ms");
}
}
4.自定义缓存复制文件
package com
.wuxiaolong
.file
.directory
;
import java
.io
.IOException
;
import java
.io
.RandomAccessFile
;
public class CopyDemo2 {
public static void main(String
[] args
) throws IOException
{
RandomAccessFile src
= new RandomAccessFile("firefox.exe","r");
RandomAccessFile aim
= new RandomAccessFile("firefox_cp2.exe","rw");
int length
= -1;
byte[] buf
= new byte[1024*10];
long start
= System
.currentTimeMillis();
while((length
=src
.read(buf
)) != -1){
aim
.write(buf
,0,length
);
}
long end
= System
.currentTimeMillis();
System
.out
.println("复制完成。耗时:" +(end
- start
) + "ms.");
}
}
5.读写基本类型数据
package com
.wuxiaolong
.file
.file1
;
import java
.io
.IOException
;
import java
.io
.RandomAccessFile
;
public class RandomAccessFileDemo3 {
public static void main(String
[] args
) throws IOException
{
RandomAccessFile raf
= new RandomAccessFile("raf.txt","rw");
raf
.writeInt( Integer
.MAX_VALUE
);
raf
.writeLong(Long
.MAX_VALUE
);
raf
.writeDouble(123.456);
System
.out
.println("完成");
long pos
= raf
.getFilePointer();
System
.out
.println("position:" + pos
);
raf
.seek(0);
int value1
= raf
.readInt();
System
.out
.println(value1
);
pos
= raf
.getFilePointer();
System
.out
.println("pos:" + pos
);
raf
.seek(4);
long value2
= raf
.readLong();
System
.out
.println(value2
);
System
.out
.println(Long
.MAX_VALUE
);
pos
= raf
.getFilePointer();
System
.out
.println("pos:" + pos
);
raf
.seek(12);
double value3
= raf
.readDouble();
System
.out
.println(value3
);
pos
= raf
.getFilePointer();
System
.out
.println("pos:" + pos
);
}
}
6.读写字符串
package com
.wuxiaolong
.file
.file1
;
import java
.io
.IOException
;
import java
.io
.RandomAccessFile
;
public class RandomAccessFileDemo4 {
public static void main(String
[] args
) throws IOException
{
RandomAccessFile raf
= new RandomAccessFile("raf.txt","rw");
String str
= "诸葛小猿";
byte[] arr
= str
.getBytes("utf-8");
raf
.write(arr
);
System
.out
.println("完成");
raf
.seek(0);
byte[] buf
= new byte[40];
int len
= raf
.read(buf
);
String s
= new String(buf
,0,len
,"utf-8");
System
.out
.println(s
);
raf
.close();
}
}
三、java.io.FileInputStream和java.io.FileOutputStream
输入流都有一个抽象父类:java.io.InputStream,他是所有字节输入流的父类。FileInputStream是InputStream的子类,是文件字节输入流,是一个低级流(节点流),其使用方式和RandomAccessFile一致。InputStream及其子类只负责读文件,不负责写文件。
输出流都有一个抽象父类:java.io.OutputStream,他是所有字节输出流的父类。FileOutputStream是OutputStream的子类,是文件字节输出流,是一个低级流(节点流),其使用方式和RandomAccessFile一致。OutputStream及其子类只负责写文件,不负责读文件。
1.FileInputStream读文件
package com
.wuxiaolong
.file
.file1
;
import java
.io
.FileInputStream
;
import java
.io
.IOException
;
public class FISDemo {
public static void main(String
[] args
) throws IOException
{
FileInputStream fis
= new FileInputStream("abc.txt");
byte[] data
= new byte[100];
int len
= fis
.read(data
);
String str
= new String(data
,0,len
,"gbk");
System
.out
.println(str
);
fis
.close();
}
}
2.FileOutputStream写文件
package com
.wuxiaolong
.file
.file1
;
import java
.io
.FileOutputStream
;
import java
.io
.IOException
;
public class FOSDemo1 {
public static void main(String
[] args
) throws IOException
{
FileOutputStream fos
= new FileOutputStream("abc.txt",true);
fos
.write("诸葛小猿。".getBytes());
System
.out
.println("完成");
fos
.write("你好".getBytes());
fos
.close();
}
}
3.FileInputStream和FileOutputStream拷贝文件
package com
.wuxiaolong
.file
.file1
;
import java
.io
.FileInputStream
;
import java
.io
.FileOutputStream
;
import java
.io
.IOException
;
public class CopyDemo {
public static void main(String
[] args
) throws IOException
{
FileInputStream fis
= new FileInputStream("abc.exe");
FileOutputStream fos
= new FileOutputStream("abc.exe",true);
byte[] b
= new byte[1204*10];
int len
=-1;
while((len
=fis
.read(b
)) != -1){
fos
.write(b
,0,len
);
}
fis
.close();
fos
.close();
System
.out
.println("完成复制");
}
}
四、java.io.BufferedInputStream和java.io.BufferedOutputStream
BufferedInputStream和BufferedOutputStream是一对缓冲流,属于高级流(处理流),用于处理低级流(节点流)的数据,使用它们可以提高读写的效率(先将数据写入缓冲区,在写入硬盘,减少了读写次数)。缓冲流单独存在没意义,必须和低级流一起使用。
1.使用缓冲流复制文件
package com
.wuxiaolong
.file
.file1
;
import java
.io
.BufferedInputStream
;
import java
.io
.BufferedOutputStream
;
import java
.io
.FileInputStream
;
import java
.io
.FileOutputStream
;
import java
.io
.IOException
;
public class CopyDemo2 {
public static void main(String
[] args
) throws IOException
{
FileInputStream fis
= new FileInputStream("abc.exe");
BufferedInputStream bis
= new BufferedInputStream(fis
);
FileOutputStream fos
= new FileOutputStream("abc.cp.exe");
BufferedOutputStream bos
= new BufferedOutputStream(fos
);
int len
= -1;
while((len
= bis
.read()) != -1){
bos
.write(len
);
}
System
.out
.println("复制完成");
bis
.close();
bos
.close();
}
}
2.手动将缓存中的数据刷到磁盘
package com
.wuxiaolong
.file
.file1
;
import java
.io
.BufferedOutputStream
;
import java
.io
.FileOutputStream
;
import java
.io
.IOException
;
public class BOSDemo {
public static void main(String
[] args
) throws IOException
{
FileOutputStream fos
= new FileOutputStream("abc.txt");
BufferedOutputStream bos
= new BufferedOutputStream(fos
);
bos
.write("诸葛小猿".getBytes());
bos
.flush();
System
.out
.println("完成");
bos
.close();
}
}
五、java.io.ObjectInputStream和java.io.ObjectOutputStream
ObjectInputStream和ObjectOutputStream是一对对象流,属于高级流,ObjectInputStream可以读取一组字节转化为java对象,而ObjectOutputStream的作用是可以直接将java中的一个对象转化为一组字节后输出。这其实就是java对象的序列化和反序列化,因此java对象必须要实现序列化接口。
1.定义一个对象
package com
.wuxiaolong
.file
.file1
;
import lombok
.*
;
import java
.io
.Serializable
;
import java
.util
.List
;
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable{
private static final long serialVersionUID
= 1L
;
private String name
;
private int age
;
private transient List
<String> otherInfo
;
}
2.对象序列化
package com
.wuxiaolong
.file
.file1
;
import java
.io
.FileOutputStream
;
import java
.io
.IOException
;
import java
.io
.ObjectOutputStream
;
import java
.util
.ArrayList
;
import java
.util
.List
;
public class OOSDemo {
public static void main(String
[] args
) throws IOException
{
Person p
= new Person();
p
.setName("诸葛小猿");
p
.setAge(30);
List
<String> otherInfo
= new ArrayList<String>();
otherInfo
.add("一个彷徨中奋斗的互联网民工");
otherInfo
.add("爱好打篮球");
p
.setOtherInfo(otherInfo
);
System
.out
.println(p
);
FileOutputStream fos
= new FileOutputStream("wuxl.obj");
ObjectOutputStream oos
= new ObjectOutputStream(fos
);
oos
.writeObject(p
);
System
.out
.println("成功");
oos
.close();
}
}
3.对象反序列化
package com
.wuxiaolong
.file
.file1
;
import java
.io
.FileInputStream
;
import java
.io
.IOException
;
import java
.io
.ObjectInputStream
;
public class OISDemo {
public static void main(String
[] args
) throws ClassNotFoundException
, IOException
{
FileInputStream fis
= new FileInputStream("wuxl.obj");
ObjectInputStream ois
= new ObjectInputStream(fis
);
Person p
= (Person
) ois
.readObject();
System
.out
.println(p
);
ois
.close();
}
}
六、java.io.InputStreamReader和java.io.OutputStreamWriter
java根据读写数据单位不同,将流分为:字节流与字符流。
字节流的最小读写单位是一个字节,前面介绍的InputStream和OutputStream都属于这一类。
字符流的最小读写单位是一个字符,字符流虽然是以字符为单位读写数据,其底层实际上还是要以字节的形式读写,所以字符流天生就具备将字节转换为字符或字符转换成字节的能力,所以所有的字符流都是高级流,方便我们读写字符数据,无需再关心字符与字节的相互转换。字符流的父类java.io.Reader和java.io.Writer,他们是以char为单位读写,转换为Unicode,他们规定了字符流的基本方法。这里介绍两个常用的字符流java.io.InputStreamReader和java.io.OutputStreamWriter的使用。字符是高级流,也需要和低级流联合使用。
除了InputStreamReader与OutputStreamWriter之外的字符流,大部分都只处理其他字符流。但是低级流都是字节流,这时若希望用一个字符流来处理一个字节流就会产生冲突。所以可以通过创建InputStreamReader与OutputStreamWriter来处理字节流,而InputStreamReader与OutputStreamWriter本身是字符流,所以可以使得其他字符流得以处理该流。这样,InputStreamReader与OutputStreamWriter相当于联系字节流和字符流的纽带,类似转化器的效果,因此这两个流也叫转换流。
1.OutputStreamWriter写文件
package com
.wuxiaolong
.file
.file2
;
import java
.io
.FileOutputStream
;
import java
.io
.IOException
;
import java
.io
.OutputStreamWriter
;
public class OSWDeom {
public static void main(String
[] args
) throws IOException
{
FileOutputStream fos
= new FileOutputStream("aa.txt");
OutputStreamWriter osw
= new OutputStreamWriter(fos
,"UTF-8");
osw
.write("诸葛小猿");
osw
.write("程序员");
String str
= "攻城狮";
char[] buf
= str
.toCharArray();
osw
.write(buf
,0,buf
.length
);
System
.out
.println("成功");
osw
.close();
}
}
2.InputStreamReader读文件
package com
.wuxiaolong
.file
.file2
;
import java
.io
.FileInputStream
;
import java
.io
.IOException
;
import java
.io
.InputStreamReader
;
public class ISRDemo {
public static void main(String
[] args
) throws IOException
{
FileInputStream fis
= new FileInputStream("abc.txt");
InputStreamReader isr
= new InputStreamReader(fis
,"GBK");
int len
= -1;
while((len
= isr
.read()) != -1){
char d
= (char) len
;
System
.out
.print(d
);
}
}
}
七、java.io.BufferedReader和java.io.BufferedWriter
BufferedWriter 和BufferedRead是缓冲字节流,属于高级流,按行读取字符串。由于这两个字符流不能直接处理字节流,所以需要InputStreamReader和OutputStreamWriter这两个转换流做纽带,将低级字节流和BufferedReader、BufferedWriter关联起来。
虽然这两个流读写的速度快,但是没有太多的方法可以使用,所有使用的较少。下面只测试一下java.io.BUfferedReader。
package com
.wuxiaolong
.file
.file2
;
import java
.io
.BufferedReader
;
import java
.io
.FileInputStream
;
import java
.io
.IOException
;
import java
.io
.InputStreamReader
;
public class BRDemo {
public static void main(String
[] args
) throws IOException
{
FileInputStream fis
= new FileInputStream("abc.txt");
BufferedReader br
= new BufferedReader(new InputStreamReader(fis
, "GBK"));
String line
= null
;
while((line
= br
.readLine()) != null
){
System
.out
.println(line
);
}
br
.close();
}
}
八、java.io.PrintWriter
缓冲字节流 java.io.PrintWriter,是一种比较常用的输出流。其内部维护了一个缓冲区(字节数组),按行写字符串,写字符效率高。内部自动处理BufferedWriter来完成缓冲操作, 并且PrintWriter具有自动行刷新功能。
1.PrintWriter写文件
package com
.wuxiaolong
.file
.file2
;
import java
.io
.FileNotFoundException
;
import java
.io
.PrintWriter
;
import java
.io
.UnsupportedEncodingException
;
public class PWDemo1 {
public static void main(String
[] args
) throws FileNotFoundException
, UnsupportedEncodingException
{
PrintWriter pw
= new PrintWriter("abc.txt","utf-8");
pw
.println("诸葛小猿");
pw
.println("诸葛小小猿");
pw
.println("诸葛小小小猿");
System
.out
.println("finished!");
pw
.close();
}
}
2.PrintWriter处理其他流
package com
.wuxiaolong
.file
.file2
;
import java
.io
.FileNotFoundException
;
import java
.io
.FileOutputStream
;
import java
.io
.OutputStreamWriter
;
import java
.io
.PrintWriter
;
import java
.io
.UnsupportedEncodingException
;
public class PWDemo2 {
public static void main(String
[] args
) throws FileNotFoundException
, UnsupportedEncodingException
{
FileOutputStream fos
= new FileOutputStream("abc.txt");
OutputStreamWriter osw
= new OutputStreamWriter(fos
,"UTF-8");
PrintWriter pw
= new PrintWriter(osw
);
pw
.println("诸葛小猿");
pw
.println("诸葛小小猿");
System
.out
.println("成功");
pw
.close();
}
}
3.PrintWriter自动行刷新
package com
.wuxiaolong
.file
.file2
;
import java
.io
.FileNotFoundException
;
import java
.io
.FileOutputStream
;
import java
.io
.OutputStreamWriter
;
import java
.io
.PrintWriter
;
import java
.util
.Scanner
;
public class PWDemo3 {
public static void main(String
[] args
) throws FileNotFoundException
{
PrintWriter pw
= new PrintWriter(new OutputStreamWriter( new FileOutputStream("noteBook.txt")),true);
System
.out
.println("请输入文件内容:");
Scanner sc
= new Scanner(System
.in
);
while(true){
String str
= sc
.nextLine();
if("exit".equals(str
)){
System
.out
.println("结束");
break;
}
pw
.println(str
);
}
pw
.close();
}
}
总结:
1.RandomAccessFile可以在任意位置读写。默认情况下,每次读写都会从头开始,写时不会覆盖所有内容,只会覆盖当前位置的内容。基于指针操作,可以在任意位置编辑,但是效率较低。
一个Stream流要么读,要么写。要么覆盖所有内容从头重写,要么在原有基础上追加。
Stream可以分为低级流(节点流)和高级流(处理流);也可以分为字节流、字符流。一般字节流是低级流,字符流是高级流。高级流需要依赖低级流完成读写功能。
InputStreamReader和OutputStreamWriter可以看成是高级流中的低级流,也可以看成是联系高级流和低级流的纽带,他介于高级流和低级流之间,可以看成是转换流。
关注公众号,输入“java-summary”即可获得源码。
完成,收工!
【传播知识,共享价值】,感谢小伙伴们的关注和支持,我是【诸葛小猿】,一个彷徨中奋斗的互联网民工。