1.File类
1.1File类的理解
* File类的使用 java.io.file
* 1.File类的一个对象,代表一个文件或一个文件目录(文件夹)
* 2.File是声明在java.io包下
* 3.File类中的方法只能实现对文件或文件目录的创建、删除、重命名、修改时间的
* 并未涉及到写入或读取文件内容的操作。读取或写入文件内容要使用IO流来完成
1.2File类的实例化
1.2.1常用构造器
* File(String filePath)
* File(String parentPath,String childPath)
* File(File parentPath,String childPath)
//构造器1
//相对于当前module
File file = new File("hello.txt");
File file2 = new File("E:\\JAVAee项目\\IDEA\\Java_Base\\he.txt");
System.out.println(file);
System.out.println(file2);
//构造器2
File file3 = new File("E:\\JAVAee项目\\IDEA","Java_Base");
System.out.println(file3);
//构造器3
File file4 = new File(file3,"hi.txt");
System.out.println(file4);
1.2.2路径的分类
* 路径问题:
* 1.相对路径:相较于某个路径下,指明的路径
* 2.绝对路径:包含盘符在内的文件或文件目录的路径
说明:
IDEA:
如果大家开发使用JUit中的单元测试方法测试,相对路径为当前module
如果使用main()方法测试,相对路径为当前Project下
Eclipse中:
不管使用单元测试还是main()测试,相对路径都是当前的project下。
1.1.3路径分隔符
* 3.路径分隔符:win和dos中默认使用“\”,linux下默认使用“/”
* public static final String separator。根据操作系统动态选择
File file3 = new File("E:"+File.separator+"\\JAVAee项目\\IDEA\\Java_Base\\he.txt");
1.3File类的常用方法
File file1 = new File("file\\hello.txt");
File file2= new File("d:\\io\\hi.txt");
//1.获取绝对路径
System.out.println(file1.getAbsolutePath());
//2.获取路径
System.out.println(file1.getPath());
//3.获取名称
System.out.println(file1.getName());
//4.获取上层文件目录路径。若无返回null
System.out.println(file1.getParent());
//5.获取文件长度,字节数。不能获取目录的长度。
System.out.println(file1.length());
//6.获取文件最后一次修改的时间,毫秒值
System.out.println(file1.lastModified());
//7.如下两个方法适用于文件目录
File file3 = new File("E:\\DownLoad\\Google");
//获取文件名
String[] list = file3.list();
for (String s:list) {
System.out.println(s);
}
System.out.println();
//获取文件
File[] files = file3.listFiles();
for(File file : files){
System.out.println(file);
}
/**
* public boolean renameTo(File dest)
* 8.把文件重命名未指定的文件路径
* 要想保证是成功的:1.file1在硬盘中存在
* 2.file2在硬盘中不存在
* 执行成功后 file1路径改变未file2的路径 原文件删除
*
*/
File file1 = new File("file\\hello.txt");
File file2 = new File("D:\\io\\hi.txt");
boolean result = file1.renameTo(file2);
System.out.println(result);
File file1 = new File("file\\hello.txt");
file1 = new File("hello.txt");
//1.判断是否是文件目录
System.out.println(file1.isDirectory());
//2.判断是否是文件
System.out.println(file1.isFile());
//3.判断是否存在
System.out.println(file1.exists());
//4.判断是否可读
System.out.println(file1.canRead());
//5.判断是否可写
System.out.println(file1.canWrite());
//6.判断是否隐藏
System.out.println(file1.isHidden());
//1.文件的创建
File file = new File("file//hi.txt");
if(!file.exists()){
file.createNewFile();
System.out.println("创建成功!");
}
else{
file.delete();
System.out.println("文件已删除!");
}
//2.文件目录的创建
/**
* public boolean mkdir();
* 上层目录不存在 无法创建
* public boolean mkdirs();
* 上层目录不存在 一并创建
*/
File file1 = new File("d:\\io\\io1");
if(!file1.exists()){
if(file1.mkdir()){
System.out.println("创建成功1!");
}
}
File file2 = new File("d:\\io\\io3\\io4");
if(!file2.exists()){
if(file2.mkdirs()){
System.out.println("创建成功2!");
}
}
1.4文件练习
1.创建一个与file同目录下的另外一个文件,命名为:haha.txt
File file = new File("d:\\io\\io1\\hello.txt");
File file1 = new File(file.getParent(),"haha.txt");
if(!file1.exists()){
if(file1.createNewFile()){
System.out.println("创建成功!");
}
}
2.判断指定目录下是否有后缀名为.jpg的文件,如果有,就输出该文件名称
//1.得到该文件目录下的所有文件名集合
File file = new File("d:\\io\\io1");
String[] nameList = file.list();
//2.使用endWith()方法判断
for(String name : nameList){
if(name.endsWith(".jpg")){
System.out.println(name);
}
}
3.遍历指定文件目录所有文件名称 包括子文件目录中的文件
3.1计算指定目录所占空间的大小
3.2删除指定文件目录及其下的所有文件
@Test
public void test03(){
//遍历指定文件目录所有文件名称 包括子文件目录中的文件
//递归
File file1 = new File("d:\\io\\io1");
readDir(file1);
//计算指定目录所占空间的大小
System.out.println(length);
//删除指定文件目录及其下的所有文件
deleteDir(file1);
}
public void readDir(File file){
if(file.isFile()){
length += file.length();
return;
}
else{
File[] files = file.listFiles();
for(File file1:files){
if(file1.isFile()){
length+=file1.length();
}
else{
readDir(file1);
}
}
}
}
public void deleteDir(File file){
if(file.isFile()){//单个文件 直接删除
file.delete();
}
else{
File[] files = file.listFiles();
for(File file1:files){//删除该文件夹下的所有文件
if(file1.isFile()){
file1.delete();
}
else{
deleteDir(file1);
}
}
file.delete();//删除该文件夹
}
}
2.节点流
2.1节点流分类
2.2字符型节点流
2.2.1FileReader
/**
* 将file下的hello.txt文件内容读入并输出到控制台
* 1.read() :返回读入的一个字符,如果到达末尾返回-1
* 2.异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
* 3.读入的文件一定要存在,否则会报FileNotFoundException异常
*/
@Test
public void testFileReader(){
FileReader fr = null;
try {
//1.实例化File对象,指明要操作的文件
File file = new File("file\\hello.txt");
//2.提供具体的流 字符流
fr = new FileReader(file);
//3.读取数据
//read() :返回读入的一个字符,如果到达末尾返回-1
int data;
while ((data = fr.read()) != -1) {
System.out.print((char) data);
}
}
catch(IOException e){
System.out.println(e.getMessage());
}
//4.流的关闭操作
finally {
if(fr!=null){
try {
fr.close();
}
catch (IOException e){
System.out.println(e.getMessage());
}
}
}
}
/**
* 对read()操作升级:使用read的重载方法
*
* read(char [] data):返回每次读入data数组中的字符个数。
* 如果达到文件末尾返回-1
*/
@Test
public void testFileReader1() {
FileReader fr = null;
try {
//1.File类的实例化
File file = new File("file\\hello.txt");
//2.FileReader流的实例化
fr = new FileReader(file);
//3.读入的操作
char[] data = new char[5];
int len;
while ((len = fr.read(data)) != -1) {
String str = new String(data,0,len);
System.out.print(str);
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
//4.资源的关闭操作
if (fr != null) {
try {
fr.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2.2FileWriter
/**
* 从内存中写出数据到硬盘的文件里
* 说明:
* 1.输出操作,对应的file文件不存在时,会自动创建此文件
* 2.如果文件存在:
* 2.1FileWriter(file,false)/FileWriter(file)--覆盖内容
* 2.2FileWriter(file,true)--追加内容
*/
@Test
public void testFileWriter() throws IOException {
//1.提供File类,指明写出的文件
File file = new File("file\\hello1.txt");
//2.提供FileWriter的对象,用于数据的写出
//是否在原文件上追加内容 默认是false
FileWriter fw = new FileWriter(file,true);
//3.写出的操作
fw.write("I have a dream!\n");
fw.write("You need to have a dream!\n");
//4.资源的关闭
fw.close();
}
2.2.3综合实现文件拷贝
/**
* 指定路径下的文件复制
* @param srcPath
* @param descPath
*/
public void copyFile(String srcPath,String descPath){
FileReader fr = null;
FileWriter fw = null;
try {
//1.创建File类的对象,指明读入和写出的文件
File srcFile = new File(srcPath);
File destFile = new File(descPath);
//2.创建输入流和输出流的对象
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//3.数据的读入和写出操作
char[] data = new char[1024];
int len;
while ((len = fr.read(data)) != -1) {
fw.write(data, 0, len);
}
}
catch (IOException e){
e.printStackTrace();
}
//4.资源的关闭
finally {
if(fw != null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fr != null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2.4总结
1.步骤:
创建文件对象–>创建流–>对文件的操作–>资源的关闭
2.异常的处理:
为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理。
3.重要方法:
–read() :返回读入的一个字符,如果到达末尾返回-1
–read(char [] data):返回每次读入data数组中的字符个数。如果达到文件末尾返回-1。
–FileWriter(file,false)/FileWriter(file)–覆盖内容
–FileWriter(file,true)–追加内容
2.3字节型节点流
2.3.1实现对文本的读取
对于文本文件的读取,如果文本中内容全是英文字母和数字,不会出现乱码;如果文本中包含汉字,可能会出现乱码,因为内存中存储的是字符的ASCII码,而使用字节型的节点流是按照字节一个一个进行读取的,如果一次读取的字节数不能恰好涵盖整数个字符的话(一个字符可能占据多个字节,因为汉字的ASCII码较大,一个字节八位不能表示),这就会造成乱码。
@Test
public void testFileInputStream() throws IOException {
//1.造文件
File file = new File("file\\hello.txt");
//2.造流
FileInputStream fis = new FileInputStream(file);
//3.读数据
byte [] buffer = new byte[5];
int len;//记录读取字节的个数
while((len = fis.read(buffer)) != -1){
String str = new String(buffer,0,len);
System.out.print(str);
}
//4.资源的关闭
fis.close();
}
2.3.2实现对文件的复制
/**
* 指定路径下的文件复制
* @param srcPath
* @param descPath
*/
public void copyFile(String srcPath,String descPath){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
File srcFile = new File(srcPath);
File destFile = new File(descPath);
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//复制过程
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("复制成功!");
}
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();
}
}
}
}
2.3.3总结
–1.对于文本文件(.txt,.java,.c,.cpp等),使用字符流来处理
–2.对于非文本文件(.jpg,.mp3,.doc,.ppt,.mp4等),使用字节流来处理
–3.文本文件的复制,可以使用字节流
3.缓冲流
3.1简介
-
1.缓冲流:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter -
2.作用:提高流的读取和写入速度
-
3.提高读写速度原因:内部提供了读写缓冲区
3.2字符型缓冲流
@Test
public void testBufferedReaderAndWriter(){
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(new File("file\\hello.txt")));
bw = new BufferedWriter(new FileWriter(new File("file\\hello1.txt")));
//读写操作
// char[] cbuf = new char[1024];
// int len;
// while ((len = br.read(cbuf)) != -1) {
// bw.write(cbuf, 0, len);
// }
//方式2:使用String 一次读一行
String data;
while((data = br.readLine()) != null){
bw.write(data);//data中不包含换行符的
bw.newLine();//换行
// bw.write(data+"\n");
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
//关闭资源
if(br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.3字节型缓冲流
@Test
public void testBufferedStream(){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.造文件
File srcFile = new File("file\\1.mp4");
File destFile = new File("file\\2.mp4");
//2.造流
//2.1造节点流
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//2.2造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//3.复制
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
// bos.flush();//刷新缓冲区
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
//4.资源关闭
//要求:先关闭外层的缓冲流,再关闭内层的节点流
if(bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//说明:在关闭外层的时候,内层的自动帮我们关闭了
// fis.close();
// fos.close();
}
}
3.4练习
1.实现文件的加密
使用异或运算,解密时对加密的文件在进行一次异或即可
//图片加密
@Test
public void testPic(){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("file\\123.jpg");
fos = new FileOutputStream("file\\1234.jpg");
byte[] buffer = new byte[20];
int len;
while ((len = fis.read(buffer)) != -1) {
//对字符出租进行加密
for (int i = 0; i < len; i++) {
buffer[i] = (byte) (buffer[i] ^ 5);
}
fos.write(buffer, 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();
}
}
}
}
2.统计一个文本中每个字符出现的次数
@Test
public void testCount(){
BufferedReader br = null;
BufferedWriter bw = null;
try {
//1.造流 声明Map集合
br = new BufferedReader(new FileReader("file\\hello.txt"));
bw = new BufferedWriter(new FileWriter("file\\hello1.txt"));
Map<Character, Integer> characterCountMap = new HashMap<Character, Integer>();
//2.读文件并统计 写入统计结果中
char[] data = new char[20];
int len;
while ((len = br.read(data)) != -1) {
//遍历读取的字符数组 统计出现次数
for (int i = 0; i < len; i++) {
if (characterCountMap.containsKey(data[i])) {//已出现过 map中存储有出现次数 加一即可
characterCountMap.put(data[i],characterCountMap.get(data[i])+ 1);
} else {//首次出现的字符,map中创建该键值对 值为1
characterCountMap.put(data[i], 1);
}
}
}
//写入
for (Character c : characterCountMap.keySet()) {
if(c =='\n'){
bw.write("换行符" + ":" + characterCountMap.get(c));
}
else if(c == '\r'){
bw.write("回车符" + ":" + characterCountMap.get(c));
}
else if(c == '\t'){
bw.write("制表符"+ ":" + characterCountMap.get(c));
}
else if(c == ' '){
bw.write("空格" + ":" + characterCountMap.get(c));
}
else{
bw.write(c + ":" + characterCountMap.get(c));
}
bw.newLine();
}
}
catch (IOException e){
e.printStackTrace();
}
finally {
//3.关闭资源
if(br != null) {
try {
br.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if(br != null) {
try {
bw.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}