一、IO-文件(File)

1.概念
File类是IO包中唯一代表磁盘文件本身的对象,通过File来创建,删除,重命名文件;
2.本质
File本质就是一个路径(文件的路径或者文件夹的路径);

路径分为绝对路径和相对路径;
绝对路径:完整描述文件位置的路径,通常以盘符为开始的路径;
相对路径:相对于当前某个位置的路径,如在eclipse中是指当前项目文件根目录下;

3.构造函数

  • File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。

例:File f = new File(“C:\\Users\\Administrator\\Pictures\\flower.png”);

  • File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。

正确写法:File f1 = new File(“C:\\Users\\Administrator\\Pictures”,“flower.png”);
正确写法:File f2 = new File(“C:\\Users\\Administrator”,“Pictures\\flower.png”);
错误写法:File f3 = new File(“C:\\Users\\Administrator\\Pic”,“tures\\flower.png”);

  • File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。

例:File f = new File(new File(“C:\\Users\\Administrator\\Pictures”),“flower.png”);

  • File(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。

4.常用方法
1)获取方法
String getAbsolutePath() 获取绝对路径名字
String getName() 获取文件或文件夹的名称
String getPath() 获取对象创建时定义的路径,不分绝对或相对路径
long length() 获取文件对象的占用的字节数,文件夹对象无法确定大小

2)创建方法
boolean createNewFile() 创建文件,返回是否创建成功
boolean mkdir() 创建文件夹,返回是否创建成功

3)删除方法
boolean delete() 删除文件或文件夹(必须是空文件夹可以删除),返回时是否删除成功

4)判断方法
boolean exists() 判断是否存在文件或文件夹
boolean isFile() 判断是否是文件
boolean isDirectory() 判断是否是文件夹

5)列举方法
String[] list() 列举出路径下的所有文件和文件夹,返回字符串数组
File[] listFiles() 列举出路径下的所有文件和文件夹,返回File数组

注意:
使用列举方法时,想要列举指定的目录下的所有内容,必须确保指定的目录必须存在,而且必须是目录,否则会返回数组为null,接着抛出异常NullPointerException

package file;

import java.io.File;
import java.io.IOException;

public class getfile {

	public static void main(String[] args) throws IOException {
		//创建file对象
		File f =new File("fos.txt");
		System.out.println(f);
		//获取文件名
		String name = f.getName();
		//获取文件的绝对路径
		String absolutePath = f.getAbsolutePath();
		//获取文件的字节大小
		long length = f.length();
		System.out.println("文件:"+name+"位于:"+absolutePath+"字节大小:"+length);
		
		//创建文件和文件夹,如果已经存在此文件或文件夹则创建失败
		File ff = new File("temp.txt");
		if(ff.createNewFile()) {
			System.out.println("创建成功");
		}
		else {
			System.out.println("创建失败");
		}
		File fff = new File("temp");
		if(fff.mkdir()) {
			System.out.println("创建成功");
		}
		else {
			System.out.println("创建失败");
		}
		
		//判断
		ExistsFile(ff);
		ExistsFile(fff);
		
		//列举
		File f1 = new File("C:\\Users\\Public\\Pictures\\Sample Pictures");
		String[] list = f1.list();
		for (String l : list) {
			System.out.println(l);
		}
		System.out.println("\n");
		File[] listFiles = f1.listFiles();
		for (File l : listFiles) {
			System.out.println(l.getName());
		}
	}
	
	
	//先判断对象的路径表示的文件或文件夹是否存在,存在再判断属于什么类型,并且删除
	public static void ExistsFile(File file) {
		if(file.exists()) {
			System.out.print(file.getName());
			if(file.isFile()) {
				System.out.println("是文件类型");
				while(file.delete()) {
					System.out.println("删除此文件");
				}
			}
			else {
				System.out.println("是文件夹类型");
				while(file.delete()) {
					System.out.println("删除此文件夹");
				}
			}
		}
		else {
			System.out.println("目标不存在");
		}
	}
}
console结果:
fos.txt
文件:fos.txt位于:C:\Users\Administrator\eclipse-workspace\com.jagger.collection\fos.txt字节大小:5
创建成功
创建成功
temp.txt是文件类型
删除此文件
temp是文件夹类型
删除此文件夹
Chrysanthemum.jpg
Desert.jpg
desktop.ini
Hydrangeas.jpg
Jellyfish.jpg
Koala.jpg
Lighthouse.jpg
Penguins.jpg
Tulips.jpg


Chrysanthemum.jpg
Desert.jpg
desktop.ini
Hydrangeas.jpg
Jellyfish.jpg
Koala.jpg
Lighthouse.jpg
Penguins.jpg
Tulips.jpg

