File类
File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)
File类声明在java.io包下
File类的实例化
File类的三个常用构造器,如下所示。
注意:
- 相对路径:相较于某个路径下,指明的路径。
- 在main函数下,相对路径是当前工程目录下
- 在Test测试方法中,相对路径是当前module下
- 绝对路径:包含盘符在内的文件或文件目录的路径
File类的常用方法
//File类常用API测试
@Test
public void test2(){
File file = new File("hello.txt");//相对路径,创建在当前Module下
String absolutePath = file.getAbsolutePath();//获取绝对路径
//G:\java\work_space\day0930_reviewJavaSenior\genericity\hello.txt
System.out.println(absolutePath);
String path = file.getPath();//获取路径,在创建对象时传入的路径
System.out.println(path);//hello.txt
File file2 = new File("D:\\fileTest\\hello.txt");
String name = file2.getName();//获取名称
System.out.println(name);//hello.txt
String parent = file2.getParent();//获取上层文件目录
System.out.println(parent);//D:\fileTest\java
long length = file2.length();//获取文件长度(字节数),不是获取目录长度。
System.out.println(length);//0
File file3 = new File("D:\\io");
//获取指定目录下的所有文件或者文件目录的名称数组
String[] list = file3.list();
for( String str:list){
System.out.println(str);
}
//获取指定目录下的所有文件或者文件目录的File数组
File[] files = file3.listFiles();
for (File file1:files){
System.out.println(file1.getName());
}
//把文件重命名为指定的文件路径
//要想保证重命名成功,调用此方法的File对象路径下文件或目录在硬盘中必须存在,
//而重命名路径下的文件或文件夹在硬盘中不存在。
boolean rename = file3.renameTo(new File("D:\\fileTest\\hello.txt"));
System.out.println(rename);
}
@Test
public void test3(){
File file = new File("D:\\fileTest\\hello");
boolean directory = file.isDirectory();//判断是否是文件目录
System.out.println(directory);
boolean file1 = file.isFile();//判断是否是文件
System.out.println(file1);
boolean exists = file.exists();//判断在硬盘中是否存在
System.out.println(exists);
boolean b = file.canRead();//判断是否可读
System.out.println(b);
boolean b1 = file.canWrite();//判断是否可写
System.out.println(b1);
boolean hidden = file.isHidden();//判断是否是隐藏文件
System.out.println(hidden);
}
File类的在磁盘中的创建与删除
@Test
public void test4() throws IOException {
//File类的创建功能
File file = new File("D:\\io\\ioTest.txt");
if (!file.exists()){
//文件创建
file.createNewFile();
System.out.println("创建成功!");
}else{//文件存在,删除文件
file.delete();
System.out.println("删除成功!");
}
}
@Test
public void test5(){
//文件目录的创建
//创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
File file1 = new File("D:\\io\\io1\\io2");
boolean mkdir = file1.mkdir();
if (mkdir){
System.out.println("mkdir创建成功!");
}
File file2 = new File("D:\\io\\io2\\io3");
//创建文件目录。如果上层文件目录不存在,一并创建
boolean mkdirs = file2.mkdirs();
if (mkdirs){
System.out.println("mkdirs创建成功!");
}
}
I/O流的使用
I/O 是Input/Output的缩写,I/O技术是非常实用的技术,用于处理设备之间的数据传输。如:读写文件,网络通讯等。
Java程序中,对于数据的输入输出操作以流(Stream)的方式进行。
java.io包下提供了各种流相关类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
流的分类:
- 按照操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
- 按数据流的流向不同分为:输入流、输出流
- 按流的角色不同分为:节点流,处理流
常用流的体系结构:
抽象基类 | 节点流(或文件流) | 缓存流(处理流的一种) | |
---|---|---|---|
字节流输入 | InputStream | FileInputStream | BufferedInputStream |
字节流输出 | OutputStream | FileOutputStream | BufferedOutputStream |
字符流输入 | reader | FileReader | BufferedReader |
字符流输出 | Writer | FileWriter | BufferedWriter |
节点流的使用
字符流的使用
FileReader输入流示例:
@Test
public void test1() {
FileReader reader = null;
try {
//1.实例化File对象,指明要操作的文件
File file = new File("hello.txt");
//2.提供具体的流
reader = new FileReader(file);
//3.数据的读入过程
char[] cbuf = new char[5];
int len;
//reader.read(cbuf)读入操作,每次返回读入cbuf数组中的字符的个数
//read返回一个字符。如果达到文本结尾,返回-1
while ((len = reader.read(cbuf)) != -1){
//常用读取数据方法
for (int i = 0; i < len; i++) {
System.out.print(cbuf[i]);
}
// //可行方式二
// String str = new String(cbuf,0,len);
// System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.手动关闭资源
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果
说明点:
- read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
- 异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
- 读入文件一定要存在,否则就会报FileNotFoundException
FileWriter字符输出流示例
@Test
public void test2() {
FileWriter writer = null;
try {
//1,提供FIle类的对象,指明写出到的文件
File file = new File("hello1.txt");
//2.提供具体的流
writer = new FileWriter(file);
//3.写入的操作
writer.write("我试试中文写不写的进去。");
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.资源的关闭
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果
从内存中写出数据到硬盘中,说明:
- 输出操作:对应File可以可以不存在的
- 如果不存在:在输出的过程中,会自动创建此文件
- 如果存在:
- 如果流适用的构造器是:FileWriter(file,false);/FileWriter(file);则会对原有数据进行覆盖
- 如果流使用的构造器是:FileWriter(file,true);则会在原有数据的基础上添加数据,不会覆盖
使用FileReader 和 FileWriter 实现文本复制操作
public void charCopy(String srcPath,String destPath){
FileReader fr = null;
FileWriter fw = null;
try {
//1,提供两个File类的对象,指明写出的文件和目标文件
File file1 = new File(srcPath);
File file2 = new File(destPath);
//2.提供输入输出流
fr = new FileReader(file1);
fw = new FileWriter(file2);
//3.复制操作
char[] cbuf = new char[5];
int len;
while ((len = fr.read(cbuf)) != -1){
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭资源
if (fw != null){//避免空指针异常出现
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
补充说明:
不能使用字符流来处理图片等字节数据
对于文本文件(.txt、.java、.c、.cpp),使用字符流处理
对于非文本文件(.jpg、.mp3、.mp4、.avi、.doc、.ppt,……),使用字节流来处理
字节流的使用
字节流的复制操作
//字节流的复制操作
public void byteCopy(String srcPath,String destPath){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File file1 = new File(srcPath);
File file2 = new File(destPath);
fis = new FileInputStream(file1);
fos = new FileOutputStream(file2);
byte[] bucf = new byte[8];
int len;
while ((len = fis.read(bucf)) != -1){
fos.write(bucf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
缓冲流的使用
作用:
- 提高流的读取、写入的速度
- 提高读写速度的原因:内部提供了一个缓冲区
字节缓冲流的复制操作
public void bufferedCopy(String srcPath,String DestPath){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//File类实例化
File file1 = new File(srcPath);
File file2 = new File(DestPath);
//创建字节流
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
//创建字节缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//复制
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//流的关闭
if (bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符缓冲流复制操作
public void bufferedCopy2(String srcPath,String DestPath){
BufferedReader br = null;
BufferedWriter bw = null;
try {
//File类实例化
File file1 = new File(srcPath);
File file2 = new File(DestPath);
//创建字节流
FileReader fr = new FileReader(file1);
FileWriter fw = new FileWriter(file2);
//创建字节缓冲流
br = new BufferedReader(fr);
bw = new BufferedWriter(fw);
//复制
//方式一:
// char[] buffer = new char[1024];
// int len;
// while ((len = br.read(buffer)) != -1){
// bw.write(buffer,0,len);
// }
//方式二:
//br.readLine(),直接读取文本中的一行数据,但不包括换行符,因此,需要手动在写入时加入"\n"换行符,或者调用newLine();换行
String data;
while ((data = br.readLine()) != null){
bw.write(data);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//流的关闭
if (bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
转换流的使用
public void copy(String srcPath,String destPath){
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
FileInputStream fis = new FileInputStream(new File(srcPath));
FileOutputStream fos = new FileOutputStream(destPath);//构造器二:直接闯入String类型的文件路径,内部自动创建一个File类
isr = new InputStreamReader(fis,"UTF-8");//在转换流中可以指定字符集,将文本转换为其他字符其的文本
osw = new OutputStreamWriter(fos,"GBK");
char[] buffer = new char[10];
int len;
while ((len = isr.read(buffer)) != -1){
osw.write(buffer,0,len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (isr != null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (osw != null){
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对象流
序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本数据类型或对象的机制
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二级制流持久的保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。//当其他程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化过程:将内存中的Java对象保存到磁盘中或通过网络传输出去
对象流的使用:
- ObjectInputStream 和 ObjectOutputStream
- 作用:用于存储和读取基本数据类型数据或对象的处理流。她的强大之处就是可以把Java中的对象持久化
- 要象一个Java对象是可序列化的,需要满足相应的要求。
- 需要实现接口:Serializable
- 当前类提供一个全局常量:SerialVersionUID
- 除了当前类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型也是可序列化的。)
补充:ObjectInputStream 和 ObjectOutputStream不能序列化staitc 和 transient修饰的成员变量
示例:
@Test
public void test(){
ObjectOutputStream oos = null;
FileInputStream fis = null;
try {
FileOutputStream fos = new FileOutputStream("hello.dat");
fis = new FileInputStream("hello.txt");
oos = new ObjectOutputStream(fos);
byte[] buffer =new byte[10];
int len;
while ((len = fis.read(buffer)) != -1){
oos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}