针对硬盘这种持久化存储的I/O设备,当我们想要进⾏数据保存时,往 往不是保存成⼀个整体,⽽是独⽴成⼀个个的单位进⾏保存,这个独⽴的单位就被抽象成⽂件的概念。
⽂件除了有数据内容之外,还有⼀部分信息,例如⽂件名、⽂件类型、文件大小等并不作为⽂件的数据
⽽存在,我们把这部分信息可以视为文件的元信息。
文件夹和目录中保存的其实就是文件的原信息,通过一个个的文件夹,我们可以将文件组织起来,方便用户使用它。
⽂件夹是⽤来存放⽂件的,⽐如 A ⽂件夹下有 N 个⽂件,⽽ A ⽂件夹有⾃⼰的⽬录,⽐如在 D:\A。
从树型结构的⻆度来看,树中的每个结点都可以被⼀条从根开始,⼀直到达的结点的路径所描 述,⽽这种描述⽅式就被称为⽂件的绝对路径(absolute path)。
除了可以从根开始进⾏路径的描述,我们可以从任意结点出发,进⾏路径的描述,⽽这种描述⽅式就被 称为相对路径(relative path),相对于当前所在结点的⼀条路径。
从WindowsPowerShell出发去Windows NT路径
.代表当前节点,两个点代表父节点
普通文件划分为文本文件 和二进制⽂件,分别指代保存被字符集编码的文本和按照标准格式保存的非被字符集编码过的⽂件。
文件由于被操作系统进行了管理,所以根据不同的用户赋予不同的对待该文件的权限,可读、可写、可执行权限。
通过权限系统,起到保护数据安全的作用,
Windows操作系统上,还有一类文件就是常见的快捷方式,这种文件只是对真实文件的一种引用。
快捷方式,可以起到对同一文件建立多个引用的目的,方便用户使用。
主要是文件的元信息、路径的操作,java中通过java.io.File
类来对一个文件进行抽象的描述。
注意:有File对象,并不代表真实存在该文件
import java.io.File;
import java.io.IOException;
public class FileDemo2 {
public static void main(String[] args) throws IOException {
File file=new File("../a.txt");
System.out.println("文件名称"+file.getName());
System.out.println("文件目录(getPath)"+file.getPath());
System.out.println("文件绝对路径:"+file.getAbsolutePath());
System.out.println("文件的绝对路径:"+file.getCanonicalPath());
}
}
getPath() VS getAbsolutePath() VS getCanonicalPath():
(1)绝对路径时,三者⼀致。
(2)相对路径时:
getPath() 是相对路径本身;
getAbsolutePath() 是项⽬⽬录 + 相对路径本身;
getCanonicalPath() 可以解析相对路径,得到争取的路径。
2.文件判断与创建
import java.io.File;
import java.io.IOException;
public class FileDemo3 {
public static void main(String[] args) throws IOException {
File file=new File("a.txt");
System.out.println("文件是否存在:" + file.exists());
System.out.println("是否为文件夹:" + file.isDirectory());
System.out.println("是否为文件:" + file.isFile());
System.out.println();
boolean result = file.createNewFile(); // 创建文件
System.out.println("文件创建:" + result);
System.out.println("文件是否存在:" + file.exists());
System.out.println("是否为文件夹:" + file.isDirectory());
System.out.println("是否为文件:" + file.isFile());
}
}
import java.io.File;
import java.io.IOException;
public class FileDemo3 {
public static void main(String[] args) throws IOException {
// File file = new File("a.txt");
// System.out.println("文件是否存在:" + file.exists());
// System.out.println("是否为文件夹:" + file.isDirectory());
// System.out.println("是否为文件:" + file.isFile());
//
// System.out.println();
// boolean result = file.createNewFile(); // 创建文件
// System.out.println("文件创建:" + result);
// System.out.println("文件是否存在:" + file.exists());
// System.out.println("是否为文件夹:" + file.isDirectory());
// System.out.println("是否为文件:" + file.isFile());
//
File file2 = new File("b.txt");
if (!file2.exists()) { // 文件不存在,创建文件
System.out.println("创建文件:" + file2.createNewFile());
}
System.out.println("是否为文件夹:" + file2.isDirectory());
System.out.println("是否为文件:" + file2.isFile());
}
}
结论:如果文件或文件夹不存在,使⽤ isDirectory 和 isFile 判断都为 false。
3.文件存在删除/不存在创建
import java.io.File;
import java.io.IOException;
public class FileDemo4 {
public static void main(String[] args) throws IOException {
//先得到一个file对象
File file=new File("a.txt");
//判断file对象是否存在
if(file.exists()){
//如果存在则删除文件
boolean result=file.delete();
System.out.println("文件删除:"+result);
}else{
//如果不存在则创建文件
boolean result=file.createNewFile();
System.out.println("新建文件:"+result);
}
}
}
file.delete()执行完之后,a.txt会立即被删除。
4.观察 deleteOnExit
import java.io.File;
import java.io.IOException;
public class FileDemo5 {
public static void main(String[] args) throws IOException, InterruptedException {
File file=new File("a.txt");
if(!file.exists()){
//如果不存在,则新建
System.out.println("新建文件:"+file.createNewFile());
}
//删除文件
file.deleteOnExit();
Thread.sleep(5*1000);
}
}
file.deleteOnExit();程序运行期间a.txt不会被删除,程序正常运行结束后,文件被删除,但如果是人为退出程序,文件不会被删除。
5.delete()和deleteOnExit()的区别
(1)
delete()
有返回值,deleteOnExit()
没有返回值。
(2)delete()
在程序执行期间会被删除,deleteOnExit()
在程序执行期间不会被删除,程序正常运行结束后,文件被删除。
(3)delete()
不管是正常删除还是异常删除(执行期间人为退出程序),都会被删除。deleteOnExit()
正常删除会被删除,异常删除(人为退出程序)文件不会被删除。
6.观察目录的创建
(1)目录的创建一:
import java.io.File;
public class FileDemo6 {
public static void main(String[] args) {
File file=new File("mytest");
System.out.println("是否为文件夹:"+file.isDirectory());
System.out.println("是否为文件:"+file.isFile());
System.out.println();
boolean result=file.mkdir();
System.out.println("创建文件夹:"+result);
System.out.println("是否为文件夹:"+file.isDirectory());
System.out.println("是否为文件:"+file.isFile());
}
}
import java.io.File;
public class FileDemo7 {
public static void main(String[] args) {
File file=new File("mytest/apps");
System.out.println("是否为文件夹:"+file.isDirectory());
System.out.println("是否为文件:"+file.isFile());
System.out.println();
boolean result=file.mkdirs();
System.out.println("创建文件夹:"+result);
System.out.println("是否为文件夹:"+file.isDirectory());
System.out.println("是否为文件:"+file.isFile());
}
}
mkdir() 的时候,如果中间⽬录不存在,则⽆法创建成功; mkdirs() 可以创建多级目录。
import java.io.File;
import java.io.IOException;
public class FileDemo8 {
public static void main(String[] args) throws IOException {
//将a.txt->重命名b.txt
File file=new File("a.txt");
File tarFile=new File("b.txt");
if(!file.exists()){
//先创建文件
file.createNewFile();
}
//重命名文件
boolean result=file.renameTo(tarFile);
System.out.println("重命名结果:"+result);
}
}
如果 renameTo 的文件不存在,那么可以重命名成功,反之则不成功。
InputStream 输⼊流是⽤来读取数据的。
InputStream 只是⼀个抽象类,要使⽤还需要具体的实现类。从文件中读取,所以使⽤ FileInputStream。
1.构造方法
2.读取文件中的内容
将⽂件完全读完的两种方式:
(1)读取方式一:
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamDemo1 {
public static void main(String[] args) {
// 1.创建流对象
InputStream inputStream = null;
try {
inputStream = new FileInputStream("c.txt");
// 2.读写操作
while (true) {
int c = inputStream.read();
// 如果流返回的 -1,说明数据已经读取完了
if (c == -1) break;
Thread.sleep(200);
System.out.printf("%c", c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException exception) {
exception.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 3.关闭流
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}`在这里插入代码片`
}
package io;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo2 {
public static void main(String[] args) {
// 1.创建流对象 try-catch-resource(JDK 1.7)
try (InputStream inputStream = new FileInputStream("c.txt")) {
// 2.读写操作
while (true) {
int c = inputStream.read();
// 如果返回为 -1,说明数据已经读取完了
if (c == -1) break;
Thread.sleep(200);
System.out.printf("%c", c);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package io;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
//一次性读取
public class InputStreamDemo3 {
public static void main(String[] args) throws IOException {
try (InputStream inputStream = new FileInputStream("c.txt")) {
byte[] bytes=new byte[1024];
//如果数据超过了byte容量,会读取多次
while(true) {
int c = inputStream.read(bytes);
if(c==-1) break;
System.out.println(new String(bytes,"utf8"));
}
} catch (Exception e) {
}
}
}
我们可以使⽤ Scanner 进⾏数据读取,它有⼀个构造⽅法:
OutputStream 输出流是进行数据写入的。
OutputStream 同样只是⼀个抽象类,要使用还需要具体的实现类,所以使⽤ FileOutputStream。
1.每次写入一个字符
package io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* 写入:每次写入一个字符
*/
public class OutputStreamDemo1 {
public static void main(String[] args) throws IOException {
File file=new File("mytest.txt");
if(!file.exists()){
//新建文件
System.out.println("新建文件:"+file.createNewFile());
}
//写入操作
try(OutputStream outputStream=new FileOutputStream("mytext.txt")){
outputStream.write('H');
outputStream.write('E');
outputStream.write('L');
outputStream.write('L');
outputStream.write('O');
outputStream.flush();
}
}
}
查看mytext.txt,写入HELLO成功:
2.字节数组批量写⼊:
package io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class OutputStreamDemo2 {
public static void main(String[] args) throws IOException {
File file=new File("mytest.txt");
if(!file.exists()){
file.createNewFile();
}
//写入操作
try(OutputStream outputStream=new FileOutputStream(file)){
byte[] bytes=new byte[]{
'H','i'
};
outputStream.write(bytes);
outputStream.flush();
}
}
}
package io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class OutputStreamDemo3{
public static void main(String[] args) throws IOException {
File file=new File("mytest.txt");
if(!file.exists()){
file.createNewFile();
}
//写入操作
try(OutputStream outputStream=new FileOutputStream(file)){
String msg="Hello Word";
outputStream.write(msg.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
}
}
}
查看mytest.txt中Hello Word已经写入:
4.字符串中⽂写⼊
package io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class OutputStreamDemo3{
public static void main(String[] args) throws IOException {
File file=new File("mytest.txt");
if(!file.exists()){
file.createNewFile();
}
//写入操作
try(OutputStream outputStream=new FileOutputStream(file)){
String msg="你好 中国";
outputStream.write(msg.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
}
}
}
JDK 还提供了⼀个类 PrintWriter 可以很⽅便的实现数据写⼊。 PrintWriter 类中提供了我们熟悉的 print/println/printf ⽅法。
package io;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
public class OutputStreamDemo4 {
public static void main(String[] args) throws IOException {
File file=new File("mytest.txt");
if(!file.exists()){
file.createNewFile();
}
try(PrintWriter printWriter=new PrintWriter(file)){
printWriter.println("这是第一行数据");
printWriter.println("这是第二行数据");
printWriter.println("这是第三行数据");
printWriter.printf("我叫:%s,今年:%d","张三",18);
printWriter.flush();
}
}
}
package io;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class OutputStreamDemo5 {
public static void main(String[] args) throws IOException {
File file=new File("mytest.txt");
if(!file.exists()){
file.createNewFile();
}
//数据追加
try(FileWriter fileWriter=new FileWriter(file,true)){
fileWriter.append("\n我是追加的数据3");
fileWriter.flush();
}catch(Exception e){
}
}
}