5.列举和删除一个目录下所有文件包括子目录下的文件

java 文件夹下第一个文件 java中一个文件是指什么_字节数组


列举过程:

package deletefile;
import java.io.File;

public class delete {

	public static void main(String[] args) {
		File f1 = new File("C:\\Users\\Administrator\\Pictures\\delete");
		
		ls(f1);
	
	}
	
	public static void ls(File file) {
		if(file.exists()) {
			File[] lf = file.listFiles();
			for (File fi : lf) {
				if(fi.isFile()) {
					System.out.println("文件-" + fi.getName());
				}
				else {
					ls(fi);
				}
			}
			System.out.println("文件夹-" + file.getName());
		}
		else {
			System.out.println("文件夹-" + file.getName());
		}
	}
}
console结果:
文件-1.txt
文件-2.txt
文件-3.txt
文件-Chrysanthemum.jpg
文件-a.txt
文件-b.txt
文件夹-copy1
文件夹-copy3
文件夹-copy2
文件-Koala.jpg
文件-Lighthouse.jpg
文件夹-delete

删除过程:
1.判断此目录下有无内容,目录下无内容直接删除目录
2.有内容:对根目录进行列举,如果列举到的是文件则直接删除,列举到的是文件夹则返回文件夹目录进行递归处理
3.再次判断根目录下有无内容,根目录下无内容直接删除根目录
4.列举到文件夹目录递归:执行1-2-3

package deletefile;
import java.io.File;

public class delete {

	public static void main(String[] args) {
		File f1 = new File("C:\\Users\\Administrator\\Pictures\\delete");
		
		recursion(f1);
	}
	
	public static void recursion(File file) {
		if(file.exists()) {
			File[] lf = file.listFiles();
			for (File fi : lf) {
				if(fi.isFile()) {
					while(fi.delete()) {
						System.out.println(fi.getName() + "文件删除成功");
					}
				}
				else {
					recursion(fi);
				}
			}
			while(file.delete()) {
				System.out.println(file.getName() + "文件夹删除成功");	
			}		
		}
		else {
			while(file.delete()) {
				System.out.println(file.getName() + "文件夹删除成功");	
			}
		}
	}

}
console结果:
1.txt文件删除成功
2.txt文件删除成功
3.txt文件删除成功
Chrysanthemum.jpg文件删除成功
a.txt文件删除成功
b.txt文件删除成功
copy1文件夹删除成功
copy3文件夹删除成功
copy2文件夹删除成功
Koala.jpg文件删除成功
Lighthouse.jpg文件删除成功
delete文件夹删除成功

二、IO-流

1.流(Stream):一个流可以理解为一个数据的序列。

  • 根据流的流向分为:输入流输出流(输入输出是相对于内存而言);输入流表示从一个源读取数据(比如通过java程序从硬盘读取数据到内存),输出流表示向一个目标写数据(比如通过java程序从内存向硬盘写入数据)。
  • 根据流的操作的数据类型分为:字符流字节流

2.JAVA中的四大流

  • 读(read):字符输入流Reader、字节输入流InputStream;
  • 写(write):字符输出流Writer、字节输出流OutputStream;

3.InputStream字节输入流
概念::InputStream类是字节输入流的抽象类,此抽象类表示输入字节流的所有类的超类;
方法:
abstract int read() ;读取一个字节
int read(byte[] b) ;读取一个字节数组

子类:

java 文件夹下第一个文件 java中一个文件是指什么_System_02


1)FileInputStream

构造:

FileInputStream(File file)

package fileinputstream;

import java.io.FileInputStream;
import java.io.IOException;

public class fis {

	public static void main(String[] args) throws IOException {
		//创建对象fi
		FileInputStream fi = new FileInputStream("fos.txt");
		//读取一个字节
		int a = 0;
		a = fi.read();//读取后赋值给a
		System.out.println(a);//直接将read()返回的ASCII值打印
		System.out.println((char)a);//将返回ASCII值强转成char型以字符形式打印
		//循环读取字节,读取文件的全部内容
		//当读取到文件的结尾时read()返回-1,所以循环中使用-1来判断是否读取完
		int b = 0;
		while((b=fi.read())!= -1) {
			System.out.println((char)b);
		}
		//关闭流
		fi.close();
		
		//创建新的对象ff
		FileInputStream ff = new FileInputStream("fos.txt");
		//读取一个字节数组
		byte[] c = new byte[4];
		int len = 0;
		len = ff.read(c);//文件内容按照字节数组长度读取到字节数组c中,返回值是字节数组的长度
		System.out.println(len);//打印长度
		String s = new String(c);//String的构造函数可以将字符数组重新构造成String
		System.out.println(s);//将字符数组以字符串形式打印
		//关闭流
		ff.close();
		
		//循环读取字节数组,读取文件的全部内容
		//当读取到文件的末尾时,read(byte[] b)返回-1,借此可以来判断是否读取完
		FileInputStream fff = new FileInputStream("fos.txt");
		byte[] d = new byte[3];
		int len1 = 0;
		while((len1=fff.read(d)) != -1) {
			System.out.print(new String(d,0,len1));
		}
		//关闭流
		fff.close();
	}
fos.txt文件内容:abcde
console打印结果:
97
a
b
c
d
e
4
abcd
abcde

2)ObjectInputStream
概念:反序列化流,ObjectInputStream读取(重构)对象
构造:
ObjectInputStream(InputStream in)

