一.java.io.File类
1.简介
File类:1.磁盘上的文件 2.磁盘上的目录
File提供了操作文件和目录的基本方法
File类不能直接访问文件中的内容,如果要访问需要用输入/输出流
2.File类中的构造方法
File file1 = new File("D:\\studyFile\\java");
File file2 = new File(new File("D:\\studyFile"), "java");
File file3 = new File("D:\\studyFile", "java");
绝对路径 D:\study\file(Windows) /home/etc(Linux)
相对路径 .当前路径 ../上一级路径
3.File类常用方法()
例如:File f = new File("D:\\studyFile\\tcp");
用途 | 函数 | 结果 |
文件名 | f.getName() | tcp |
路径名 | f.getPath() | D:\studyFile\tcp |
绝对路径名 | f.getAbsolutePath() | D:\studyFile\tcp |
父目录 | f.getParent() | D:\studyFile |
父目录对象 | f.getParentFile() | D:\studyFile |
长度(文件字节) | f.length() | 8099 |
最后修改时间 | f.lastModified() | 1685270881789 |
是否存在 | f.exists() | true |
是否为文件 | f.isFile() | true |
是否为目录 | f.isDirectory() | false |
创建文件 | f.createNewFile() | 存在则false,否则创建 |
重命名 | f.renameTo(File dest) | |
删除 | f.delete() | |
创建一级目录 | f2.mkdir(); | |
创建迭代目录 | f3.mkdirs(); | |
获取当前目录下的文件和目录名称 | String[] list = f3.list(); | 名字 |
获取当前目录下的文件和目录对象 | File[] list=f3.listFiles() | 代表对象 输出指向他的绝对路径 全路径 |
4.递归获取所有文件
public static void check(File f) {
if(!f.exists()) {
return;
}
File[] listFiles = f.listFiles();
for (File file : listFiles) {
if(file.isFile()) {
System.out.println(file.getAbsolutePath());
}else {
check(file);
}
}
}
// 是文件则输出其绝对路径 是目录则递归直至到其为一个文件为止
5.文件过滤---将图片全都筛选出来
public static void main(String[] args) {
File file = new File("D:\\studyFile\\tcp");
String[] list = file.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if(name.endsWith(".jpg")||name.endsWith(".png"))
return true;
return false;
}
});
System.out.println(Arrays.toString(list));
}
public interface FilenameFilter
tips:FilenameFilter()是接口 不能new 需要new一个实现类/匿名内部类
new之后的括号中其实可以看做你写了一个类,实现了这个接口,重写了方法,只不过这个类是匿名的,没有名字,所以称为匿名内部类。并且对象的创建最终都是需要调用构造方法,接口中是没有构造方法的,类中显示声明构造方法,但默认有空参构造方法,接口中是没有的。
二.IO流
1.简介
IO:input output 输入和输出流
通过IO流实现对文件的读写操作
流Stream: 一组,有序的,有起点有终点的动态数据集合
文件是数据在硬盘的静态存储
流是数据在传输是的动态形态 输入流:磁盘文件读取到程序中 输出流:程序写到磁盘文件中
2.流的分类
按照流中的数据单位:
字节流:操作数据的最小单位为字节 图片 音频 视频 二进制形式存储
字符流:操作数据的最小单位为字符 文本 中文(字节容易出现读取一半中文的情况)
按照数据的来源
节点流:直接对数据源进行操作
包装流:对一个节点流进行操作
依赖其他流(ObjectInputStream/ObjectOutputStream BufferedReader/BufferedWriter)
字节流 | 字符流 | |
输入流 | 字节输入流(InputStream) | 字符输入流(Reader) |
输出流 | 字节输出流(OutputStream) | 字符输出流(Writer) |
(A)字节流
文件字节输入输出流 FileInputStream()/FileOutputStream()
对象输入输出流ObjectInputStream/ObjectOutputStream
字节数组输入输出流ByteArrayInputStream()/ByteArrayOutputStream()
随机流RandomAccessFile()
1.1文件字节输入流 FileInputStream()![](https://i-blog.csdnimg.cn/blog_migrate/a4064e902a813231320c1671b486479c.png)
//方法一:一个字节一个字节读取数据
int n = -1;
while ((n = fis.read()) != -1) {
System.out.print((char) n);
}
//方法二:一次读取10个字节 减少对硬盘的读取次数 提高效率
//fis.read(b) 一次读取b.length个字节 放在b这个字节数组中 返回的是实际读到的字节个数
//每次都实行覆盖操作 到最后没覆盖完 就会重复到上面的数据 若每次循环new byte()浪费空间
//就在转化时 num(实际读到的个数)作为字符串长度 new String(byte[],offset,length)
//将字节数组转为字符串new String(byte[]) / new String(byte[],offset,length)
//读取字节数组时 一定要把数组填进去fis.read(b)
byte[] b = new byte[10];
int num=-1;
while((num=fis.read(b))!=-1) {
System.out.println(num);
// String s = new String(b);
// b=new byte[10]; 清空数组
String s = new String(b,0,num);
System.out.println(s);
tips:字节数组 转化为字符串
***关闭输入流:只要打开了外部资源(文件 数据库连接 网络连接)在使用完成后 需要关闭流对象 关闭资源
//方法一:
try{}catch{}finally {
//若上面代码报错 执行关闭语句 会抛异常 空指针异常 因为fis还没有new出来 不能调用空对象的方法
if(fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//方法二:不用写关闭 新的语法结构try-with-resource 自动关闭外部资源 不需要写finally中的关闭
try(
// 打开的资源对象相关代码 new对象即打开io流对象连接
FileInputStream fis = new FileInputStream("a.txt");
){
int n = -1;
while ((n = fis.read()) != -1) {
System.out.print((char) n);
}
}catch(IOException e) {
e.printStackTrace();
}
1.2文件字节输出流FileOutputStream()
try(
// 如果文件不存在会自动创建 默认false(覆盖原先) true(追加)
FileOutputStream fos = new FileOutputStream("b.txt");
) {
// String转化为bytes[] write()中参数只能bytes[]/int 必须要转化
byte[] bytes = "absdfhjskkedaa".getBytes();
fos.write(bytes);//先将数据写入内存缓冲区 当关闭时写入文件
fos.flush();//刷新输出流 完成数据的输出 当关闭时将数据写入文件 只要是写就要刷新
} catch (IOException e) {
e.printStackTrace();
}
2.对象输入输出流ObjectInputStream/ObjectOutputStream
属于包装流,依赖于另外的流对象(节点),关闭时,只需要关闭包装流。
序列化和反序列
* 序列化:将 java对象写入IO流,以流的形式将对象保存到磁盘 --- 文件看不懂 ObjectOutputStram对象输出流:序列化 --- 对象写入文件中
* 反序列化:从IO流读取文件,实现从磁盘将对象恢复到程序中
* java中的对象进行序列化操作时,该对象要去实现一个接口 Serializable
public class User implements Serializable{略}//对象进行序列化操作时,该对象要去实现一个接口
User user1 = new User("zhang",12,"女");
User user2 = new User("su",12,"女");
ArrayList list = new ArrayList();
list.add(user1);
list.add(user2);
try(
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.data"));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.data"));
){
// 方法一:一个个对象写进去
/* oos.writeObject(user1);
oos.writeObject(user2);
oos.flush();
*/
// 方法二:写入一个集合
oos.writeObject(list);
oos.flush();
// 读取和写入的顺序一致
// 方法一:一个个对象读
/* User u1=(User)ois.readObject();
User u2=(User)ois.readObject();
System.out.println(u1.getName()+u1.getId());
System.out.println(u2.getName()+u2.getId());
*/
// 方法二:读出一个集合 类型转化强转
ArrayList<User> list=(ArrayList<User>)ois.readObject();
System.out.println(list);
} catch (IOException e) {
e.printStackTrace();
}
3.字节数组输入输出流ByteArrayInputStream()/ByteArrayOutputStream()
// 在一个数组中 去读取数据
// 字节数组输入输出流 输入内存读写流 不需要关闭
private static void test01() {
byte[] bytes = "welcome to NJ".getBytes();//字节数组
ByteArrayInputStream bas = new ByteArrayInputStream(bytes);
int n=-1;
try {
while((n=bas.read())!=-1) {
System.out.print((char)n);
}
}catch(Exception e){
e.printStackTrace();
}
}
private static void test02() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
bos.write("contribute".getBytes());
bos.flush();//写入了内存中内置的一个字节数组中
// 获取内置的字节数组中的数据toByteArray()
byte[] byteArray = bos.toByteArray();
System.out.println(new String(byteArray));
} catch (IOException e) {
e.printStackTrace();
}
}
4.随机流RandomAccessFile()
随机读写流: 是一个字节流,可以对文件进行随机读写
* 随机: 可以定位到文件的任意位置进行读写操作,同过移动指针来实现
* 读写:使用该流可以对文件进行读写操作模式 r:文件不存在会报错 rw:会自动创建文件 模式 r:文件不存在会报错 rw:会自动创建文件
try(
RandomAccessFile raf=new RandomAccessFile("z.txt","rw");
){
// utf-8一个字符3个字节
raf.write("王五".getBytes());
raf.write("jjlinjjlin".getBytes());
System.out.println(raf.getFilePointer());//获取当前指针的位置 从0开始 写多少移多少
raf.seek(6);//指针移动到指定位置 后面写进来的东西从第6位以后开始覆盖 有几位盖几位
raf.write("老林".getBytes());
byte[] b=new byte[2];
raf.read(b);//原本一个个读取 现在一个字节数组按2个一组读取
System.out.println(new String(b));//读取到的2个转化为字符串输出
System.out.println(raf.getFilePointer());
raf.skipBytes(3);//将指针跳过指定的字节数
System.out.println(raf.getFilePointer());
}catch(Exception e) {
e.printStackTrace();
}
(B)字符流
0.简介
1.Reader字符输入流的父类,常用子类
* FileReader
* BufferedReader
* inputStreamReader
2.Writer字符输出流的父类,常用子类
* FilerWriter
* BufferdWriter
* OutputStreamWriter
1.文件字符输入输出流 FileReader/FileWriter
try(
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("c.txt");)
{
String s="张家人";
char[] ch=new char[10];
int n=-1;
while((n=fr.read(ch))!=-1) {
fw.write(s);//要看方法里面可以塞那些类型参数
fw.write(ch,0,n);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
2.缓冲输入输出流 BufferedReader/BufferedWriter
属于包装流,在读写时,会先操作缓冲区,减少对磁盘的IO操作,提高效率
try(
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
PrintStream ps=new PrintStream("b.txt");
) {
String s=null;
while((s=br.readLine())!=null) {
// 方法一:写进去时不会有换行 需要手动添加
// bw.write(s);
// bw.newLine();
// 或者 bw.write("\r\n");
// 方法二:System.out.println();其中out是PrintStream打印流类型 有直接换行的方法
ps.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
3.转换流InputStreamReader/OutputStreamWriter
转换流
* 用于将字节流转为字符流,可以实现编码的转换
* 在转换的时候指定使用的编码
* 在java中没有提供字符流转字节流的方法,不支持
try(
FileInputStream fis = new FileInputStream("a.txt");
InputStreamReader isr=new InputStreamReader(fis,"gbk");
BufferedReader br=new BufferedReader(isr);
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"gbk"));
) {
String s = br.readLine();
bw.write(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
//文件以gbk编码保存 但在运行时按照utf-8编码 编码不同 会出现乱码
附加练习(复制文件)
初级
// 读一个字节 写一个字节
private static void test01() {
try(
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos =new FileOutputStream("c.txt")
) {
int n=-1;
while((n=fis.read())!=-1) {
fos.write(n);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 每次读多个字节 写入时保证不产生覆盖的情况(b,0,n)
private static void test02() {
try(
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos =new FileOutputStream("c.txt")
) {
byte[] b=new byte[1024];
int n=-1;
while((n=fis.read(b))!=-1) {
fos.write(b,0,n);
}
} catch (IOException e) {
e.printStackTrace();
}
}
进阶
public static void main(String[] args) {
copyFile("D:\\code","C:\\");
}
private static void copyFile(String oldstr, String newstr) {
File oldfile = new File(oldstr);
File newfile = new File(newstr);
if(oldfile.isDirectory()) {
newfile=new File(newstr+File.separator+oldfile.getName());
newfile.mkdirs();
File[] listFiles = oldfile.listFiles();
for (File file : listFiles) {
copyFile(file.getAbsolutePath(),newfile.getAbsolutePath());
}
}else if(oldfile.isFile()) {
try(
FileInputStream fis=new FileInputStream(oldfile);
FileOutputStream fos=new FileOutputStream(newfile+File.separator+oldfile.getName());
){
byte[] b=new byte[1024*1024];
int n=-1;
while((n=fis.read(b))!=-1) {
fos.write(b,0,n);
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
File.separator不同操作系统的斜杠不一样
这是一边看视频一边学习的笔记-借用了一些老师的笔记内容-如有侵权,通知删除!
新手小白学习之路~~~