文件操作和IO

发布时间:2024年01月19日

认识文件

我们先来认识狭义上的?件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进?数据保存时,往往不是保存成?个整体,?是独?成?个个的单位进?保存,这个独?的单位就被抽象成?件的概念,就类似办公桌上的?份份真实的?件?般。
?件除了有数据内容之外,还有?部分信息,例如?件名、?件类型、?件??等并不作为?件的数据?存在,我们把这部分信息可以视为?件的元信息。

文件路径(Path)

如何在?件系统中如何定位我们的?个唯?的?件就成为当前要解决的问题,但这难不倒计算机科学家,因为从树型结构的?度来看,树中的每个结点都可以被?条从根开始,?直到达的结点的路径所描述,?这种描述?式就被称为?件的绝对路径(absolute path)。
除了可以从根开始进?路径的描述,还有相对路径,先指定一个”当前目录“/ “工作目录”/"基准目录“,从当前目录出发,找到目标文件。

在实际开发中用的更多的是相对路径

文件分类

1.文本文件:是按照”文本“ / 字符串方式来理解文件内容(文本文件里面的二进制内容都是表示的字符串),进一步的,可以认为,二进制文件的内容,都是合法的字符(字符编码/普通字母/汉字)
2.二进制文件:没有上述限制,这里的内容任何数据都可以

如何判断呢?
使用记事本打开文件,如果是乱码,就是二进制文件,否者是文本文件

Java 中操作?件

Java 中通过 java.io.File 类来对?个?件(包括?录)进?抽象的描述。注意,有 File 对象,
并不代表真实存在该?件。

File 概述

我们先来看看 File 类中的常?属性、构造?法和?法

属性

在这里插入图片描述

构造方法

在这里插入图片描述

方法

在这里插入图片描述

代码示例

相对路径

public class Test1 {
    public static void main(String[] args) throws IOException {
//        File file = new File("D:\\java_cc\\javase\\IODemo/11.txt");
        //ctrl+D直接复制上一行内容
        File file = new File("./11.txt");
        System.out.println(file.exists());
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsoluteFile());
        System.out.println(file.getCanonicalFile());
    }
}

运行结果

true
.
11.txt
.\11.txt
D:\java_cc\javase\IODemo.\11.txt
D:\java_cc\javase\IODemo\11.txt

绝对路径

public class Test1 {
    public static void main(String[] args) throws IOException {
       File file = new File("D:\\java_cc\\javase\\IODemo/11.txt");
        //ctrl+D直接复制上一行内容

        System.out.println(file.exists());
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsoluteFile());
        System.out.println(file.getCanonicalFile());
    }
}

运行结果:

true
D:\java_cc\javase\IODemo
11.txt
D:\java_cc\javase\IODemo\11.txt
D:\java_cc\javase\IODemo\11.txt
D:\java_cc\javase\IODemo\11.txt

对比相对路径和绝对路径,get的运行结果有所差异

普通文件的创建与删除

public class Test2 {
    public static void main(String[] args) throws IOException {
        File file = new File("22.txt");//开始不存在
        System.out.println(file.exists());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
        System.out.println(file.exists());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
    }
}

运行结果

false
false
false
true
true
false
true
false

public class IODemo3 {
    public static void main(String[] args) throws InterruptedException {
        File file = new File("./test.txt");
        // boolean ret = file.delete();
        file.deleteOnExit();
        Thread.sleep(5000);
        // System.out.println(ret);
    }
}

程序运行结束后被删除

目录的创建

public class Test3 {
    public static void main(String[] args) {
        File file = new File("some-dir");
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.mkdir());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
    }
}

运行结果:

false
false
true
true
false

创建多级目录

import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File dir = new File("some-parent\\some-dir"); // some-parent 和 so
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdirs());
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
}
}

运行结果:

false
false
true
true
false

创建some-parent下的some-dir目录

文件的重命名

import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求 some-file.txt 得存在
File dest = new File("dest.txt"); // 要求 dest.txt 不存在
System.out.println(file.exists());
System.out.println(dest.exists());
System.out.println(file.renameTo(dest));
System.out.println(file.exists());
System.out.println(dest.exists());
}
}

运行结果:

true
false
true
false
true

文件的读写——数据流

流是操作系统提供的概念
Java标准库对于流进行了一系列的封装,提供了一组类来负责进行这些工作
大致分为两大类别:
1.字节流:以字节为单位进行读写,一次最少读写一个字节
代表类:InputStream(输入),OutputStream(输出)
2.字符流:以字符为单位进行读写,比如,如果utf8表示汉字,三个字节就是一个汉字,每次读写都得是以三个字节为一个单位,来进行读写,不能一次读写半个汉字
代表类:Reader(输入) Writer(输出)

InputStream概述

方法
在这里插入图片描述
说明

InputStream只是?个抽象类,要使?还需要具体的实现类。关于InputStream的实现类有很多,基
本可以认为不同的输?设备都可以对应?个InputStream类,我们现在只关?从?件中读取,所以使?FileInputStream