3)BufferedInputStream
概念: 相对于FileInputStream增加了功能,即缓冲输入和支持mark和reset方法的功能;
构造:

  • BufferedInputStream(InputStream in);
  • BufferedInputStream(InputStream in, int size); 可以指定缓冲区大小

4.OutputStream字节输出流

概念:

OutputStream类是字节输入流的抽象类,此抽象类表示输出字节流的所有类的超类;

方法:

void close(); 关闭流

void flush(); 刷新流

void write(byte[] b) ; 写一个字节数组

void write(byte[] b, int off, int len) ; 写一个字节数组的指定部分

abstract void write(int b) ; 写一个字节

子类:

java 文件夹下第一个文件 java中一个文件是指什么_字节数组_03


1)FileOutputStream

构造:

FileOutputStream(File file)

package fileoutputstream;

import java.io.File;
import java.io.FileOutputStream;

public class fos {

	public static void main(String[] args) throws Exception {
//		构造函数的使用区别
//		FileOutputStream(File file) 默认无续写 
//		FileOutputStream(File file, boolean append)   
//		FileOutputStream(String name) 
//		FileOutputStream(String name, boolean append)   
		//创建对象
		FileOutputStream f = new FileOutputStream("fos.txt",true);
		FileOutputStream ff = new FileOutputStream(new File("fos1.txt"),true);
		//写入数据,换行windows:\r\n,linux:\n,mac:\r
		f.write("\r\nsucces".getBytes());//使用getBytes()将字符串拆解成字节
		ff.write("fail".getBytes());
		//关闭流
		f.close();
		ff.close();
	}
}

2)ObjectOutputStream
概念:序列化流,将Java对象的原始数据类型和图形写入OutputStream
构造:
ObjectOutputStream(OutputStream out)

注意: serializable,serialVersionUID,transient的使用

  • serializable:java.io.serializable接口,一个类只有实现此接口(标记的作用,无需添加实现内容),才可以进行序列化,否则报异常:NotSerializableException;
  • serialVersionUID:序列化后的对象进行了修改,直接反序列化就会出现异常:InvalidClassException(因为一个类生成后会自动生成一个serialVersionUID,只要对类进行了修改就会生成新的serialVersionUID);
  • transient:用于修饰成员变量,如果在序列化的时候使用了修饰成员变量,就会忽略该成员变量;

3)BufferedOutputStream
概念: 该类实现缓冲输出流;
构造:

  • BufferedOutputStream(OutputStream out);
  • BufferedOutputStream(OutputStream out, int size); 可以指定的缓冲区大小

5.Reader字符输入流

概念:

Reader类是字符输入流的抽象类,此抽象类表示输入字符流的所有类的超类;

方法:

子类:

java 文件夹下第一个文件 java中一个文件是指什么_java_04


1) Filereader

**作用:**方便操作字符文件,使用的默认GBK字符集;

构造:

FileReader(File file)

方法:

int read();//读一个字符

int read(char[] chs);//读一个字符数组

2) InputStreamReader

作用:是字节流到字符流的桥梁,读取字节,并使用指定的charset将其解码为字符;
构造
InputStreamReader(InputStream in) ;默认使用GBK字符集
InputStreamReader(InputStream in, String charsetName) ;指定字符集创建
示例:
GBK中每个中文字符占用2个字节,UTF-8每个中文字符占用3个字节;

