File类
理解
File类位于java.io包下,File类的一个对象对应操作系统下一个文件或一个文件目录
File实例化
文件路径的表达方式:
方式1:绝对路径。以Windows为例,包括盘符在内的文件或文件目录的完整路径
d://io//hello.txt <-----> d:\io\hello.txt
方式2:相对路径:相对于某一个文件目录来讲的相对位置
在IDEA中,如果使用单元测试方法:相对于目前的module来讲
如果使用main()方法:相对于当前的project来讲
可以调用getAbsolutePath()方法查看
构造器
public class FileTest {
@Test
public void test1(){
File file2=new File("abc");
}
@Test
public void test2(){
File file = new File("d:\\io", "abc");
File file1 = new File(file, "456");
}
}
常用方法
public class FileMethodTest {
/**
* 获取文件和目录的基本信息
*/
@Test
public void test(){
File file1 = new File("hello.txt");
System.out.println(file1.getName());//只看文件或文件目录的名字
System.out.println(file1.getPath());
System.out.println(file1.getAbsolutePath());
System.out.println(file1.getAbsoluteFile().getParent());
System.out.println(file1.getParent());
System.out.println(file1.length());//不适用于文件夹求大小
System.out.println(file1.lastModified());
}
/**
* 列出目录的下一级
*/
@Test
public void test2(){
File file = new File("d:/temp");
String[] list = file.list();
for(Object obj:list){
System.out.println(obj);
}
System.out.println();
File[] files = file.listFiles();
for(File f:files){
System.out.println(f);
}
}
/**
* File类的重命名
* renameTo返回成功条件:file1必须存在,file2必须不存在
*/
@Test
public void test3(){
File file1 = new File("hello.txt");
File file2 = new File("d:/io/abc.txt");
boolean b = file1.renameTo(file2);
System.out.println(b ? "命名成功:" : "命名失败");
}
/**
* 判断功能的方法
*/
@Test
public void test4(){
File file1 = new File("d:/io/abc.txt");
System.out.println(file1.exists());
System.out.println(file1.isDirectory());
System.out.println(file1.isFile());
System.out.println(file1.canRead());
System.out.println(file1.canWrite());
System.out.println(file1.isHidden());
}
/**
* 文件删除和操作
*/
@Test
public void test5(){
File file = new File("d:/io/hello.txt");
if(!file.exists()){
try {
boolean newFile = file.createNewFile();
if(newFile){
System.out.println("创建成功");
}
} catch (IOException e) {
e.printStackTrace();
}
}else{
System.out.println("此文件已存在");
file.delete();
System.out.println("文件删除成功");
}
}
/**
* 创建文件目录
* mkdir()难以应对上层目录不在的情况
*/
@Test
public void test6(){
File file = new File("d:/io/io3");
file.mkdir();
File file1 = new File("d:/io/io3/io33");
file1.mkdirs();
file1.delete();
file.delete();
}
}
不要光整面上笔记的东西,还是要代码要熟练,不要畏惧写代码。
IO流
站在内存角度衡量输入(数据从外部流入内存),输出(从内存输出到外部,比如磁盘等)
(抽象基类) | 输入流 | 输出流 |
---|---|---|
字节流 | InputStream | OutPutStream |
字符流 | Reader | Writer |
异常记录
1.写的时候忘了传cbuffer参数,默认使用了空参read,依次只能读取一个字符,返回值是该字符的int型,即len = 73(hello.txt文件中第一个字符为大写I,值为73),报空指针异常。
File src = new File("hello.txt");
File desc = new File("hello_copy.txt");
fileReader = new FileReader(src);
fileWriter = new FileWriter(desc);
char[] cbuffer = new char[5];
int len;
//正确写法:len = fileReader.read(cbuffer)
while ((len = fileReader.read()) != -1) {
fileWriter.write(cbuffer, 0, len);
}
2.写的时候经常设计流资源的关闭操作,所以要使用try-catch-finally解决异常
3.文件可能为空,在关闭前应判断文件是否为空。
4.对于输入流来讲,要求File类的对象在物理磁盘上的文件必须存在。输出流可以不存在,会自动创建。默认写入是覆盖方式。
字符流实例代码
package com.atguigu01_filestream.exer1;
import org.junit.Test;
import java.io.*;
public class FileReaderWriterTest {
@Test
public void test() {
FileReader fileReader = null;
try {
//1.创建File对象
File file = new File("hello.txt");
//2.创建输入流
fileReader = new FileReader(file);
//3.读取数据并显示到控制台上
char[] cbuffer = new char[5];
int len;
while ((len = fileReader.read(cbuffer)) != -1) {
for (int i = 0; i < len; i++) {
System.out.println(cbuffer[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.流资源关闭
try {
if (fileReader != null)
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void test2() throws IOException {
FileWriter fileWriter = null;
try {
File file = new File("info.txt");
fileWriter = new FileWriter(file);
fileWriter.write("I love you\n");
fileWriter.write("you love him\n");
fileWriter.write("太惨了");
System.out.println("输出成功");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileWriter != null)
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void test3() throws IOException {
FileReader fileReader = null;
FileWriter fileWriter = null;
try {
File src = new File("hello.txt");
File desc = new File("hello_copy.txt");
fileReader = new FileReader(src);
fileWriter = new FileWriter(desc);
char[] cbuffer = new char[5];
int len;
while ((len = fileReader.read()) != -1) {
fileWriter.write(cbuffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileWriter != null)
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fileReader != null)
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字节类实例代码
文本文件:.txt,.java,.c,等
非文本文件:.doc,.xls,.jpg.pdf等
public class FileStreamTest {
@Test
public void test1() throws FileNotFoundException {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
File src = new File("FashionClothes.jpg");
File desc = new File("FashionClothes_copy.jpg");
fileInputStream = new FileInputStream(src);
fileOutputStream = new FileOutputStream(desc);
byte[] buffer=new byte[1024];
int len;
while ((len=fileInputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileOutputStream!=null)
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fileInputStream!=null)
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void test2(){
File file = new File("FashionClothes_copy.jpg");
file.delete();
}
}
处理流:缓冲流
抽象基类 | 文件流 | 缓冲流 |
---|---|---|
InputStream | FileInputStream | BufferedInputStream |
OutputStream | FileOutputStream | BufferedOutputStream |
Reader | FileReader | BufferedReader |
Writer | FileWriter | BufferedWriter |
处理流:转换流
编码:字符->字节
解码:字节->字符
API:
InputStreamReader:解码,将一个输入型的字节流转换为输入型的字符流
OutputStreamWriter:编码,将一个输出型的字符流转换为输出型的字节流。
关于字符集中的理解:
在存储中的文件的字符集:
ascii码:主要存储abc,123,常用标点符,总共128个。每个字符占用一个字节
gbk:存储包括中文简体繁体,abc,123,常用标点符等。中文字符使用两个字节存储,向下兼容ascii码,英文标点符号是一个字节,中文格式下标点符号占两个字节。
utf-8:每次8个位传输数据。存储世界范围内主要语言的所有字符。
1.中文3个字节
2.ascii一个字节
在内存中的字符:
不管中文还是英文,一个字符(char)占用2个字节。比如内存中一个'a'占用2个字节。
在内存中使用的字符集称为”Unicode"字符集
处理流:对象流
对象的序列化机制:
把内存中的Java对象转换成平台无关的二进制流。
序列化过程:将内存中的Java对象保存在文件中或通过网络传输出去。ObjectOutputStream
反序列化过程:逆向过程。ObjectInputStream
自定义类implements Serializable,自定义声明一个全局常量,自定义类的各个属性也必须是可序列化的
注意:类中的属性如果声明为transient或static,则不会实现序列化,也就是属性的值不会保存在文件中