FileInputStream概述

构造方法
在这里插入图片描述

代码?例

?例1
将?件完全读完的两种?式。相?较??,后?种的IO次数更少,性能更好。

import java.io.*;
// 需要先在项??录下准备好?个 hello.txt 的?件,??填充 "Hello" 的内容
public class Main {
	public static void main(String[] args) throws IOException {
		try (InputStream is = new FileInputStream("hello.txt")) {
		while (true) {
		int b = is.read();
			if (b == -1) {
			// 代表?件已经全部读完
			break;
			}
		System.out.printf("%c", b);
		}
	}
	}
}
import java.io.*;
// 需要先在项??录下准备好?个 hello.txt 的?件,??填充 "Hello" 的内容
public class Main {
	public static void main(String[] args) throws IOException {
		try (InputStream is = new FileInputStream("hello.txt")) {
			byte[] buf = new byte[1024];
			int len;
				while (true) {
				len = is.read(buf);
					if (len == -1) {
					// 代表?件已经全部读完
					break;
					}
				for (int i = 0; i < len; i++) {
				System.out.printf("%c", buf[i]);
				}
			}
		}
	}
}


?例2
这?我们把?件内容中填充中?看看,注意,写中?的时候使?UTF-8编码。hello.txt中填写"你好中国"
注意:这?我利?了这?个中?的UTF-8编码后?度刚好是3个字节和?度不超过1024字节的现
状,但这种?式并不是通?的

import java.io.*;
// 需要先在项??录下准备好?个 hello.txt 的?件,??填充 "你好中国" 的内容
public class Main {
	public static void main(String[] args) throws IOException {
		try (InputStream is = new FileInputStream("hello.txt")) {
			byte[] buf = new byte[1024];
			int len;
				while (true) {
				len = is.read(buf);
					if (len == -1) {
					// 代表?件已经全部读完
					break;
					}
				// 每次使? 3 字节进? utf-8 解码,得到中?字符
				// 利? String 中的构造?法完成
				// 这个?法了解下即可,不是通?的解决办法
				for (int i = 0; i < len; i += 3) {
					String s = new String(buf, i, 3, "UTF-8");
					System.out.printf("%s", s);
				}
			}
		}
	}
}

利?Scanner进?字符读取

上述例?中,我们看到了对字符类型直接使?InputStream进?读取是?常?烦且困难的,所以,我们使??种我们之前?较熟悉的类来完成该?作,就是Scanner类。
在这里插入图片描述

import java.io.*;
import java.util.*;
// 需要先在项??录下准备好?个 hello.txt 的?件,??填充 "你好中国" 的内容
public class Main {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("hello.txt")) {
try (Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNext()) {
String s = scanner.next();
System.out.print(s);
}
}
}
}
}

OutputStream概述

在这里插入图片描述
在这里插入图片描述
说明
OutputStream同样只是?个抽象类,要使?还需要具体的实现类。我们现在还是只关?写??件
中,所以使?FileOutputStream

利?OutputStreamWriter进?字符写入

import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
os.write('H');
os.write('e');
os.write('l');
os.write('l');
os.write('o');
// 不要忘记 flush
os.flush();
}
}
}
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
byte[] b = new byte[] {
(byte)'G', (byte)'o', (byte)'o', (byte)'d'
};
os.write(b);
// 不要忘记 flush
os.flush();
}
}
}
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
byte[] b = new byte[] {
(byte)'G', (byte)'o', (byte)'o', (byte)'d', (byte)'B', (byte)'a'
};
os.write(b, 0, 4);
// 不要忘记 flush
os.flush();
}
}
}

mport java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
String s = "Nothing";
byte[] b = s.getBytes();
os.write(b);
// 不要忘记 flush
os.flush();
}
}
}
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
String s = "你好中国";
byte[] b = s.getBytes("utf-8");
os.write(b);
// 不要忘记 flush
os.flush();
}
}
}

利?PrintWriter找到我们熟悉的?法

上述,我们其实已经完成输出?作,但总是有所不?便,我们接来下将OutputStream处理下,使?PrintWriter类来完成输出,因为PrintWriter类中提供了我们熟悉的print/println/printf?法

OutputStream os = ...;
OutputStreamWriter osWriter = new OutputStreamWriter(os, "utf-8"); // 告诉
PrintWriter writer = new PrintWriter(osWriter);
// 接下来我们就可以?便的使? writer 提供的各种?法了
writer.print("Hello");
writer.println("你好");
writer.printf("%d: %s\n", 1, "没什么");
// 不要忘记 flush
writer.flush();

示例:

import java.io.*;public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8
try (PrintWriter writer = new PrintWriter(osWriter)) {
writer.println("我是第??");
writer.print("我的第??\r\n");
writer.printf("%d: 我的第三?\r\n", 1 + 1);
writer.flush();
}
}
}
}
}

文章来源:https://blog.csdn.net/weixin_65476629/article/details/135631363
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。