package inputstreamreader;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class inputstreamreader {

	public static void main(String[] args) throws IOException {
		//创建对象
		InputStreamReader isr1 = new InputStreamReader(new FileInputStream("gbk.txt"));
		InputStreamReader isr2 = new InputStreamReader(new FileInputStream("utf8.txt"),"UTF-8");
		InputStreamReader isr3 = new InputStreamReader(new FileInputStream("utf8.txt"));
		//读取
		int read = isr1.read();
		System.out.println((char)read);
		
		reads(isr1);
		reads(isr2);
		//用默认的GBK读取UTF-8文件,导致console结果出现乱码
		reads(isr3);
		//关闭流
		isr1.close();

	}
	public static void reads(InputStreamReader isr) throws IOException {
		char[] cbuf = new char[2];
		while(isr.read(cbuf) != -1) {
			for (char c : cbuf) {
				System.out.print(c);
			}
		}
		System.out.println("\n");
	}
}
console结果:
和
谐社会社

我爱中国

鎴戠埍涓浗

6.Writer字符输出流

概念:

Writer类是字符输出流的抽象类,此抽象类表示输出字符流的所有类的超类;

方法:

子类:

java 文件夹下第一个文件 java中一个文件是指什么_java_05


1) Filewirter

**作用:**方便操作字符文件,使用的默认GBK字符集;

构造:

FileWriter(File file)

方法:

write(int ch);//写一个字符(可以写字符或ASCII值)

write(String s);//写一个字符串

write(char[] chs);//写一个字符数组

write(char[] chs,int startIndex,int len);//写一个字符数组的某个长度

write(string s,int startIndex,int len);//写一个字符串的某个长度

2) OutputStreamWriter
作用:是字符流到字节流的桥梁,将写入的字符编码成使用指定的字节charset ,如将中文字符流通过GBK/UTF-8字符集进行编码转换成字节流进行写入操作;
构造
OutputStreamWriter(OutputStream out);默认使用GBK字符集
OutputStreamWriter(OutputStream out, String charsetName) ;指定字符集创建
示例:

package outputstreamwriter;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class osw {

	public static void main(String[] args) throws IOException {
		//分别根据GBK和UTF-8码表创建对象,比较两者编码的区别
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf8.txt"), "UTF-8");
		OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("gbk.txt"));
		//写入
		osw.write("我爱中国");
		osw1.write("和谐社会");
		//关闭流
		osw1.close();
		osw.close();
	}
}
创建的utf8文件属性:
内容:我爱中国
大小:12 字节 (12 字节)

创建的gbk文件属性:
内容:和谐社会
大小:8 字节 (8 字节)

注意:InputStreamReader和FileReader,OutputStreamWriter和FileWriter的区别
InputStreamReader:fr的父类,可以指定字符集,不能直接操作字符文件;
FileReader:是isr的子类,只能使用GBK字符集,直接操作的字符文件;

3)PrintWriter
**作用:**将对象的格式表示打印到文本输出流;
构造:

  • PrintWriter(File file)
  • PrintWriter(OutputStream out)
  • PrintWriter(String fileName)
  • PrintWriter(Writer out)

7.复制文件
过程:
1)创建输入、输出流对象
2)边对源文件进行读取,边写入到目标文件
3)关闭流

1)利用字节数组复制速度更快,console结果表明复制用时不到1毫秒

package copyfile;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class cpfile {

	public static void main(String[] args) throws IOException {
		//创建字节读取、写入对象
		FileInputStream fis = new FileInputStream("hashmap.png");
		FileOutputStream fos = new FileOutputStream("copy.png");
		
		//s用于接收起始时间
		long s = System.currentTimeMillis();
		//字节数组复制:一边从源文件读取,一边写入到目标文件中
		byte[] b = new byte[1024];//长度通常定义为1024的整数倍
		int len = 0;
		while((len=fis.read(b)) != -1) {
			fos.write(b, 0, len);
		}
		//e用于接收复制完成后的时间,再打印出时间差
		long e = System.currentTimeMillis();
		System.out.println(e-s);
		
		//关闭流
		fos.close();
		fis.close();
	}
}
console打印结果:
0

2)一个字节一个字节的进行复制速度更慢,console结果表明复制大概用了253毫秒;

package copyfile;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class cpfile {

	public static void main(String[] args) throws IOException {
		//创建字节读取、写入对象
		FileInputStream fis = new FileInputStream("hashmap.png");
		FileOutputStream fos = new FileOutputStream("copy.png");
		
		//s用于接收起始时间
		long s = System.currentTimeMillis();
		//一个字节一个字节进行复制
		int b = 0;
		while((b=fis.read()) != -1) {
			fos.write(b);
		}
		//e用于接收复制完成后的时间,再打印出时间差
		long e = System.currentTimeMillis();
		System.out.println(e-s);
		
		//关闭流
		fos.close();
		fis.close();
	}
}
console打印结果:
253

8.复制文件夹
过程:
1)
2)
3)

9.字节流读取中文出现乱码的问题