IO流总结前,有必要总结一下File类的的功能特性:
File:文件和目录(文件夹)路径名的抽象表示形式。
(1)得到File对象三种方式:
//File(String pathname):根据一个路径得到File对象
//把e:\\test\\test.txt下的test.txt封装成File对象
File file=new File("e:\\test\\test.txt");
//File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
File file2=new File("e:\\test", "test.txt");
//File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。
File file3=new File("e:\\test");
File file4=new File(file3, "test.txt");
(2)创建文件、文件夹,及多级文件夹:
//在E盘目录下创建test文件夹
File file=new File("e:\\test");
System.out.println("mkdir:"+file.mkdir());
//在test文件夹中创建text.txt文件
File file2=new File("e:\\test\\test.txt");
System.out.println("createNewFile:"+file2.createNewFile());
//注意的是要创建某个目录下的文件,那么该目录必须存在,不存在会报错
//创建多级目录
File file3=new File("e:\\test\\aaa\\bbb\\ccc\\ddd");
System.out.println("mkdirs:"+file3.mkdirs());
上面的三个方法需要注意的是createNewFile和mkdir两个方法,如果要创建对应的文件或者是目录,则该目录名和文件名前面的路径必须存在,不存在则创建文件是会报错,在创建 目录时会返回false,且不提醒错误。而mkdirs则比较人性化,会把不存在的目录创建出来。特别要注意的是:如果要创建文件,只能用createNewFile()方法,如果用的mkdir或者是mkdirs,那么只能创建文件夹。如:File file=new File("e:\\test\\test.txt");file.mkdirs();那么就会在test文件夹下创建一个名为test.txt的文件夹,而不是一个名为test的文件。
(3)File类的获取功能:
public String getAbsolutePath();获取绝对路径;
public String getPatn();获取相对路径;
public String getName();获取名称;
public Long length();获取长度,字节数;
public Long lastModified();获取最后一次的修改时间,毫秒值。
高级的获取功能:
public String[] list():获取指定目录下的所有文件或者文件夹的名称数组;
public File[] listFiles():或者去指定目录下的所有文件或者文件夹的File数组。
(4)File类的删除功能:
public boolean delete()删除由此抽象路径名表示的文件或目录。 如果此路径名表示目录,则目录必须为空才能删除。
需要注意的是:
A:如果你创建的文件或者目录(文件夹)忘了写盘符路径,那么默认在项目路径下;
B:Java中的删除不走回收站;
C:要删除一个文件夹,要注意该文件夹内不能包含文件或者文件夹。
(5)File类的判断功能:
public boolean isDirectory();判断是否是目录;
public boolean isFile();判断是否是文件;
public boolean exists();判断是否存在;
public boolean canRead();判断是否可读;
public boolean canWrite();判断是否可写;
public boolean isHidden();判断是否隐藏。
(6)File类的重命名:
重命名文件:public boolean renameTo(File dest):如果路径名相同就改名;如果路径名不同,就是改名加剪切。
IO流总结:分字节流和字符流。
(一)字节流:字节输入流、字节输出流
(1)字节输入流:超类:InputStream(抽象类):所有字节输入流的超类。
有int read():一次读取一个字节和int read(byte[] b):一次读取一个字节数组两个方法,写法如下:
//一次读取一个字节
int by = 0;
while ((by = fis.read()) != -1) {
System.out.print((char) by);
}
//一次读取一个数组
byte[] bys=new byte[1024];
int len=0;
while((len=is.read(bys))!=-1){
System.out.print(new String(bys,0,len))
}
子类:FileInputStream和BufferedInputStream:
FileInputStream:
写法:FileInputStream fis=new FileInputStream("a.txt");//文件必须存在,否则报错。
或者:FileInputStream fis=new FileInputStream(File file);
BufferedInputStream:
写法:BufferedInputStream bis=new BufferedInputStream(InputStream is);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(String name));
或者:BufferedInputStream bis=new BufferedInputStream(InputStream is,int size);
(2)字节输出流:超类:OutputStream(抽象类):所有字节输出流的超类。
有void write(int b):一次写一个字节和void write(byte[] bys,int i,int len):一次写一个字节数组的一部分两个方法:
//一次写一个数组的一部分
byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1) {
bos.write(bys, 0, len);
}
//一次写一个字节
int by=0;
while((by=bis.read())!=-1) {
bos.write(by);
}
子类:FileOutputStream和BufferedOutputStream
FileOutputStream:
写法:FileOutputStream fos=new FileOutputStream("b.txt");//文件可以不存在,没有会自己创建;
或者:FileOutputStream fos=new FileOutputStream(File file);
BufferedOutputStream:
写法:BufferedOutputStream bos=new BufferedOutputStream(OutputStream os);
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(String name));
或者:BufferedOutputStream bos=new BufferedOutputStream(OutputStream os,int size);
对于文件的复制:字节流提供了四种方式实现复制:分别是两种普通的读取文件复制和两种buffer高级读取文件复制。
/*
* 需求:把硬盘上的视频复制到当前项目目录下的Copy.mp4中
*
* 字节流四种方式复制文件
* 基本字节流一次读写一个字节:
* 基本字节流一次读写一个字节数组:
* 高级字节流一次读写一个字节:
* 高级字节流一次读写一个字节数组:
*/
public class ByteCopyFourMethod {
public static void main(String[] args) {
long start = System.currentTimeMillis();
// method1();//95716
// method2();//203 1986
// method3();//651
method4();// 63 1990
long end = System.currentTimeMillis();
System.out.println(end - start);
}
private static void method4() {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("c:\\test.avi"));
bos = new BufferedOutputStream(new FileOutputStream("D:\\method4.avi"));
byte[] bys = new byte[9 * 1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void method3() {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("c:\\test.avi"));
bos = new BufferedOutputStream(new FileOutputStream("method3.avi"));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void method1() {
// TODO Auto-generated method stub
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("c:\\test.avi");
fos = new FileOutputStream("method1.avi");
int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void method2() {
// TODO Auto-generated method stub
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("c:\\test.avi");
fos = new FileOutputStream("D:\\method2.avi");
byte[] bys = new byte[9 * 1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(二)转换流:因为很多的地方可以使用字符流代替字节流对文件进行更为方便的操作,所以,Java提供了转换流供开发者将字节流包装成字符流。
InputStreamReader(InputStream is):将字节输入流转化为字符输入流。
OutputStreamWriter(OutputStream os):将字节输出流转化为字符输出流。
(三)字符流:字符输入流、字符输出流
(1)字符输入流:超类:Reader:所有字符输入流的超类。
有int read():一次读取一个字节和int read(char[] chs):一次读取一个字节数组。
//一次读取一个字节
int b=0;
while((b=is.read())!=-1){
System.out.print(b);
}
//一次读取一个字节数组
byte[] bys=new byte[1024];
int len=0;
while((len=is.read(bys))!=-1){
System.out.print(new String(bys,0,len))
}
子类:InputStreamReader、BufferedReader:
InputStreamReader:
写法:InputStreamReader isr=new InputStreamReader(new FileInputStream("a.txt"));
由于这个写法很长,所以Java提供了InputStreamReader的子类FileReader来进行字符输入流的操作:
写法:FileReader fr=new FileReader("a.txt");
BufferedReader:
写法:BufferedReader br=new BufferedReader(new InputStreamReader(new FileinputStream("a.txt")));
或者:BufferedReader br=new BufferedReader(FileReader("a.txt"));
该类有一个特殊的方法:String readLine():一次读取一行数据
String line=null;
while((line=br.readLine())!=null){//readLine()函数是读完最后一行,返回的是null
System.out.println(line);
//这里记得要分行,因为readLine时根据换行符进行判读是否读到一行的结果的,不包含换行符,自己要添加
}
(2)字符输出流:超类:Writer:所有字符串输出流的超类。
有void write(int ch):一次写一个字节和void write(char[] chas,int i,int len):一次写一个字节数组的一部分。
os.write(ch);//一次写一个字节
len=is.read(chs);
os.write(chs,0,len);//一次写一个数组
子类:OutputStreamWriter和BufferedWriter
OutputStreamWriter:
写法:OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("b.txt"));
由于这个写法很长,所以Java提供了OutputStreamWriter的子类FileWriter来进行字符输入流的操作:
写法:FileWriter fw=new FileWriter("b.txt");
BufferedWriter:
写法:BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt")));
或者:BufferedWriter bw=new BufferedWriter(new FileWriter("b.txt"));
该类有特殊方法:void newLine():写换行符号 void write(String s):写一个字符串。
对于字符流进行内容复制的标准写法推荐(参考):
BufferedReader br=new BufferedReader(FileReader("a.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("b.txt"));
String line=null;
while((line=br.read())!=null){
bw.writer(line);
bw.newLine();//兼容各种系统的换行
bw.flush();//刷新缓冲区
}
小结:
除了用windows记事本打开的能读懂的数据用字符流以外,其他的全部使用字节流。
字节流复制数据:4种 普通读写2种,一次一个字节和一次一个数组,高级读写2种,一次一个字节和一次一个数组。
字符流复制数据:5种,多的一种是每次复制按一行复制。
以上是常用流的介绍,其他相对较少使用的流将在下一个基础总结中总结。
注:以上文章仅是个人学习过程总结,若有不当之处,望不吝赐教。