File类:
Java API:java.io.File 类 访问文件属性
1.首先创建一下file的对象:
里面可以写相对路径或者绝对路径
File file = new File("CCC.java");
通过对象引用下面的这些方法来实现对文件的操作
流:
java如何读写文件?:通过流
流是一组有序的数据序列以先进先出方式发送信息的通道
Java流的分类:
1.按照流向区分
输入流和输出流
根据流传输方向的不同,又可分为输入流和输出流。其中输入流只能从流中读取数据,而不能向其写入数据;输出流只能向流中写入数据,而不能从中读取数据。
字节流是8位通用字节流,字节流是16位Unicode字符流
2.按照处理数据单元划分
字节流和字符流
根据流操作的数据单位的不同,可以分为字节流和字符流。字节流以字节为单位进行数据的读写,每次读写一个或多个字节数据;字符流以字符为单位进行数据的读写,每次读写一个或者多个字符数据。
字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:
(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。
结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
输入流和输出流
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
字节流概述(InputStream和OutputStream):
InputStream被看成一个输入管道,OutputStream被看成一个输出管道,数据通过InputStream从源设备输入到程序,通过OutputStream从程序输出到目标设备,从而实现数据的传输。由此可见,I/O流中的输入/输出都是相对于程序而言的。
InputStream类:
常用方法:
第一个read()方法是从输入流中逐个读入字节,而第二个和第三个read()方法则将若干字节以字节数组的形式一次性读入,从而提高读数据的效率。
方法 | 方法描述 |
int read( ) | 从输入流读取一个8位的字节,把它转换为0~255之间的整数,并返回这一整数。当没有可用字节时,将返回-1 |
int read(byte[] b) | 从输入流读取若干字节,把它们保存到参数b指定的字节数组中,返回的整数表示读取字节的数目 |
int read(byte[] b,int off,int len) | 从输入流读取若干字节,把它们保存到参数b指定的字节数组中,off指定字节数组开始保存数据的起始下标,len表示读取的字节数目 |
void close( ) | 关闭此输入流并释放与该流关联的所有系统资源 |
int available(); | 获取当前流中可用的字节数。 |
子类FileInputStream常用的构造方法:
FileInputStream(File file)
FileInputStream(String name)
OutputStream类:
常用方法:
第一个方法逐个写入字节,后两个方法是将若干个字节以字节数组的形式一次性写入,从而提高写数据的效率。
方法 | 描述 |
void write(int c) | 向输出流写入一个字节 |
void write(byte[] buf) | 把参数b指定的字节数组的所有字节写到输出流 |
void write(byte[] b,int off,int len) | 将指定byte数组中从偏移量off开始的len个字节写入输出流 |
void close() | 刷新此输出流并强制写出所有缓冲的输出字节 |
void flush(): | 强制把缓冲区的数据写到输出流中 |
子类FileOutputStream常用的构造方法:
FileOutputStream (File file)
FileOutputStream(String name)
FileOutputStream(String name,boolean append)
1.前两种构造方法在向文件写数据时将覆盖文件中原有的内容
2.创建FileOutputStream实例时,如果相应的文件并不存在,则会自动创建一个空的文件
字节流读写文件:
使用FileOutputStream 写文本文件:
创建一个out.txt并且写入文本
public static void main(String[] args) throws Exception {
// 创建文件输出流对象,并指定输出文件名称
FileOutputStream out = new FileOutputStream("out.txt");
// 定义一个字符串
String str = "hello";
// 将字符串转换为字节数组进行写入操作
out.write(str.getBytes());
// 关闭流
out.close();
}
使用FileInputStream 读文本文件
FileInputStream是InputStream的子类,它是操作文件的字节输入流,专门用于读取文件中的数据。
结果是以 这是因为读取到硬盘上的文件是以字节的形式存在的。每一个字母各占一个字节因此,最终结果显示的是文件“test.txt”中的字节所对应的ASCII码值。
public static void main(String[] args) throws Exception {
// 创建一个文件字节输入流来读取文件
FileInputStream in = new FileInputStream("test.txt");
// 定义一个int类型的变量b
int b = 0;
// 通过循环来读取文件,当返回值为-1结束循环
while((b=in.read()) != -1){
System.out.println(b);
}
// 关闭流
in.close();
}
文件的拷贝:
while循环将字节逐个进行拷贝。每循环一次,就通过FileInputStream的read()方法读取一个字节,并通过FileOutputStream的write()方法将该字节写入指定文件,循环往复,直到读取的长度len的值为-1,表示读取到了文件的末尾,结束循环,完成文件的拷贝。
public static void main(String[] args) throws Exception {
// 创建文件输入流对象读取指定目录下的文件
FileInputStream in = new FileInputStream("source/src.png");
// 创建文件输出流对象将读取到的文件内容写入到指定目录的文件中
FileOutputStream out = new FileOutputStream("target/dest.png");
// 定义一个int类型的变量len
int len = 0;
// 获取拷贝文件前的系统时间
long beginTime = System.currentTimeMillis();
// 通过循环将读取到的文件字节信息写入到新文件
while ((len = in.read()) != -1) {
out.write(len);
}
// 获取拷贝之后的系统时间
long endTime = System.currentTimeMillis();
// 输出拷贝花费时间
System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
// 关闭流
in.close();
out.close();
}
字节流的缓冲区
虽然上一小节实现了文件的拷贝,但是一个字节一个字节的读写,需要频繁的操作文件,这种效率是非常低的。
当通过流的方式拷贝文件时,为了提高传输效率,也可以定义一个字节数组作为缓冲区。这样,在拷贝文件时,就可以一次性读取多个字节的数据,将数据先保存在字节数组中,然后将字节数组中的数据一次性写入到新文件中。
public static void main(String[] args) throws Exception {// 创建文件输入流对象读取指定目录下的文件
FileInputStream in = new FileInputStream("source/src.jpg");
// 创建文件输出流对象将读取到的文件内容写入到指定目录的文件中
FileOutputStream out = new FileOutputStream("target/dest.jpg");
// 定义一个int类型的变量
lenint len = 0;
// 定义一个长度为1024的字节数组
byte[] buff = new byte[1024];
// 获取拷贝文件前的系统时间
long beginTime = System.currentTimeMillis();
// 通过循环将读取到的文件字节信息写入到新文件
while ((len = in.read(buff)) != -1) {
// 每循环读取一次字节数组,就将所读取到的内容写入到文件
out.write(buff,0,len);
}
// 获取拷贝之后的系统时间
long endTime = System.currentTimeMillis();
// 输出拷贝花费时间
System.out.println("花费时间为:"+(endTime-beginTime) +"毫秒");
// 关闭流
in.close();
out.close();
}
字节缓冲流: BufferedInputStream
, BufferedOutputStream
在IO包中提供了两个带缓冲的字节流,分别是BufferedInputStream和BufferedOutputStream,它们的构造方法中分别接收InputStream和OutputStream类型的参数作为对象
创建了BufferedInputStream和BufferedOutputStream两个缓冲流对象,这两个流内部都定义了一个大小为8192的字节数组,当调用read()或者write()方法读写数据时,首先将读写的数据存入到定义好的字节数组,然后将字节数组的数据一次性读写到文件中,这种方式与前面小节中讲解的字节流的缓冲区类似
子类BufferedReader特有的方法:
readLine()
字节缓冲流复制文本
public static void main(String[] args) throws Exception {
// 创建用于输入和输出的字节缓冲流对象
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("reader.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("writer.txt"))) {
// 定义一个int类型的变量来存储读取的字节
int byteData;
// 获取拷贝文件前的系统时间
long beginTime = System.currentTimeMillis();
// 通过循环读取输入字节缓冲流中的数据,并通过输出字节缓冲流写入到新文件
while ((byteData = bis.read()) != -1) {
bos.write(byteData);
}
// 获取拷贝之后的系统时间
long endTime = System.currentTimeMillis();
// 输出拷贝花费时间
System.out.println("花费时间为:" + (endTime - beginTime) + "毫秒");
}
字符流(Reader和Writer):
InputStream类和OutputStream类在读写文件时操作的都是字节,如果希望在程序中操作字符,使用这两个类就不太方便了
同字节流一样,字符流也有两个抽象的顶级父类,分别是Reader和Writer。其中Reader是字符输入流,用于从某个源设备读取字符。Writer是字符输出流,用于向某个目标设备写入字符。
其中FileReader和FileWriter用于读写文件,BufferedReader和BufferedWriter是具有缓冲功能的流,使用它们可以提高读写效率。
Writer类常用的方法:
write(String str)
write(String str,int off,int len)
void close()
void flush()
子类OutputStreamWriter常用的构造方法:
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out,String charsetName)
FileWriter类:
FileWriter类是OutputStreamWriter的子类
该类只能按照本地平台的字符编码来写数据,用户不能指定其他的字符编码类型
FileWriter (File file)
FileWriter (String name)
// 创建FileWriter对象,并指定写入数据的目标文件
FileWriter fileWriter = new FileWriter("writer.txt");
//写文本文件
fileWriter.write();
//关闭相关的流对象
fileWriter.close();
其余知识点请看下一篇。