文件输入输出流
- 文件内容操作与实战
- 字符流
- Reader
- Writer
- 字节流
- inputStream
- OutputStream
- 实战💪
文件内容操作与实战
文件的分类上一篇文章(文件对象处理)已经和大家讲解过了。本章主要文件主要针对于对文件内容的操作展开讲解,文件分为:文本文件和二进制文件,不同的文件,操作方法也不尽相同。
针对文本文件,Java提供了一组类——”字符流“,代表类(Reader,Writer)。同样的,Java也为二进制文件提供了一组操作类——”字节流“,代表类(InputStream,OutputStream)。其实这两种的对文件操作原理是相同的,只是针对的文件不同,所以才有了字符流和字节流之分。因为有了字节流与字符流之分,所以相对应的,字节流最低读写字符是”一个字节“,字符流也有对应限制,字符流最低读写”一个字符 “。
这种读写操作一般也统称为IO流。IO操作是在CPU上进行的,以CPU来看待数据的输入和输出。
字符流
输入流:Reader
输出流:Writer
注意:
使用完文件资源后应该关闭文件资源
Reader
创建对象及使用:
public static void main(String[] args) throws IOException {//创建一个字符流操作对象
try(Reader reader = new FileReader("d:/hello.txt")){
while (true) {
//每次读取一个字符
int read = reader.read();
if(read == -1){
break;
}
System.out.print((char)read+" ");
}
}
}
Writer
字符流写入对象的创建及使用:
同样的需要使用子类来构造
public static void main(String[] args) throws IOException {
try(Writer writer = new FileWriter("d:/hello.txt")){
writer.write("我爱敲代码");
}
}
文件使用完,需要进行关闭操作,防止不必要的意外发生。文件的资源泄漏问题不会立即出现,而是一段时间才会出现明显问题。
字节流
输入流:inputStream
输入流:OutputStream
注意:
使用完文件资源后应该关闭文件资源
inputStream
构造inputStream对象
因为这个类是一个抽象方法,在构造时,不能直接使用类名去调用。这里使用子类FileInputStream来构造对象。
public static void main(String[] args) throws IOException {
//相当于打开一个文件,将这个变量与文件关联
InputStream inputStream = new FileInputStream("d:/hello.txt");
inputStream.close();
//每次使用完文件,必须关闭,防止不必要的资源浪费
}
有时候因为中途return或者结束了进程会不可避免地无法将文件关闭,所以这里使用try/catch/finally语句来进行关闭文件资源操作。
改写代码:
public static void main(String[] args) throws IOException {
//方案一
InputStream inputStream = null;
try {
//打开文件
inputStream = new FileInputStream("d:/hello.txt");
}finally {
//关闭文件
inputStream.close();
}
//方案二,会自动执行close关闭操作
try(InputStream inputStream = new FileInputStream("d:/hello.txt")){
}
}
解决了构造函数接下来我们将继续来实现读写操作。
读操作
可以看见有三个方法可以进行读操作,接下来我们一一测试read()方法的作用。
//read()相当于把字节变成二进制进行表示
public static void main(String[] args) throws IOException {
try(InputStream inputStream = new FileInputStream("d:/hello.txt")){
while (true){
int input = inputStream.read();
//遇到-1则表示没有数据,退出循环
if(input == -1){
break;
}
System.out.println(input);
}
}
}
三个方法使用的操作基本一致,都是读到末尾时返回-1,另外两个方法可以指定读取大小。返回的是总字节数,不是二进制数据。
OutputStream
构造inputStream对象
同样的,这个也是一个抽象类,需要调用子类仿佛来创建对象:
//创建对象及使用方法
//将hello写入文件
public static void main(String[] args) throws IOException {
try(OutputStream outputStream = new FileOutputStream("d:/hello.txt")){
byte[] bytes = {'h','e','l','l','o'};
outputStream.write(bytes);
}
}
实战💪
遍历目录,对文件进行查找或者删除
1.将输入目录进行遍历
2.每次找到一个文件就获取目录
3.对比文件名与输入的文件名是否一致
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class FindAndDelete {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要查找的目录:");
File fileDir = new File(scanner.next());
if(!fileDir.isDirectory()){
System.out.println("您输入的不是目录!");
return;
}
System.out.println("请输入要查找的文件名");
String file = scanner.next();
//递归目录/文件的操作
scanDir(fileDir,file);
}
private static void scanDir(File fileDir, String file) throws IOException {
File[] files = fileDir.listFiles();
if(files == null){
//当前目录为空
return;
}
for(File f:files){
// System.out.println("当前搜索到"+f.getCanonicalPath());
if(f.isFile()){
String filename = f.getName();
if(filename.equals(file)){
System.out.println(f.getCanonicalPath()+"存在该文件");
}
}else if(f.isDirectory()){
scanDir(f,file);
}else {
continue;
}
}
}
}
遍历目录,查找文件中的内容与指定内容一致并输出文件目录,类似于文件检索
1.先去简单递归遍历目录
2.每次找到一个文件并获取目录
3.在判定的查询的词中,是否存在上述内容
public class FindTargetDoc {
public static void main(String[] args) throws IOException {
//1.先让用户输入需要搜索文件的根目录
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个目录:");
File fileDir = new File(scanner.next());
//判断输入的是否为目录
if(!fileDir.isDirectory()){
System.out.println("输入错误,你输入的目录不存在");
}
//2.获取用户需要查询的词
System.out.println("请输入要查询的词");
String word = scanner.next();
//3.递归进行目录/文件的操作
scanDir(fileDir,word);
}
private static void scanDir(File fileDir, String word) throws IOException {
//列出当前FileDir的内容
File[] files = fileDir.listFiles();
if(files == null){
//当前目录是空
return;
}
for (File f:files) {
if(f.isFile()){
//判断是否为文件
String content = readFile(f);
if(content.contains(word)){
System.out.println(f.getCanonicalPath()+"包含查找的文件");
}
}else if(f.isDirectory()) {
//判断是否为目录
scanDir(f,word);
}else {
//不是普通文件也不是目录文件
continue;
}
}
}
private static String readFile(File f) throws IOException{
//读取整个内容,返回
//处理是字符流,所以使用字符流进行处理
StringBuilder stringBuilder = new StringBuilder();
try(Reader reader = new FileReader(f)){
//将读取的字符拼接到StringBuilder上
while (true){
int ch = reader.read();
if(ch == -1){
break;
}
stringBuilder.append((char)ch);
}
}
return stringBuilder.toString();
}
}
进行普通文件的复制操作
1.需要准备两个文件
2.一个有内容,一个无内容
3.一个读一个写,将其读完存储在另一个文档中即可
public class CopyFile {
public static void main(String[] args) throws IOException {
//这里可以输入,读者可以自行更改
File source = new File("d:/aaa/hello.txt");
File dest = new File("d:/aaa/world.txt");
if(!source.exists() || !dest.exists()){
System.out.println("文件不存在");
}
Reader reader = new FileReader(source);
Writer writer = new FileWriter(dest);
StringBuilder stringBuilder = new StringBuilder();
while (true){
int ch = reader.read();
if(ch == -1){
break;
}
stringBuilder.append((char)ch);
}
writer.write(stringBuilder.toString());
reader.close();//记得关闭资源
writer.close();
}
}
以上就是关于我们文件内容的操作及实战,感谢阅读(〃 ̄︶ ̄)人( ̄︶ ̄〃)