一、File类: 文件和目录路径名的抽象表示形式。
注意:
File仅代表一个联系,可能文件存在,也可能不存在;
这里的文件可以是文件,也可以是文件夹;
1、构造器:
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(File parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File(String parent, String child)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File file1=new File("D:\\Demo");
File file2=new File(file1,"Test.txt");
File file3=new File("D:/Demo1","Test");
2、方法:
//1.boolean canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件。
// 如果文件设置只读,就不可修改
System.out.println("canWrite():"+file2.canWrite());
//2.boolean setReadOnly()
System.out.println("setReadOnly():"+file2.setReadOnly());
System.out.println("canWrite():"+file2.canWrite());
//3.boolean createNewFile()当且仅当不存在具有此抽象路径名指定名称的文件时,
//不可分地创建一个新的空文件。
//如果文件所在路径不存在,报错找不到指定的路径,如果路径都存在创建一个新的文件
System.out.println("createNewFile():"+file2.createNewFile());
//4. boolean delete() 删除
System.out.println("delete():"+file2.delete());
System.out.println("delete():"+file1.delete());
//5.boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
System.out.println("exists():"+file2.exists());
//6.File getAbsoluteFile() 返回此抽象路径名的绝对路径名形式。
// String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。
//7.String getName() 返回由此抽象路径名表示的文件或目录的名称。
System.out.println("getName():"+file2.getName());
System.out.println("getName():"+file3.getName());
//8.String getParent()
//返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回null。
// File getParentFile()
//返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
System.out.println("getParent():"+file3.getParent());
System.out.println("getParentFile():"+file1.getParentFile());
//9.boolean isAbsolute() 测试此抽象路径名是否为绝对路径名。
//10.boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
//boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
//boolean isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件。
//11.long lastModified() 返回此抽象路径名表示的文件最后一次被修改的时间。
//12.String[] list() || File[] listFiles()
// 13.boolean mkdir() 创建此抽象路径名指定的目录。
// boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录
File file4=new File("D:/test1/test2/test3");
System.out.println(file4.mkdirs());
//14.//boolean renameTo(File dest) 重新命名此抽象路径名表示的文件。注意路径
二、IO流
1、概念
流:一连串流动的数据,以先进先出的方式传输信息,管道
以JAVA内存为中心:数据源→目的地
分类:分类之间相辅相成并不冲突
按流向:输入流、输出流
按操作单元:字节流、字符流
按功能分:节点流、功能流
2、字节流:是万能的(重要),属于节点流
InputStream 字节输入流 此抽象类是表示字节输入流的所有类的超类
FileInputStream 文件输入流 从文件系统中的某个文件中获得输入字节
OutputStream 字节输出流 此抽象类是表示输出字节流的所有类的超类
FileOutputStream 文件输出流 用于将数据写入File
2.1、字节输入流读取步骤
//建立连接
File src=new File("D:/text.txt");
//选择流
InputStream is=new FileInputStream(src);
//一次读入一个字节数据,至结尾返回-1
System.out.println(is.read());
//关闭
is.close();
2.2、字节输入流一次读取多个字节
InputStream is=null;
try {
is = new FileInputStream(src);
//一次读入一个字节数据,至结尾返回-1
System.out.println(is.read());
//准备容器存储多个数据,并循环读取
byte[] arr=new byte[1024];
int len=-1;
while((len=is.read(arr))!=-1) {
System.out.println(Arrays.toString(arr)); }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(is!=null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
2.3、字节输出流读取步骤
//建立连接
File dest=new File("D:/text.txt");
//选择流
byte[] arr="黑色毛衣".getBytes();
OutputStream os=null;
os=new FileOutputStream(dest,true);
os.write(arr);
os.close();
2.4、文件的拷贝
public static void copy(String src,String dest) {
copy(new File(src),new File(dest));
}
public static void copy(File src,File dest) {
InputStream is=null;
OutputStream os=null;
try {
//创建流
is=new FileInputStream(src);
os=new FileOutputStream(dest);
byte[] arr=new byte[1024];
int len=-1;
//读取
while((len=is.read(arr))!=-1) {
//写入
os.write(arr, 0, len);
}
//刷出
os.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//关闭 先打开的后关闭,后打开的先关闭
try {
if(os!=null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(is!=null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
2.5、拷贝文件夹
public static void main(String[] args) throws IOException {
/*
* 拷贝文件夹
* 1.不能拷贝当当前文件所在路径
* 2.不能拷贝到当前文件的子路径下
*/
copyDir("D:/Test01","D:/Test02");
}
//不能拷贝到当前问佳佳所在路径
public static void copyDir(String src,String dest) throws IOException {
int num=dest.lastIndexOf("/");
int num2=dest.lastIndexOf("\\");
String str=dest.substring(0, num);
String str1=dest.substring(0, num);
System.out.println(str);
if(str.equals(src)||(str+"/").equals(src)||str1.equals(src)||(str1+"/").equals(src)) {
throw new IOException("不能拷贝到当前文件所在路径");
}
copyDirW(new File(src), new File(dest));
}
//不能拷贝到当前文件的子路径下
public static void copyDirW(File src,File dest) throws IOException {
if(dest.getAbsolutePath().contains(src.getAbsolutePath())) {
throw new IOException("不能拷贝到当前文件的子路径下");
}
File destNew=new File(dest+"/"+src.getName());
copyDetail(src,destNew);
}
//拷贝
public static void copyDetail(File src,File dest) {
if(src.isDirectory()) {
if(!dest.exists()) {
dest.mkdirs();
}
File[] file=src.listFiles();
for(File f:file) {
copyDetail(f,new File(dest,f.getName()));
}
}else if(src.isFile()) {
if(!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
FileUtils.copy(src, dest);
}
}
3、字符流: 只能读写纯文本内容 按功能分则属于节点流
基类:Reader 字符输入流 FileReader 文件字符输入流
Writer 字符输出流 FileWriter
字符流读取过程
//选择流
Reader read=null;
Writer write=null;
try {
read=new FileReader("D:/text2.txt");
write=new FileWriter("D:/text.txt");
//按字符读取
char[] ch=new char[1024];
int len=-1;
while((len=read.read(ch))!=-1) {
write.write(ch, 0, len);
System.out.println(ch);
}
write.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(write!=null)
write.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(read!=null)
read.close();
} catch (IOException e) {
e.printStackTrace();
}
}
4、缓冲流:
字符流 字节流 -->节点流
包裹节点流,在节点流之上-->功能流|处理流
处理流:增强功能,提高性能的作用,在节点流之外才能使用,不能代替节点流
字节缓冲流
BufferedInputStream BufferedOutputStream 无新增方法
字符缓冲流 不能发生多态,因为存在新增方法
BufferedReader 字符输入缓冲流 新增方法 readLine() 读取一行
BufferedWriter 字符输出缓冲流 新增方法 newLine() 写出换行符
4.1、字节缓冲流
//建立连接
File file1=new File("D:\\Test02/test02.txt");
File file2=new File("D:\\text.txt");
//选择流
InputStream is=new BufferedInputStream(new FileInputStream(file1));
OutputStream os=new BufferedOutputStream(new FileOutputStream(file2));
//操作
byte[] arr=new byte[1024];
int len=-1;
while((len=is.read(arr))!=-1) {
os.write(arr, 0, len);
}
//刷出
os.flush();
//关闭
os.close();
is.close();
4.2、字符缓冲流
//建立连接
File file1 = new File("D:\\Test02/test02.txt");
File file2 = new File("D:\\text.txt");
// 选择流
BufferedReader is = new BufferedReader(new FileReader(file1));
BufferedWriter os = new BufferedWriter(new FileWriter(file2));
// 操作
String s=null;
while((s=is.readLine())!=null){
os.write(s);
os.newLine();
}
// 刷出
os.flush();
// 关闭
os.close();
is.close();
5、Data流
Data流 ->基本数据类型流,读入写出带有基本数据类型的数据+字符串数据
注意:
功能流,必须要包裹节点流使用(字节流)
DataInputStream 新增方法 readXxx()
DataOutputStream 新增方法 writeXxx()
public static void main(String[] args) throws IOException {
write("D:\\text.txt");
read("D:\\text.txt");
}
public static void write(String dest) throws IOException {
DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest))) ;
String s="两只小猪";
double d=3.141593;
int a=10;
//写出
dos.writeUTF(s);
dos.writeDouble(d);
dos.writeInt(a);
//刷出
dos.flush();
//关闭
dos.close();
}
public static void read(String src) throws IOException {
DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream(src))) ;
System.out.println(dis.readUTF());
System.out.println(dis.readDouble());
System.out.println(dis.readInt());
}
<meta charset="utf-8">
三、注意与拓展
1、字符输出流在使用创建的时候,如果默认为覆盖情况时,创建对象时src文件会被覆盖为空,即使没有调用write.writer();写入
Writer write = new FileWriter(src); write.close();
FileWriter除构造函数以外全部是继承了父类的方法。先创建一个FileOutputStream,如果不给出append参数或者append为false则清空原文件从头开始写入,否则是从尾部开始扩展文件内容,使用文件描述符创建时必定是从文件头部开始写。然后通过FileOutputStream创建OutputStreamWriter
public FileWriter(File file) throws IOException { super(new FileOutputStream(file)); }
源码:创建使用默认字符集的OutputStreamWriter。
public OutputStreamWriter(OutputStream out) { super(out); try { se = StreamEncoder.forOutputStreamWriter(out, this, (String)null); } catch (UnsupportedEncodingException e) { throw new Error(e); } }
FileWriter是将字符写入文件的通用类,构造函数假定使用默认的字符编码和默认的字节缓冲区大小8K是使用者可以接受的,如果要指定这些值,需要通过一个FileOutputStream来构造FileWriter的父类OutputStreamWriter。
文件是否有效或者是否能够被创建取决于平台,在一些平台上,对于同一个文件同一时间只允许一个FileWriter或者其他文件写入对象打开。在这种情况下,如果一个文件已经被打开,构造函数会抛出异常。
public void write(int c) throws IOException { char cbuf[] = new char[1]; cbuf[0] = (char) c; write(cbuf, 0, 1); } //这个是实际调用写入的方法 public void write(char cbuf[], int off, int len) throws IOException { synchronized (lock) { ensureOpen(); if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } implWrite(cbuf, off, len); } }
implWrite调用了内部方法flushLeftoverChar,作用是将缓存的字符写入输出流,这个方法同时在close时也被调用,因为leftoverChar只有一个字符,而一次输出至少是两个字符,所以还要从cb中读取字符,保证写入的是2个字符
flushBuffer()和flush()将ByteBuffer中的数据写入输出流,flush()同时还会进行输出流的刷新,具体操作取决于输出流的实现,比如FileOutputStream是什么也不做,因为没有缓冲区。
网友评论