一、File类
1.1 File
概念:表示操作系统磁盘上的文件或者是文件夹
路径:
- 相对路径 (相对于当前工程的根路径)
- 绝对路径 (在磁盘上的完整路径)
常见方法
方法名 | 描述 |
---|---|
createNewFile() | 创建一个新文件。 |
mkdir() | 创建一个新目录。如果父目录不存在,则无法创建 |
mkdirs() | 创建一个新目录。如果父目录不存在,则一起创建 |
delete() | 删除文件或空目录。 |
exists() | 判断File对象所对象所代表的对象是否存在。 |
length() | 获取文件(夹)的大小(字节) |
getAbsolutePath() | 获取文件的绝对路径。 |
getAbsoluteFile() | 获取文件(夹)的绝对路径:(返回File) |
getName() | 获取当前file对象的文件名或者是文件夹名 |
getParent() | 获取当前file对象的父目录(返回String) |
isDirectory() | 是否是目录。 |
isFile() | 是否是文件。 |
getPath() | 获取文件(夹)的相对路径:(返回String) |
listFiles() | 列出目录中的所有内容。 |
//创建File对象
File file = new File("d:\\a.txt");
if(!file.exists()) {
//创建文件
file.createNewFile();
}
System.out.println("判断文件或者是文件夹是否存在"+file.exists());
System.out.println("判断是否是文件:"+file.isFile());
System.out.println("判断是否是文件夹:"+file.isDirectory());
System.out.println("获取文件或者文件夹的名字:"+file.getName());
System.out.println("获取文件大小(字节):"+file.length());
System.out.println("获取文件的相对路径:"+file.getPath());
System.out.println("获取文件的绝对路径(String):"+file.getAbsolutePath());
System.out.println("获取文件的绝对路径(File):"+file.getAbsoluteFile());
System.out.println("获取文件的父目录(String):"+file.getParent());
System.out.println("获取文件的父目录(File):"+file.getParentFile());
System.out.println("获取文件所在位置磁盘的总空间:"+file.getTotalSpace());
System.out.println("获取文件所在位置磁盘的可用空间:"+file.getFreeSpace());
System.out.println("获取文件的最后修改时间(毫秒)"+file.lastModified());
System.out.println("判断文件是否可读"+file.canRead());
System.out.println("判断文件是否可写"+file.canWrite());
System.out.println("判断文件是否可执行"+file.canExecute());
System.out.println("判断文件是否是隐藏文件"+file.isHidden());
1.2 FileNameFilter接口
FileNameFilter:文件过滤器接口
- boolean accept(File pathname)。
- 当调用File类中的listFiles()方法时,支持传入FileNameFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中。
案例:使用文件过滤器获取所有java文件
File[] files = f.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
});
for (File file2 : files) {
System.out.println(file2.getName());
}
1.3 文件搜索案例
遍历出某文件夹中的所有的java文件
public class FileDemo02 {
public static void main(String[] args) {
getJavaFile(new File("d:\\zz"));
}
//思考:删除一个文件夹
//思考:获取文件夹下所有的java文件
public static void getJavaFile(File file) {
//遍历当前文件夹下所有的文件或者是文件
File[] files = file.listFiles();
//f有两种情况,文件或者是文件夹
for (File f : files) {
if(f.isFile()) {
if(f.getName().endsWith(".java")) {
System.out.println(f.getName());
}
}else {
//递归调用getJavaFile
getJavaFile(f);
}
}
}
}
二、IO流
2.1 概念
- 内存与存储设备之间传输数据的通道。
- 水借助管道传输;数据借助流传输。
2.2 流的分类
2.2.1 按方向
- 输入流:将<存储设备>中的内容读入到<内存>中。
- 输出流:将<内存>中的内容写入到<存储设备>中。
2.2.2 按单位
- 字节流:以字节为单位,可以读写所有数据 。
- 字符流:以字符为单位,只能读写文本数据 。
2.2.3 按功能
- 节点流:具有实际传输数据的读写功能。
- 过滤流:在节点流的基础之上增强功能。
三、字节流【重点】
3.1 字节抽象类
InputStream
:字节输入流
- public int read(){}。
- public int read(byte[] b){}。
- public int read(byte[] b,int off,int len){}。
OutputStream
:字节输出流
- public void write(int n){}。
- public void write(byte[] b){}。
- public void write(byte[] b,int off,int len){}。
3.2 文件字节流【重点】
FileOutputStream
:
out.write(int b)
;
- 一次写入一个字节,整数表示这个字节对应ASCII码值
out.write(byte b)
;
- 一次写入一个字节数组的内容
out.write(b, off, len)
;
- 参数2:从数组的指定位置开始
- 参数3:执行写出的字节个数
- 一次写入一个字节数组的内容
FileInputStream
:
fis.read()
;
- 一次读取一个字节,返回这个字节所对应的ASCII值,如果读到流的末尾返回-1
fis.read(byte[] b)
;
- 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
fis.read(byte[] b,int offset,int len)
;
- 参数2:读取到数组中指定起始位置
- 参数3: 指定读取的字节个数
- 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
文件字节输入流
FileInputStream
public class FileInputStreamDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try {
//一、创建流对象
fis = new FileInputStream("a.txt");
//二、通过流对象进行读或者写
/*
* 方法1:read()
* 一次读取一个字节,返回这个字节所对应的ASCII值,如果读到流的末尾返回-1
*/
// System.out.println(fis.read());
// System.out.println(fis.read());
// System.out.println(fis.read());
// System.out.println(fis.read());
/**
* 方法2:fis.read(b)
* 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返 回-1
*
*/
//自定义缓冲区
// byte[] buf = new byte[1024];
// int len = fis.read(buf);
// //将byte数组转换成String字符串
// String str = new String(buf,0,len);
// System.out.println(str);
//自定义缓冲区
// byte[] buf = new byte[1024];
// int len;
// while( (len = fis.read(buf)) != -1) {
// String str = new String(buf,0,len);
// System.out.println(str);
// }
/**
* 方法3:fis.read(buf,offset,len);
* 参数2:读取到数组中指定起始位置
* 参数3: 指定读取的字节个数
*
* 从流中一次读取自定义缓冲区大小的字节,并返回读取到的字节长度,如果读到流的末尾返回-1
*/
//自定义缓冲区
byte[] buf = new byte[1024];
fis.read(buf, 2, 3);
System.out.println(Arrays.toString(buf));
} catch (Exception e) {
e.printStackTrace();
}finally {
//三、关闭流对象
try {
if(fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件字节输入流FileOutputStream
public class FileOutputStreamDemo {
public static void main(String[] args) {
//一、创建流对象
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("b.txt"));
//二、通过流对象进行读或者写
/**
* fos.write(int b)
* 一次写入一个字节,整数表示这个字节对应ASCII码值
*/
//fos.write(97);
/**
* fos.write(byte[] b);
* 一次写入一个字节数组的内容
*/
//byte[] b = "你好".getBytes();
//fos.write(b);
/**
* fos.write(byte[] b,int offset,int len);
* 参数2:从数组的指定位置开始
* 参数3:执行写出的字节个数
*
* 一次写入一个字节数组的内容
*/
byte[] b = "你好吗?".getBytes();
//System.out.println(Arrays.toString(b));
//fos.write(b, 2, 6);
fos.write(b,0,b.length);
} catch (Exception e) {
e.printStackTrace();
}finally {
//三、关闭流对象
try {
if(fos != null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.3 IO流细节
- 1、在使用文件输出流的时候如果文件不存在会自动创建,但是要保证其父目录存在
- 2、在使用文件输出流的时候,如果想要向文件中追加内容,那么需要将构造参数append设置为true
- 3、在使用IO读写的时候,读写的操作应当写在try代码块中,关闭资源的代码写在finally代码块中
- 4、将IO流的创建写在try()中,这样IO流在使用完成之后无需关闭
3.4 字节缓冲流【重点】
缓冲流:BufferedOutputStream
/BufferedInputStream
- 提高IO效率,减少访问磁盘的次数。
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
public class BufferedSteamDemo {
public static void main(String[] args) throws Exception {
// //一、创建缓冲流流对象
// FileInputStream fis = new FileInputStream("c.txt");
// BufferedInputStream bis = new BufferedInputStream(fis);
//
// //二、通过流对象进行读写
// byte[] buf = new byte[1024];
// int len;
// while((len = bis.read(buf) ) != -1) {
// String str = new String(buf, 0, len);
// System.out.println(str);
// }
//
// //三、关闭流资源(后用先关闭)
// bis.close();
// fis.close();
//一、创建缓冲流流对象
FileOutputStream fos = new FileOutputStream("d.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//二、通过流对象进行读写
bos.write("hello,缓冲流".getBytes());
//刷新(将缓冲区的内容刷新到目的地(硬盘))
bos.flush();
//三、关闭流资源(后用先关闭)
//关闭流资源的时候,会自动刷新缓冲区内容。(只会刷新一次)
bos.close();
fos.close();
}
}
3.5综合案例(文件拷贝)
public class FileCopyDemo {
public static void main(String[] args) {
copy2();
}
public static void copy1() {
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("C:\\Users\\hawa\\Desktop\\Java2105班\\上课视频\\1阶段.zip");
fos = new FileOutputStream("d:\\1.zip");
//定义缓冲区(一次读取1024个字节)
byte[] buf = new byte[1024];
int len;
while((len = fis.read(buf)) != -1) {
fos.write(buf,0,len);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(fis!=null)
fis.close();
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
//字节流耗时:147035
System.out.println("字节流耗时:"+(end - start));
}
public static void copy2() {
long start = System.currentTimeMillis();
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream("C:\\Users\\hawa\\Desktop\\Java2105班\\上课视频\\1阶段.zip");
fos = new FileOutputStream("d:\\1.zip");
bis = new BufferedInputStream(fis,80*1024);
bos = new BufferedOutputStream(fos,80*1024);
byte[] buf = new byte[1024];
int len;
while((len = bis.read(buf)) !=-1) {
bos.write(buf, 0, len);
//刷新一次就相当于磁盘之间的一次IO操作,会降低效率
//bos.flush();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(fis!=null)
fis.close();
if(bis != null)
bis.close();
if(bos!=null)
bos.close();
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
//缓冲流耗时:106388
System.out.println("缓冲流耗时:"+(end - start));
}
}
3.6 对象流【重点】
对象流:ObjectOutputStream
/ObjectInputStream
- 增加了缓冲区功能。
- 增加了读写8种基本数据类型和字符串功能。
- 增加了读写对象的功能:
readObject()
从流中读取一个对象。writeObject(Object obj)
向流中写入一个对象
3.6.1 对象流读写基本操作
//============对象流读写基本类型+String类型============
//一、创建流对象
FileOutputStream fos = new FileOutputStream("e.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//二、通过对象流进行读写
oos.writeInt(97); //Integer
oos.writeDouble(100.25); //Double
oos.writeUTF("对象流"); //String
//三、关闭流资源
oos.close();
fos.close();
//一、创建流对象
FileInputStream fis = new FileInputStream("e.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//二、通过对象流进行读写 (读取的顺序和写入的顺序要一致)
System.out.println(ois.readInt());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
//三、关闭流资源
ois.close();
fis.close();
3.6.2 对象流读写对象
对象流写操作(序列化)
//============对象流读写对象============
//写入对象
FileOutputStream fos = new FileOutputStream("f.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
User user = new User("cxk", 30);
oos.writeObject(user);
oos.close();
fos.close();
对象流写操作(反序列化)
//读取对象
FileInputStream fis = new FileInputStream("f.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
User user1 = (User) ois.readObject();
System.out.println(user1);
ois.close();
fis.close();
实体类(必须要实现序列化接口)
class User implements Serializable{
String name;
int age;
//.....
}
3.6.3对象流读写合集
//============对象流读写List集合============
//写入对象
FileOutputStream fos = new FileOutputStream("f.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
User user1 = new User("cxk1", 31);
User user2 = new User("cxk2", 32);
User user3 = new User("cxk3", 33);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
oos.writeObject(userList);
oos.close();
fos.close();
//读取对象
FileInputStream fis = new FileInputStream("f.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
List<User> users = (List<User>) ois.readObject();
System.out.println(users);
List<User> users1 = (List<User>) ois.readObject();
ois.close();
fis.close();
3.6.4 对象流使用细节
序列化的细节:
- 1、对象流读到流的末尾,会抛出异常
EOFException
- 2、如果属性不想被序列化,那么可以使用transient关键字修饰
- 3、类实现了
Serializable
接口,会自动生成一序列化id(序列化和反序列的id要保证一致)
3.7 数据流
DataInputStream
和DataOutputStream
是过滤流,封装了对基本数据类型加String的读和写的操作
方法与对象流一致(省略)
四、字符流【重点】
4.1 字符抽象类
Reader
:字符输入流
- public int read(){}。
- public int read(char[] c){}。
- public int read(char[] b,int off,int len){}。
Writer
:字符输出流
- public void write(int n){}。
- public void write(String str){}。
- public void write(String str,int offset,int len){}。
- public void write(char[] c){}。
- public void write(char[] c,int offset,int len){}。
4.2 文件字符流【重点】
文件字符输入流
public class FileReaderAndWriterDemo2 {
public static void main(String[] args) throws Exception {
//一、创建字符流对象
FileReader fr = new FileReader("h.txt");
//二、通过流对象读写数据
/**
* fr.read()
* 一次读取一个字符,并返回这个字符在Unicode码表中的值,如果读到流的末尾返回-1
*/
//System.out.println(fr.read());
//System.out.println(fr.read());
/**
* fr.read(char[] ch)
* 一次读取一个字符数组,并返回读取到的字符的长度,如果读到流的末尾返回-1
*/
// char[] cbuf = new char[1024];
// int len;
// while((len = fr.read(cbuf)) != -1) {
// String str = new String(cbuf, 0, len);
// System.out.println(str);
// }
/**
* fr.read(char[] ch,int offset,int len)
* 参数2:指定存放在数组中的起始位置 参数3:指定存放字符的长度
* 一次读取一个字符数组,并返回读取到的字符的长度,如果读到流的末尾返回-1
*/
char[] cbuf = new char[1024];
fr.read(cbuf, 3, 10);
System.out.println(Arrays.toString(cbuf));
//三、关闭流资源
fr.close();
}
}
文件字符输出流Filewrite
public class FileReaderAndWriterDemo {
public static void main(String[] args) throws Exception {
//一、创建字符流对象
FileWriter fw = new FileWriter("h.txt");
//二、通过流对象读写数据
/**
* write(int b)
* 写入一个字符,整数表示这个字符在Unicode码表中的值
*/
//fw.write(97);
//fw.write(20320);
/**
* write(char[] ch)
* 写入一个字符数组
*/
//String str = "你真棒";
//fw.write(str.toCharArray());
/**
* write(String str)
* 写入一个字符串
*/
//fw.write("你好真棒!!!");
/**
* write(char[] ch,int offset,int len)
* 参数2:可以指定数组的起始位置 参数3:可以指定写入的字符长度
* 写入一个字符数组
*/
//String str = "你真棒";
//fw.write(str.toCharArray(), 1, 2);
/**
* write(String str)
* 参数2:可以指定字符串的起始位置 参数3:可以指定写入的字符长度
* 写入一个字符串
*/
fw.write("你好真棒!!!", 1, 2);
//三、关闭流资源
fw.close();
}
}
4.3 字符缓冲流
缓冲流:BufferedWriter
/BufferedReader
- 支持输入换行符
- 可一次写一行、读一行。
public class BufferedDemo {
public static void main(String[] args) throws Exception {
//1、创建字符串缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("d:\\a.txt"));
//2、通过字符缓冲流读取内容
//一次一行内容,读到文件末尾返回null
//System.out.println(br.readLine());
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
//3、关闭资源
br.close();
//1、创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\ddd.txt"));
bw.write("BufferedWriter。。。。。");
//写入一个换行
bw.newLine();
bw.write("第二行。。。。。");
//3、关闭资源
bw.close();
}
}
4.4 转换流
转换流:
InputStreamReader
/OutputStreamWriter
- 可将字节流转换为字符流。
- 可设置字符的编码方式。
将字节输入流转换成字符输入流,并设置编码
public class InputStreamReaderDemo {
public static void main(String[] args) throws Exception {
//1、创建字节流对象
FileInputStream fis = new FileInputStream("d:\\a.txt");
//2、将字节流装换成字符流
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
//3、将字符流包装成字符缓冲流
BufferedReader br = new BufferedReader(isr);
String line;
while( (line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
//OutputStreamWriter 将字节输出流转换成字符输出流
}
}
4.5 打印流
- 字节打印流
- 字符打印流
打印流中提供了一组可以直接写出基本类型和String的方法
注意:打印流中的print(Object obj)方法并不是写出对象,而是写出对象的toString方法的返回值
public class PrintDemo {
public static void main(String[] args) throws Exception {
//1、创建字节打印流
PrintStream ps = new PrintStream("D:\\aaaa.txt");
//printXXX方法
ps.print(10);
//换行
ps.println("dsadsa");
ps.print("哈哈print流");
//注意:写入的是对象字符串变现形式(toString方法的结果)
ps.print(new Student());
ps.close();
//2、创建字符打印流
PrintWriter pw = new PrintWriter("D:\\aaaa.txt");
pw.print("哈哈");
pw.println();
pw.print(1000);
pw.close();
}
}
五、字符编码
- 字符
- 各个国家的文化符号
- 字符集
- 将文化符号进行统一收集生成字符集合(字典)
- 字符编码
- 每一种字符集 对字符的编排
- 常见字符集 :
ASCII
、GBK
、Unicode
(万国码) - 常见的字符编码:
ASCII编码 GBK编码 UTF-8 UTF-16 UTF-32 ISO8859-1 Big5 GB2312 GB18030
ASCII编码
- 美国信息交换标准代码 最多只能表示256个字符
- 一个字符 = 一个字节
GBK编码
- 国标码 前身是
GB2312
- 如果是0~256 ASCII码中的字符 。 一个字符 = 一个字节
- 其他情况 一个字符 = 两个字节
- 国标码 前身是
UTF-8 编码
- 可变字符
- 如果是0~128 ASCII码中的字符 一个字符 = 一个字节
- 如果是128~2048 Unicode码表中的字符 一个字符 = 两个字节
- 如果是2048 ~65535 Unicode码表的字符 一个字符 = 三个字节
- 编码:
- 将程序的内容写入到目的地,就是编码过程
- 解码:
- 将目的地的内容读取到程序中,就是解码过程
- 为什么会出现乱码?
- 编码和解码的编码方式不一致