1、File对象的创建
其中第一个\:表示转义字符 第二个\:表示目录层级
File file = new File("E:\\idea\\AAA\\test1.txt");
注:目录层级 在window系统中 \ ;在Linux和mac系统中 /
Java是一个跨平台语言,可以在window系统和Linux和mac系统上使用,那么怎么解决层级目录的问题呢?
(1)window系统兼容 \ 和 /,所以File对象创建的时候可以直接写成下面这种形式
File file = new File("E:/idea/AAA/test.txt");
(2)使用File.separator,在不同的系统中显示不同形式的成绩目录
File file2 = new File("E:"+File.separator+"AAA"+File.separator+"test1.txt");
2、文件的创建和目录的创建
createNewFile():创建文件
mkdir():创建目录
mkdirs():创建多级目录
public class TestAdd {
public static void main(String[] args) throws IOException {
File file = new File("E:/idea/AAA/test1.txt");
file.createNewFile();//创建文件
File file1 = new File("E:/idea/AAA/test");
file1.mkdir();//make directory 创建目录
File file2 = new File("E:/idea/AAA/test2.txt");
file2.createNewFile();
File file3 = new File("E:/idea/AAA/CCC");
file3.mkdir();
File file4 = new File("E:/idea/AAA/test/aaa");
file4.createNewFile();
File file5 = new File("E:/idea/AAA/aaa/aaa");
file4.mkdirs();
}
}
3、删除
public class TestDel {
public static void main(String[] args) throws InterruptedException {
File file = new File("E:/idea/AAA/test1.txt");
File file1 = new File("E:/idea/AAA/test");
File file2 = new File("E:/idea/AAA/test2.txt");
File file3 = new File("E:/idea/AAA/CCC");
File file4 = new File("E:/idea/AAA/test/aaa");
//删除操作 有文件时不能删除
//delete():只能删除空目录
file1.delete();
file4.delete();
//deleteOnExit():程序退出时删除文件
file3.deleteOnExit();
Thread.sleep(10000);
}
}
4、修改权限和重命名
public class TestChange {
public static void main(String[] args) {
File file = new File("E:/idea/AAA/test1.txt");
File file1 = new File("E:/idea/AAA/test");
File file2 = new File("E:/idea/AAA/test2.txt");
File file3 = new File("E:/idea/AAA/CCC");
File file4 = new File("E:/idea/AAA/test/aaa");
//设置文件权限
file.setReadable(false);//读权限
file.setReadOnly();//设置只读
file.setWritable(false);//写权限
//重命名 renameTo():传入的参数类型为File对象类型
file.renameTo(new File("E:/idea/AAA/test4.txt"));
}
}
5、查询
public class TestFind {
public static void main(String[] args) {
File file = new File("E:/idea/AAA/test1.txt");
//查询文件是否存在
boolean exists = file.exists();
System.out.println(exists);
//查询文件的名称
String name = file.getName();
System.out.println("file -- name:"+name);//file -- name:test1.txt
//获取文件的父级路径
String parent = file.getParent();
System.out.println("file -- parent:"+parent);//file -- parent:E:\idea\AAA
//获取文件的完整路径
String path = file.getPath();
System.out.println("file -- path:"+path);//file -- path:E:\idea\AAA\test1.txt
//判断File对象是不是文件
boolean f = file.isFile();
System.out.println(f);//true
//判断File对象是不是目录
boolean d = file.isDirectory();
System.out.println(d);//false
File file1 = new File("E:/idea/AAA");
//列出E:/idea/AAA目录下的所有文件对象
File[] files = file1.listFiles();
//System.out.println(files);//[Ljava.io.File;@4554617c
for (File file2 : files) {
//String s = String.valueOf(x);底层源码重写了toString方法
System.out.println(file2);
}
//获取E:/idea/AAA目录下的所有子文件的名称
String[] list = file1.list();
System.out.println(list);//[Ljava.lang.String;@4554617c
System.out.println(Arrays.toString(list));//[CCC, test, test1.txt, test2.txt]
}
}
案例:输出某一个目录下所有的文件,包括子目录里的文件,使用递归实现
public class TestDigui {
public static void main(String[] args) {
//输出E:/idea/AAA目录下的所有文件,不包含目录
Find("E:/idea/AAA");
}
//输出所有的文件,不包括目录
public static void Find(String path){
//根据传入的path路径创建File对象
File file = new File(path);
//如果不是目录也不是文件直接退出
if (!file.isDirectory() && !file.isFile()){
return;
}
//获取该目录下的所有File对象
File[] files = file.listFiles();
for (File f: files ) {
//是目录继续查找
if (f.isDirectory()){
Find(f.getPath());
}else {
System.out.println(f.getPath());
}
}
}
}
//运行结果
E:\idea\AAA\test\aaa
E:\idea\AAA\test1.txt
E:\idea\AAA\test2.txt
6、IO流
IO:Java的输入输出流,对文件内容进行读写操作
I:inputStream输入流(读) O:outputStream输出流(写)
Java流的分类:
(1)流向
- 输入流:程序可以从中读取数据的流
- 输出流:程序能向其中写入数据的流
(2)流的单位
- 字节流:以字节为单位传输数据的流
- 字符流:以字符为单位传输数据的流
(3)功能
- 节点流:直接和文件进行交互
- 处理流:不能直接作用在文件上,需要一个中间的容器
四个基本的流:其他的流都是在这些流的基础上扩展的
InputStream:字节输入流
OutputStream:字节输出流
Reader:字符输入流
Writer:字符输出流
示例代码:
Writer字符输出流
public class TestWriter {
public static void main(String[] args) throws IOException {
//字符输出流(指定对哪个文件(路径)进行写操作)
Writer writer = new FileWriter("E:/idea/AAA/test1.txt");
String str = "hello";
//使用此方法每次都会覆盖之前的内容
writer.write(str);
//刷新流
writer.flush();
//关闭流
writer.close();
}
}
以上这种方式,每次写入都会覆盖之前的内容,那么怎么实现追加效果呢?
public class TestWriter {
public static void main(String[] args) throws IOException {
//不覆盖之前的内容,实现追加效果,设置FileWriter的append属性为true,即可实现追加效果
Writer writer1 = new FileWriter("E:/idea/AAA/test1.txt",true);
String str1 = " world!";
writer1.append(str1);//hello world!
writer1.flush();
writer1.close();
}
}
Reader输入流
read方法每次读取后会记录读取的位置,下一次读取时从剩下未读取的部分开始读取。
public class TestReader {
public static void main(String[] args) throws IOException {
//创建需要读取的文件对象
Reader reader = new FileReader("E:/idea/AAA/test1.txt");
//read()方法返回的时第一个字符的ASSIC表中对应的值,需要进行数据转换
//int read = reader.read();
//System.out.println((char) read);
//定义一个char数组,每次读取的内容存放在数组中
char[] cs = new char[5];
//读取的字符个数
int count = 0;
//当reader.read(cs)为-1时表示文件中的内容结束
while ((count = reader.read(cs))!=-1){
//System.out.print(cs);//hello world!orl
//将每次读取的数组转为字符串存储,从下标为0的位置存储,存储读取的个数
String str = new String(cs,0,count);
System.out.print(str);//hello world!
}
/*char[] cs = new char[5];
int read1 = reader.read(cs);
System.out.println(read1);//5
System.out.println(cs);//hello
read1 = reader.read(cs);
System.out.println(read1);//5
System.out.println(cs);// worl
read1 = reader.read(cs);
System.out.println(read1);//2
System.out.println(cs);//d!orl 数组内容替换*/
}
}
使用字符输入输出流实现文件的复制
public class TestCopyFile {
//使用字符输入输出流完成文件复制
@Test
public void copyFile() throws IOException {
//创建一个字符输入流
FileReader fileReader = new FileReader("E:/idea/AAA/test1.txt");
//创建一个字符输出流
FileWriter fileWriter = new FileWriter("E:/idea/AAA/test3.txt");
int count = 0;
char[] cs = new char[5];
while ((count = fileReader.read(cs)) != -1) {
fileWriter.write(cs, 0, count);
fileWriter.flush();
}
fileWriter.close();
fileReader.close();
}
}
这里用到了junit单元测试
junit 单元测试 @Test注解 可以让方法独立运行,相当于main方法的作用
修饰符为public 不能有返回值,也不能有形参
@Test public void test1(){ System.out.println("~~~~~~~~~~~~~~~~~~~~~"); } @Test public void test2(){ System.out.println("---------------------"); }
使用字符输入输出流可以复制文件,那么可以复制图片和视频吗?
字符输入输出流以字符为单位,复制图片和视频需要使用字节输入输出流
OutputStream字节输出流
当定义的字节输出流没有该文件时,会新建文件,但是不会新建目录
需要将要存储的数据转为字节数组进行存储
public class TestStream {
//字节输出流测试
@Test
public void testOutputStream() throws IOException {
//如果没有文件会新建文件,但是不会新建目录
OutputStream outputStream = new FileOutputStream("E:/idea/AAA/test4.txt");
String str = "hello";
//把字符串转为字节数组
byte[] bytes = str.getBytes();
outputStream.write(bytes);
outputStream.close();
}
}
InputStream字节输入流
以字节数组为单位读取,如果中文可能会出现乱码情况,utf-8编码下一个汉字占3个字节,如果不正常读取,就会出现中文乱码情况,解决方法:可以将字节数组的容量设置的足够大,但是如果文件中的内容是文本的话,推荐使用字符输入流。
public class TestStream {
//字节输入流测试
@Test
public void testInoutStream() throws IOException {
//定义字节输入流
InputStream inputStream = new FileInputStream("E:/idea/AAA/test4.txt");
//定义字节数组
byte[] bytes = new byte[3];
int count = 0;
while ((count = inputStream.read(bytes))!=-1){
String str = new String(bytes,0,count);
//System.out.print(bytes);//[B@14bf9759[B@14bf9759
//System.out.print(Arrays.toString(bytes));//[104, 101, 108][108, 111, 108]
System.out.print(str);//hello
}
inputStream.close();
}
}
使用字节输入输出流实现图片的复制
public class TestCopyImg {
@Test
public void copyImg() throws IOException {
InputStream inputStream = new FileInputStream("E:/idea/AAA/cat.jpg");
OutputStream outputStream = new FileOutputStream("E:/idea/AAA/cat1.jpg");
byte[] bytes = new byte[5];
int count = 0;
while ((count = inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,count);
}
outputStream.close();
inputStream.close();
}
}
缓存流
缓存流是在四个基础流上添加了一个缓冲池的功能,可以提高IO的效率,降低IO的次数。
读写操作,先将数据存入缓存池中,然后刷新缓存池,将数据写入文件/程序
public class TestBuffer {
//输出缓存流测试
@Test
public void testOuntputBuffer() throws IOException {
OutputStream out = new FileOutputStream("E:/idea/AAA/test8.txt");
//缓存流必须作用在四个基础流上
BufferedOutputStream bos = new BufferedOutputStream(out);
String str = "qwertyuiop";
byte[] bytes = str.getBytes();
//写入的内容暂时存放在缓存池中,如果不刷新缓存池,文件中就不会显示你的完整内容
bos.write(bytes);
//关闭缓存流,先刷新缓存池,在关闭流资源
bos.close();
}
}
对象流
对象流的作用就是让数据持久化,即存储到硬盘上,相当于存档(写,序列化),读档(读,反序列化)
对象输出流(存档)
public class TestObjStream {
//存档 序列化
@Test
public void objOutputStream() throws IOException {
OutputStream outputStream = new FileOutputStream("E:/idea/AAA/Game.txt");
//定义对象输出流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
//定义对象
Game game = new Game("zjw",3,"耍无赖");
//使用对象输出流调用输出方法 输出的类对象 该类必须实现Serializable 序列化接口 java.io.NotSerializableException
objectOutputStream.writeObject(game);
objectOutputStream.close();
}
}
对象输入流(读档)
public class TestObjStream {
@Test
public void objInputStream() throws IOException, ClassNotFoundException {
InputStream inputStream = new FileInputStream("E:/idea/AAA/Game.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
Object object = objectInputStream.readObject();
System.out.println(object);//com.gjx.testIO.Game@59ec2012
objectInputStream.close();
}
}