目录
针对文件内容操作:
一.常见的数据流有两种:
1.字节数
以字节为单位进行读取
2.字符流
以字符形式进行读取
二、读写文件内容的过程
1.打开文件
2.读文件/写文件
3.关闭文件
在打开文件时,操作系统会为该文件在文件描述符表(一种数据结构)申请资源,如果一直打开,而不关闭,文件描述符表中的内容就会被耗尽。后序进行打开文件操作,就会失败,同时,可能会出现文件泄露的情况。(在java中,提供了垃圾回收机制,)
三、常见的类和方法
涉及的方法用法类似:
这里的输入输出是相对于CPU来讲的。数据从硬盘到CPU叫输入,数据从CPU到硬盘叫做输出。
(1)对于字节流
InPutStream 输入流
OutPutStream 输出流
(2)对于字符流
Reader 读
Writer 写
(3)基于InputStream 的常见操作方法
用InputStream 读取文件的内容:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoDemo4 {
//读,输入,从硬盘中将数据读取到cpu
public static void main(String[] args) throws IOException {
InputStream inputStream=new FileInputStream("./text.txt");//打开文件
byte [] bytes=new byte[1024];
int n= inputStream.read(bytes);//输出型参数,准备好容器,将读取的数据存入字符数组
String s=new String(bytes,0,n);//构建字符串
System.out.println(s);//显示
inputStream.close();//关闭输入流
}
}
1.对于inputStream 对象的参数,如果该文件不存在,则直接报错
2.使用InputStream创建对象的过程,就是打开文件的过程
3.如果使用inputStream.read(),则是一次读取一个字节。
如果想要读取多个字节,则可以创建一个字节数组,调用read(byte[])即可。
如果想要读取从len开始,偏移off后,len长度,则可以使用 read(byte[] ,int off,int length);
4.返回值n 表示实际读取的字节长度。如果n=-1,表示已读取完毕
5.中文在Java中用三个字节utf-8表示,在读取中文时,如果直接查看byte[] 数组中的值,则:
所以,这里使用 new String(byte,0,n);的方式,会将utf-8转换成Unicode后,再转换成Utf-8,从而显示正确的数据:
6.输入流的关闭。这里使用.close()方法。但是在写内部逻辑时,很多时候,一句return 会导致代码无法执行到该方法。所以,可以使用另一种方式:try with resources:
即:将输入流的操作放在try()语句中,当代码执行完毕后,try会自动执行close()方法,将输入流关闭。代码展示:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IoDemo4 {
//读,输入,从硬盘中将数据读取到cpu
public static void main(String[] args) throws IOException {
try( InputStream inputStream=new FileInputStream("./text.txt")) {
//打开文件
byte[] bytes = new byte[1024];
int n = inputStream.read(bytes);//输出型参数,准备好容器,将读取的数据存入字符数组
String s = new String(bytes, 0, n);//构建字符串
System.out.println(s);//显示
}
}
}
也可以达到相同的效果。
(4)基于OutPutStream 的常见操作方法
用OutputStream 在文件写入内容:
输出流也同样要关闭资源。在代码中将使用try()语句进行操作:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class IoDemo5 {
public static void main(String[] args) {
try(OutputStream outputStream=new FileOutputStream("text1.txt")) {
//打开文件
byte[] bytes=new byte[10];
for (int i = 0; i < 10; i++) {
bytes[i]='d';
}
outputStream.write(bytes);//写入
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
1.创建对象同时打开文件。如果文件不存在,会创建该文件。不能创建目录。
2.创建的数组对写入的内容,也可以写入一个字节,使用write(‘a’)方法。
3.对于写操作,打开文件时,会清空文件里的内容(默认)。如果想在原有的基础上,继续写,可以在打开时,多加一个true的参数:
try(OutputStream outputStream=new FileOutputStream("text1.txt",true)) {
//打开文件
} catch (IOException e) {
throw new RuntimeException(e);
}
}
4.关闭输出流。
(5)基于Writer与Reader抽象类
Witer 与Reader 是以char为单位进行操作,与OutputStream、InputSream 的用法类似:
import java.io.*;
public class IoDemo6 {
public static void main(String[] args) throws IOException {
try(Writer writer=new FileWriter("./text.txt",true);
Reader reader=new FileReader("./text.txt")) {
String d="shifhwgthtg";
writer.write(d);
char[] chars=new char[4096];
int m= reader.read(chars);
String s=new String(chars,0,m);
System.out.println(s);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
注意:1.Writer时打开文件,会将文件内容清空,会导致n=-1,构建不了字符串,会报错。
用法与字节流类似。
用Scaner也可以对文件进行读取,将System.in改为输入流即可。
例如:
import java.io.*;
import java.util.Scanner;
public class IoDemo7 {
public static void main(String[] args) throws IOException {
try(InputStream inputStream=new FileInputStream("./text.txt")){
Scanner scanner=new Scanner(inputStream);
String s=scanner.nextLine();
System.out.println(s);
}
}
}
读取文件内容。