目录
9.1文件字节输入流类 : FileInputStream类
13.6 键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:"java","txt")作为key
13.8 递归实现输入任意目录,列出文件以及文件夹,效果看图
13.11 在程序中写一个"HelloJavaWorld你好世界"输出到操作系统文件Hello.txt文件中
13.12 拷贝一张图片,从一个目录到另外一个目录下(PS:是拷贝是不是移动)
13.13 统计一个文件calcCharNum.txt(见附件)中字母'A'和'a'出现的总次数
13.14 统计一个文件calcCharNum.txt(见附件)中各个字母出现次数:A(8),B(16),C(10)...,a(12),b(10),c(3)....,括号内代表字符出现次数
13.16 使用随机文件流类RandomAccessFile将一个文本文件倒置读出
13.17 编写一个Java应用程序,可以实现Dos中的type命令,并加上行号。即将文本文件在控制台上显示出来,并在每一行的前面加上行号
13.18 输入两个文件夹名称,将A文件夹内容全部拷贝到B文件夹,要求使用多线程来操作
13.19 查看D盘中所有的文件和文件夹名称,并且使用名称升序降序,文件夹在前和文件夹在后,文件大小排序等
1.文件IO
外存 内存 缓存
打开txt文件的步骤:
1.启动一个应用程序[记事本,word,excel],系统会给这个程序分配内存空间
2.在外存和内存之间建立一个管道
3.将外存中的数据通过管道输送到内存中
4.输送数据的管道叫做数据流对象
PS: 1.字节是可以操作的最小的有意义的单位
2.所有的数据都可以用字节表示
2.字节输入流
InputStream:所有字节输入流的抽象父类
FileInputStream 文件输入流
ByteArrayInputStream 字节数组输入流
ObjectInputStream 对象输入流
FilterInputStream 过滤输入流
BufferedInputStream 缓冲字节输入流
DataInputStream 基本数据类型输入流
FileInputStream 文件字节输入流
构造方法
FileInputStream(File f,String name)
FileInputStream(String parent,String name)
FileInputStream(String name)
常用方法:
int len = available() 获得流中的估计剩余字节数
int t = read(); 读取流中的字节,如果是-1,说明读取到文件末尾
返回值表示读取到的字节数,如果为-1,表示到流的末尾
skip(t); 丢弃到t个字节
int t =read(byte[]) 将流中的数据读入到字节数组中,直到填满整个数组
int t = read(byte[],off,len) 将流中的数据读入到字节数组中,从数组的第off个位置开始填充,读取len个
返回值表示读取到的真实的字节数,如果为-1,表示到流的末尾
InputStream 类是字节输入流的抽象类,定义了操作输入流的各种方法,这些方法如表:
返回 | 方法 | 说明 |
---|---|---|
int | available() | 返回当前输入流的数据读取方法可以读取的有效字节数量 |
Abstract int | read() | 从当前数据流中读取一个字节。若已达到流结尾,则返回-1 |
int | read(byte[ ] bytes) | 从当前输入流读取一定的byte数据,并存取在数组中,然后返回读取的byte数据的数量,若已到达流结尾,则返回-1。 |
void | reset() | 将当前的输入流重新定位到最后一次调用mark()方法时的位置 |
void | mark(int readlimit) | 在当前输入流中做标记位置,当调用reset()方法时将返回到该位置,从标记位置开始,到再读入readlimit个字符为止,这个标记都维持有效。 |
Boolean | markSupported() | 测试当前输入流是否支持mark()和reset()方法,只要其中一个不支持,则返回false |
long | skip(long n) | 跳过和丢弃当前输入的n个字节数据 |
void | close() | 关闭当前输入流,并释放任何与之相关联的系统资源 |
InputStream 类是抽象类,不能通过new关键字来创建该实例对象,需要其子类创建该实例对象。下面通过实例如何使用InputStream从控制台获取用户输入的数据信息。
package com.zch.io;
import java.io.IOException;
import java.io.InputStream;
/**
* 创建InputStream实例inp,并将其赋值为System类的in属性,定义为控制台输入流,从inp输入流中获取字节信息,
* 用这些字节信息创建字符串,并将其在控制台上输出。
* @author zch
*
*/
public class InputMessage {
public static void main(String[] args) {
InputStream inp = System.in;
byte[] bytes = new byte[1024];
try {
while(inp.read() != -1){
//根据用户输入的信息创建字符串
String str = new String(bytes).trim();
}
inp.close(); //关闭流
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.字节输出流
OutputStream
FileOutputStream 文件输出流
ByteArrayOutputStream 字节数组输出流
ObjectOutputStream 对象输出流
FilterOutputStream 过滤输出流
BufferedOutputStream 缓冲字节输出流
DataOutputStream 基本数据类型输出流
FileOutputStream 文件字节输出流
构造方法
FileOutputStream(String path)
FileOutputStream(File f)
FileOutputStream(String path,boolean append)
FileOutputStream(File f,boolean append)
常用方法:
write(int) 将指定的字节写到输出流
write(byte[]) 将字节数组中的所有字节写到输出流
write(byte[],off,len) 将字节数组中的字节写到输出流,从下标off开始,写len个
flush() 刷新输出流,将流中的字节强制输出
案例:
1.读取文本文件中的数据
2.将内存中的数据写到文件中
3.完成一个文件复制
作业:
1.查询API文档,找出字符串类中 关于字节数组,字符数组,字符串三者的相互转换的操作
2.定义一个方法完成文件的复制
public void copy(String src,String dest){}
3.给定一个文件,将文件中的所有字节+1,重新写到硬盘中,变成一个新的文件【简单的文件加密】
OutputStream定义了输出流的各种方法,如下表:
返回 | 方法 | 说明 |
---|---|---|
void | write(byte[ ] b) | 将byte[ ] 数组中的数据写入当前输出流 |
void | write(byte[] b ,int off, int len) | 将byte[ ]数组下标off开始的len长度的数据写入当前输出流 |
Abstract void | write(int b) | 写入一个byte数据到当前输出流 |
void | flush() | 刷新当前输出流,并强制写入所有缓冲的字节数据 |
void | close() | 关闭当前输出流 |
和InputStream类一样,OutputStream 类是抽象类,不能通过new关键字来创建该实例对象,需要其子类创建该实例对象。
package com.zch.io;
import java.io.IOException;
import java.io.OutputStream;
/**
* 创建OutputStream实例out,并将其赋值为System.out标准输出流。通过write()方法向流写入数据。
* @author zch
*
*/
public class OutputData {
public static void main(String[] args) {
OutputStream output = System.out; //实例化OutputStream对象
byte[] bytes = "使用OutputStream输出流在控制台输出字符串\n".getBytes(); //创建bytes数组
try {
output.write(bytes);
bytes = "输出内容:\n".getBytes();
output.write(bytes); //向流中写入数据
bytes = "Java数据交互管道——IO流 \n".getBytes();
output.write(bytes);
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果如下:
使用OutputStream输出流在控制台输出字符串
输出内容:
Java数据交互管道——IO流
4.字符集编码
ISO8859系列 : 西欧字符集 用来表示半角字符,不能处理中文
A B c d 2 3
ab C D2 3
GBK/GB2312/GB18030 : 简体中文
BIG5 : 繁体中文
UTF-8 : 基于Unicode编码的字符集
ANSI
5.缓冲流的使用
只能对基本的数据流进行包装
BufferedInputStream bis = new BufferedInputStream(inputstream);
BufferedOutputStream bos = new BufferedOutpuStream(outputstream);
基本数据类型的数据流(可以直接操作基本数据类型)
DataInputStream
DataOutputStream
案例:有一个学生对象,将学生对象的数据保存到文件中
------------
作业:
1.查API文档,学习使用Object流
使用对象流来对学生对象进行写和读操作
2.使用ArrayList保存若干个学生对象,将数据保存到文件中,并可以正确的读取出来
6.对象的序列化和反序列化
序列化:对象本身是不能够在流中串行的,将对象转换成可串行的,有序的数据流
反序列化:将串行的有序的流数据转换成对象的形式
7.如何实现序列化和反序列化?
如果某一个类的对象需要序列化或反序列化,就需要让该类实现序列化Serializable接口
序列化接口不做任何操作,仅仅是给该类的对象添加一个可序列化标记
8.文件协议
txt
doc
bmp
rar
9.其他流
字节数组输入流
ByteArrayInputStream
字节数组输出流
ByteArrayOutputStream
字符输入流
Reader
InputStreamReader 字节输入流到字符输入流的转换流
FileReader 文件字符流
BufferedReader 缓冲字符流
字符输出流
Writer
OutputStreamWriter
FileWriter
BufferedWriter
1.使用字符流完成文本文件的复制
2.如果不是文本文件,能否用字符流来复制???
3.完成文件夹的复制[字节流]
4.解压jdk中的src.zip [用字符流]
统计src中有多少个java文件
统计一共有多少行Java代码
统计src文件夹的总大小
5.[扩展]解析BMP格式的图片
9.1文件字节输入流类 : FileInputStream类
文件字节输入流可以从指定路径的文件中读取字节数据。文件字节输入流类继承InputStream类,并实现了读取输入流的各种方法。
创建文件字节输入流创建的构造方法语法如下:
- 语法1:以File对象为参数创建FileInputStream实例
new FileInputStream(File file)
- 1
- 语法2:以文件对象的绝对路径为参数创建FIleInputStream实例
new FileInputStream(String filepath)
9.2文件字节输出流类:FileOutputStream
文件字节输出流关联指定文件路径的文件,数据通过文件字节输出流以字节为单位输出并保存到文件中。文件字节输出流继承自OutputStream类,并实现OutputStream类的各种方法。
文件字节输出流的构造方法语法如下:
- 语法1:以File对象为参数创建FileOutputStream实例
new FileOutputStream(File file)
- 1
- 语法2:以文件对象的绝对路径为参数创建FIleOutputStream实例
new FileOutputStream(String filepath)
下面通过实例介绍文件的写入和读取
package com.zch.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 创建OutputStream实例out,并将其赋值为System.out标准输出流,通过write方法向流中写入数据
*
* @author zch
*
*/
public class FileCreate {
public static void main(String[] args) {
File file = new File("D:/", "word.txt"); //创建文件对象
try {
if (!file.exists()) { //如果文件不存在则新建文件
file.createNewFile();
}
FileOutputStream output = new FileOutputStream(file);
byte[] bytes = "Java数据交流管道——IO流".getBytes();
output.write(bytes); //将数组的信息写入文件中
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
FileInputStream input = new FileInputStream(file);
byte[] bytes2 = new byte[1024];
int len = input.read(bytes2);
System.out.println("文件中的信息是:" + new String(bytes2, 0, len));
input.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
9.3使用字符输入输出流
字符输入输出流 与 字节输入输出流有相同的功能,但传送数据的方式不一样,字节流以字节为单位传送数据,可以使任何类型的数据,例如文本、音频、视频、图片等。字符流以字符为单位传送数据,只能传送文本类型的数据。使用字符输入输出流的好处是,当读取中文时不会出现乱码问题,而使用字节输入输出流时,却不能保证这一点。
1、字符输入流抽象类:Reader类
该类定义了操作字符输入流的方法,如下表:
返回 | 方法 | 说明 |
---|---|---|
boolean | ready() | 判断此数据流是否准备好 |
int | read() | 读入一个字符,若已读到流结尾,则返回值为-1 |
int | read(char[ ]) | 读取一些字符到char[ ]数组内,并返回所读入的字符的数量,若已到达流结尾,则返回-1 |
Abscract int | read(char[ ] chars,int off,int len) | 读取一些字符到char[ ]数组下标从off开始到off+len的位置,并返回所读入的字符的数量,若已到达流结尾,则返回-1; |
void | reset() | 将当前输入流重新定位到最后一次mark()方法时的位置 |
void | mark(int readLimit) | 将当前输入流中做标记,当调用reset方法时将返回到该位置,从标记位置开始,到再读入readLimit个字符为止,这个标记都维持有效 |
boolean | markSupported | 测试当前输入流是否支持mark()方法和reset()方法。只要有一个方法不支持,则返回-1 |
long | skip(long n) | 跳过参数n指定的字符数量,并返回所跳过字符的数量 |
Abstract void | close() | 关闭字符输入流,并释放与之关联的所有资源 |
2、字符输出流类Writer类
Writer 类主要是用于解决字符输入流的类,其地位与Reader类在输入流的地位和作用是相同的,也是所有字符输出流的流类。
Writer类的主要方法如下:
返回 | 方法 | 说明 |
void | write(char[ ] cbuf) | 将字符数组的数据写入字符输出流 |
Abstract void | write(char[ ] cbuf int off ,int len) | 将字符数组从下标off 开始向输入流写入长度为len的数据 |
void | write(int c ) | 向字符输入流中写入一个字符数据 |
void | write(String str ) | 向输入流中写入一个字符串数据 |
void | write(String str , int off ,int len) | 向输入流中写入一个字符串从off 开始长度为len的数据 |
Abstract void | flush() | 刷新当前输出流,并强制写入所有缓冲区的字节数据 |
void | close() | 向输出流中写入缓冲区的数据,然后关闭当前输出流,释放所有与当前输出流相关联的系统资源 |
3、文件字符输入流FileReader
文件字符输入流与文件字节输入流的功能相似,但是传送数据的方式不一样,字节流以字节为单位传送数据,可以使文本、视频、音频、图片等。字符流以字符为单位传送数据,只能传送文本类型的数据。
创建字符输入流常用的构造方法:
- 语法1:
new FileReader(File file);
- 语法2:
new FileReader(String path);
下面通过实例介绍FileReader类读取指定磁盘文件的内容。
package com.zch.io;
import java.io.File;
import java.io.FileReader;
public class FileInAndOut {
public static void main(String[] args) {
//定义指定磁盘的文件的File对象
File file = new File("D://word.txt");
if(! file.exists()){
System.out.println("对不起,不包含指定路径的文件");
}else{
//根据指定路径的File对象创建FileReader对象
try {
FileReader fr = new FileReader(file);
char[] data = new char[23]; //定义char数组
int length = 0;
while((length = fr.read(data))>0){ //循环读取文件中的数据
String str = new String(data,0,length); //根据读取文件的内容创建String 对象
System.out.println(str); //输出读取内容
}
fr.close(); //关闭流
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行结果如下图:
4、文件字符输出流FileWriter
文件字符输出流继承自Writer类,提供了向文件输出的各种方法,数据通过文件字符输出流以字符为单位输出并保存到文件中。
package com.zch.io;
/**
* 通过给定的String类型参数的指定文件名称与路径,创建FileWriter类。
*
* @author zch
*/
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) {
File file = new File("D://word2.txt"); //创建指定文件
try {
if(! file.exists()){
file.createNewFile(); //如果指定文件不存在,新建文件
}
FileReader fr = new FileReader("D://word.txt");
FileWriter fw = new FileWriter(file); //创建FileWriter对象
int length = 0;
while((length = fr.read()) != -1){ //如果没有读到文件末尾
fw.write(length); //向文件写入数据
}
fr.close(); //关闭流
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行后创建了Word2.txt 文件,并向其中写入数据
10.NIO
FileChannel
ByteBuffer
//创建文件字节流
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest, true);
//获得输入和输出管道
FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel();
outChannel.transferFrom(inChannel, 0, f.length());
inChannel.transferTo(0, f.length(), outChannel);
ByteBuffer buffer = ByteBuffer.wrap("中南大".getBytes());
outChannel.write(buffer);
11.文件路径
绝对路径:从根磁盘开始计算的路径
windows: D:\\aa\\bb\\cc\\dd.txt
Linux: /aa/bb/cc/dd.txt
http://www.qq.com/aa/bb/cc.css
相对路径:
A: D:\\aa\\a.txt
B: D:\\aa\\bb\\cc\\c.txt
A相对于B的路径: ..\\..\\a.txt
B相对于A的路径: bb\\cc\\c.txt
11.1 如何获取文件信息
File 类是对文件和文件夹的抽象,包含了对文件和文件夹的多种属性和操作方法。File类的常用方法如下表
返回 | 方法 | 说明 |
---|---|---|
String | getName | 获取文件名称 |
String | getParent | 获取文件的父路径字符串 |
String | getPath | 获取文件的相对路径字符串 |
String | getAbsolutePath | 获取文件的绝对路径字符串 |
boolean | exists | 判断文件或者文件夹是否存在 |
boolean | isFile | 判断是不是文件类型 |
boolean | isDirectory | 判断是不是文件夹类型 |
boolean | delete | 删除文件或文件夹,如果删除成功返回结果为true |
boolean | mkdir | 创建文件夹,创建成功返回true |
boolean | setReadOnly | 设置文件或文件夹的只读属性 |
long | length | 获取文件的长度 |
long | lastModified | 获取文件的最后修改时间 |
String[ ] | list | 获取文件夹中的文件和子文件夹的名称,并存放到字符串数组中 |
package com.zch.io;
import java.io.File;
import java.util.Date;
/**
* 在src根目录下创建FileInfo类,在该类的主方法中创建文件对象,通过File类的相关方法,获取文件的相关信息
*
* @author zch
*
*/
public class FileInfo {
public static void main(String[] args) {
String filePath = "src/com/zch/io/FileInfo.java";
// 根据指定路径创建文件对象
File file = new File(filePath);
System.out.println("文件名称:" + file.getName());
System.out.println("文件是否存在:" + file.exists());
System.out.println("文件的相对路径:" + file.getPath());
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("是否为可执行文件:" + file.canExecute());
System.out.println("文件可以读取:" + file.canRead());
System.out.println("文件可以写入:" + file.canWrite());
System.out.println("文件上级路径:" + file.getParent());
System.out.println("文件大小:" + file.length() + "B");
System.out.println("文件最后修改时间:" + new Date(file.lastModified()));
System.out.println("是否文件类型:" + file.isFile());
System.out.println("是否为文件夹:" + file.isDirectory());
}
}
运行结果如下:
文件名称:FileInfo.java
文件是否存在:true
文件的相对路径:src\com\zch\io\FileInfo.java
文件的绝对路径:D:\Java\IO\src\com\zch\io\FileInfo.java
是否为可执行文件:true
文件可以读取:true
文件可以写入:true
文件上级路径:src\com\zch\io
文件大小:1195B
文件最后修改时间:Sat Sep 09 21:30:10 CST 2017
是否文件类型:true
是否为文件夹:false
在使用delete()方法删除File对象时,如果删除的对象是目录,该目录中的内容必须为空
12.扩展:
1.字节流和字符流的区别,以及各自的使用场景
2.InputStream中 read()方法的返回值表示什么意思?
read(byte[] s)方法的参数表示什么意思?返回值表示什么意思?
read(byte[] s,int t,ine len) 三个参数的意思?返回值是什么意思?
3.outputStream中 write(int t)方法的参数表示什么意思? write(byte[] s)方法的参数表示什么意思? write(byte[] s,int t,ine len) 三个 参数的意思?
4.写出常用的字节流和字符流有哪些?各自的继承体系?
5.使用文件管道FileChannel的好处有哪些?
6.使用FileInputStream/FileOutPUtStream实现文件复制
使用FileInputStream/FileOutPUtStream+自定义缓冲区实现文件复制
使用缓冲字节流实现文件复制
使用缓冲字节流+自定义缓冲区实现文件复制
7.使用字符流用第6题的方式复制文件
8.文件夹的复制一定要会写
9.统计文件夹中的各种数据
文件个数,文件夹个数 文件大小 总行数 标志性的数据[XXX的行数,jpg文件个数]
13.IO流实战
13.1 Java IO流实现复制文件夹
通过IO不仅可以复制文件,还可以复制文件夹,但是文件夹内,可能包含其他文件夹,因此需要对他们进行分别复制。
package com.zch.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyFile {
public static void main(String[] args) {
File sourceFile = null;
File desFile = null;
String sourceFolder = "D://简历2";
String copyFolder = "D://copy";
sourceFile = new File(sourceFolder);
if (!sourceFile.isDirectory() || !sourceFile.exists()) {
System.out.println("源文件夹不存在!");
} else {
desFile = new File(copyFolder);
desFile.mkdir();
copy(sourceFile.listFiles(), desFile);
System.out.println("文件夹复制成功!");
}
}
/**
* 创建copy方法,该方法接收文件数组和目标文件夹两个参数,如果目标文件夹不存在,则调用mkdir()方法创建文件夹,然后再循环中将文件数组
* 中的每个文件对象写到目标文件夹内。
* @param fl
* @param file
*/
public static void copy(File[] fl, File file) {
if (!file.exists()) { // 如果文件夹不存在
file.mkdir(); // 建立新的文件夹
}
for (int i = 0; i < fl.length; i++) {
if (fl[i].isFile()) { // 如果是文件类型,则复制文件
try {
FileInputStream fis = new FileInputStream(fl[i]);
FileOutputStream out = new FileOutputStream(new File(
file.getPath() + File.separator + fl[i].getName()));
int count = fis.available();
byte[] data = new byte[count];
if ((fis.read(data)) != -1) {
out.write(data);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fl[i].isDirectory()) { // 如果是文件夹类型
File des = new File(file.getPath() + File.separator
+ fl[i].getName());
des.mkdir(); // 在目标文件夹中创建相同的文件夹
copy(fl[i].listFiles(), des); // 递归调用方法本身
}
}
}
}
运行本实例,会将D盘中的简历文件中的内容复制到D盘的copy文件夹中,而且包含文件夹的子文件夹
13.2 Java IO流实现分行向文件中写入数据
FileWriter类可以向文件写入字符数据,如果将FileWriter类封装到BufferWriter类的缓冲字符流中,能够实现缓冲字符输出流,并且可以通过读输出流的newLine()方法,来实现数据的分行写入。
package com.zch.io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* 创建BranchWriter类,在主方法中定义文件对象,将该对象作为参数创建BufferedWriter类实例,
* 调用该实例的writer方法将数据写入文件中,然后 调用newLine()方法写入换行符,实现分行向文件写入数据。
*
* @author zch
*
*/
public class BranchWriter {
public static void main(String[] args) {
String filePath = "D://BranchWriter.txt";
File file = new File(filePath);
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file); // 创建文件输出流
BufferedWriter bw = new BufferedWriter(fw); // 使用缓冲区数据流封装输出流
for (int i = 0; i < 100; i++) { //循环写入100行数据
bw.write("Java交互管道——IO流".toCharArray());// 写入数据到输出流
bw.newLine(); // 写入换行符
bw.flush(); // 刷新缓冲区
}
System.out.println("成功写入数据!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
13.3 删除指定文件
File类的delete()方法可以实现删除指定的文件,首先使用目标文件路径创建File类的实例对象,然后再调用File类的delete()方法。
package com.zch.io;
import java.io.File;
public class FileDelete {
public static void main(String[] args) {
String filePath = "D://word.txt";
File file = new File(filePath);
delFile(file);
}
public static void delFile(File file) {
if (!file.exists()) {
System.out.println("文件不存在!");
return;
}
boolean rs = file.delete();
if (rs) {
System.out.println("文件删除成功!");
} else {
System.out.println("文件删除失败!");
}
}
}
13.4 查看文件中各个字母出现的次数
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Set;
public class Test {
public static void main(String[] args) throws Exception {
//定义一个Map集合储存数据
//为什么用map集合?
// map集合不能储存重复元素,如果储存的键和之前的有重复,新存入的键和值会覆盖之前的 这正是我们需要的
HashMap<Character, Integer> map = new HashMap<>();
//创建一个File对象.参数使用我们想要查看的文件的路径
File f1 = new File("参数使用我们想要查看的文件的路径");
//定义一个字符缓冲输入流更快的读取数据//此处用字符输入流最适宜
BufferedReader br = new BufferedReader(new FileReader(f1));
//定义个字符串用来保存每次读取的数据
String len;
//一次读取一行字符//whlie循环当读取的一行数据为空,则停止循环
while ((len = br.readLine()) != null) {
//将每次读取的字符串拆分成字符数组
char[] chars = len.toCharArray();
//使用增强for变量数组
for (char aChar : chars) {
//判断数组中的字符是不是大写或者小写字母
if ((aChar >= 'a' && aChar <= 'z') || (aChar >= 'A' && aChar <= 'Z')) {
//是字符进入
//判读字符是不是第一次出现
if (!map.containsKey(aChar)) {
//是第一次出现,将字符当做键 出现的次数1为值 存入Map集合中
map.put(aChar, 1);
} else {
//不是第一次出现 通过get()方法得到当前字符出现的次数 (键对应的值)
Integer integer = map.get(aChar);
integer++;//本次该字符又出现了一次,将值+1,
map.put(aChar, integer);//将得到的新的值和 键保存到集合中
}
}
}
}//关闭资源
br.close();
//遍历集合
Set<Character> characters = map.keySet();
for (Character character : characters) {
System.out.println(character + "=" + map.get(character));
}
}
}
13.5 io流使用案例---复制图片
这里我们用io流实现将输入流指定路径下的图片复制到输出流指定路径
package com.test9;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class photoCopy {
public static void main(String [] args){
//定义输入输出流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//为输入输出流指定路径
fis = new FileInputStream("C:\\Users\\zhangbin\\Pictures\\Camera Roll" +
"\\1c950a7b02087bf41df462a9fed3572c11dfcf51.jpg");
fos = new FileOutputStream("D:\\a.jpg");
//实际读入字节数
int n = 0;
//相当于缓存
byte []bytes = new byte[1024];
//循环写入
while ((n=fis.read(bytes))!=-1){
fos.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
//关闭输入输出流
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
13.6 键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:"java","txt")作为key
键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:“java”,“txt”)作为key,
用个数作为value,放入到map集合中,并用两种方式遍历map集合
例如:
- doc 的类型的文件有 3 个
- java 的类型的文件有 5 个
- txt 的类型的文件有 7 个
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class HomeWork2 {
public static void main(String[] args) {
System.out.print("请输入文件夹路径:");
// 测试路径:D:\360MoveData\Users\xucc\Desktop\aaa
File file = new File(new Scanner(System.in).next());
HashFile(file);
}
public static void HashFile(File file) {
File[] fileArr = file.listFiles();
List<String> list = new ArrayList<String>();//新建一个数组,用来存储所有文件的后缀名
for (File f : fileArr) {
if (!f.isDirectory()) {
int index = f.toString().indexOf(".");//获取文件名中“.”的下标
String fileName = f.toString().substring(index + 1);// 截取文件后缀名
list.add(fileName);
} else {
File[] file2 = f.listFiles();
for (File f2 : file2) {
int index = f2.toString().indexOf(".");
String fileName = f2.toString().substring(index + 1);// 截取文件后缀名
list.add(fileName);
}
}
}
HashMap<String, Integer> hm = new HashMap<>();
int value = 1;
for (String f : list) {
if (!hm.containsKey(f))
hm.put(f, 1);
else
hm.put(f, ++value);
}
for(String key : hm.keySet())
System.out.println(key +"的类型的文件有"+hm.get(key));
System.out.println("________________");
for (Map.Entry<String, Integer> me : hm.entrySet()) {
String key = me.getKey();
int numValue = me.getValue();
System.out.println(key + "的类型的文件有" + numValue);
}
}
}
输出结果:
13.7 在电脑D盘下创建一个文件为HelloWorld.txt文件,判断他是文件还是目录,在创建一个目录IOTest,之后将HelloWorld.txt移动到IOTest目录下去;之后遍历IOTest这个目录下的文
件
package com.xykj.lesson1;
import java.io.File;
import java.io.IOException;
public class Test1 {
/**
* 1. 在电脑D盘下创建一个文件为HelloWorld.txt文件,
* 判断他是文件还是目录,再创建一个目录IOTest,
* 之后将HelloWorld.txt移动到IOTest目录下去;
* 之后遍历IOTest这个目录下的文件
*
* 程序分析:
* 1、文件创建使用File的createNewFile()方法
* 2、判断是文件用isFile(),判断是目录用isDirectory
* 3、创建目录用:mkdirs()方法
* 4、移动文件用:renameTo
* 5、遍历目录用:list()方法获得存放文件的数组,foreach遍历的方法把文件打印出来
* */
public static void main(String[] args) {
//在电脑D盘下创建一个文件为HelloWorld.txt文件
File file=new File("D:","HelloWorld.txt");
//创建文件,返回一个布尔值
boolean isCreate;
try {
isCreate = file.createNewFile();
if (isCreate) {
System.out.println("创建文件成功!");
}else {
System.out.println("创建文件失败!文件已经存在");
}
} catch (IOException e) {
System.out.println("创建文件失败!");
}
// 判断他是文件还是目录,
if (file.isFile()) {
System.out.println("这是一个文件");
} else {
System.out.println("这是一个目录");
}
//再创建一个目录IOTest
File file2=new File("D:/IOTest");
file2.mkdirs();
//HelloWorld.txt移动到IOTest目录下去?失败?》
if (file.renameTo(file2)) {
System.out.println("文件移动成功!");
} else {
System.out.println("文件移动失败");
}
//遍历IOTest目录下的文件
String[] arr=file2.list();
for (String string : arr) {
System.out.println(string);
}
}
}
上面的file.renameTo(file2)改为:file.renameTo(file2.getPath + "/" + file.getName());就不会有错了。
13.8 递归实现输入任意目录,列出文件以及文件夹,效果看图
1.先建一个FileUtile工具类
package com.xykj.lesson2;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* 这是一个获取目录下所有文件夹内的所有文件的封装类
* 当然前提是你要传进来一个正确路径的文件夹
* */
public class FileUtils {
//获取文件夹下所有的文件
public static List<file> getAllFiles(String dir){
//创建一个集合存放遍历到的File
List< File >files=new ArrayList<file>();
File file=new File(dir);
//文件夹必须存在 并且要是文件夹
if (file.exists()&&file.isDirectory()) {
//重点! 这里要本身一直遍历
longErgodic(file,files);//把遍历得到的东西存放在files里面
}
return files;
}
//重点理解,这是一个递归方法,会不断来回调用本身,但是所有获得的数据都会存放在集合files里面
private static void longErgodic(File file, List<file> files) {
//.listFiles()方法的使用
//把文件夹的所有文件(包括文件和文件名)都放在一个文件类的数组里面
File[] fillArr=file.listFiles();
//如果是一个空的文件夹
if (fillArr==null) {
//后面的不执行,直接返回
return;
}
//如果文件夹有内容,遍历里面的所有文件(包括文件夹和文件),都添加到集合里面
for (File file2 : fillArr) {
//如果只是想要里面的文件或者文件夹或者某些固定格式的文件可以判断下再添加
files.add(file2);
//添加到集合后,在来判断是否是文件夹,再遍历里面的所有文件
//方法的递归
longErgodic(file2, files);
}
}
}
2.再建一个主方法调用类
package com.xykj.lesson2;
import java.io.File;
import java.util.List;
public class Test2 {
/**
* 递归实现输入任意目录,列出文件以及文件夹
*
* 设计:在FileUtils类里面实现了逻辑操作,在另一边调用就可以了
* */
public static void main(String[] args) {
//比如输入D盘
List<file>list=FileUtils.getAllFiles("D:");
//输出所有的文件和文件夹的名字
for (File file : list) {
System.out.println(file);
}
}
}
13.9 递归实现列出当前工程下所有.java文件
package com.xykj.lesson3;
import java.io.File;
import java.util.List;
import com.xykj.lesson2.FileUtils;
public class Test3 {
/**
* 递归实现列出当前工程下所有.java文件
* 还是要题目2的遍历文件的工具类来获取所有的文件,再过滤.java文件就可以了
* 当前目录的地址:输入.就可以获取
* */
public static void main(String[] args) {
//输入. 获取当前文件的 所有文件
List<file>list=FileUtils.getAllFiles(".");
//输出.java后缀的文件的名字
for (File file : list) {
if (file.toString().endsWith(".java")) {
System.out.println(file.getName());
}
}
}
}
13.10 从磁盘读取一个文件到内存中,再打印到控制台
package com.xykj.lesson4;
import java.io.File;
import java.io.FileInputStream;
public class Tset4 {
/**
* 从磁盘读取一个文件到内存中,再打印到控制台
*
* 程序设计:
* 1、读取文件用到FileinputSteam
* 2、把读取的内容不断加入到StringBuffer,
* 3、再把StringBuffer打印出来就可以
* */
public static void main(String[] args) {
// 读取D:\notePad\aa.txt里面的内容
File file = new File("D:\\notePad\\aa.txt");
try {
// 创建读取流即输入流
FileInputStream fis = new FileInputStream(file);
int len = 0;
byte[] buf = new byte[1024];
StringBuffer sb = new StringBuffer();
// 把读取的数据添加到StringBuffer里面
while ((len = fis.read(buf)) != -1) {
sb.append(new String(buf, 0, len));
}
// 把StringBuffer里面的内容打印出来
System.out.println(sb);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.11 在程序中写一个"HelloJavaWorld你好世界"输出到操作系统文件Hello.txt文件中
package com.xykj.lesson5;
import java.io.File;
import java.io.FileOutputStream;
public class Test5 {
/**
* 在程序中写一个"HelloJavaWorld你好世界"输出到操作系统文件Hello.txt文件中
*
* 程序分析:文件写入,要用到输出流FileOutputStream
* */
public static void main(String[] args) {
// 向文件D:/Hello.txt,写入内容
File file = new File("D:/Hello.txt");
try {
// 创建输出流
FileOutputStream fos = new FileOutputStream(file);
//把String类型的字符串转化为byte数组的数据保存在输出流中
fos.write("HelloJavaWorld你好世界".getBytes());
fos.flush();//刷新输出流
fos.close();//关闭输出流
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.12 拷贝一张图片,从一个目录到另外一个目录下(PS:是拷贝是不是移动)
package com.xykj.lesson6;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test6 {
/**
* 拷贝一张图片,从一个目录到另外一个目录下(PS:是拷贝是不是移动)
*
* 程序设计思路:
* 这题不能使用renameTo,
* 解题步骤:
* 1、在目的地址创建一个图片文件
* 2、读取源地址文件的字节流
* 3、把读取到的字节流写入到目的地址的文件里面
* 4、刷新输出流,并关闭就可以了
*
* @throws Exception
* */
public static void main(String[] args) {
// 本题示范把D盘下的mm.jpg复制到D盘java文件夹里面
// 源文件地址
File fileFrom = new File("D:/mm.jpg");
// 目的文件地址
File fileTo = new File("D:/java/mm.jpg");
// 1、创建目的文件地址
try {
if (!fileTo.createNewFile()) {
System.out.println("创建文件失败!");
}
// 2、读取源地址文件的字节流
FileInputStream fis = new FileInputStream(fileFrom);
FileOutputStream fos = new FileOutputStream(fileTo);
int len = 0;
byte[] buf = new byte[1024];
while ((len = fis.read(buf)) != -1) {
// 3、把读取到的字节流写入到目的地址的文件里面
fos.write(buf, 0, len);
}
// 刷新下输出流
fos.flush();
// 关闭输入流和输出流
fis.close();
fos.close();
System.out.println("文件复制成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.13 统计一个文件calcCharNum.txt(见附件)中字母'A'和'a'出现的总次数
package com.xykj.lesson7;
import java.io.File;
import java.io.FileInputStream;
public class Test7 {
/**
* 统计一个文件calcCharNum.txt(见附件)中字母'A'和'a'出现的总次数
*
* 程序分析:
* 读取文件用FileInputStream
* 一次只读一个字节(一个字母就是一个字节),当字节内容和A或a相等时,相应的数量加1
* */
public static void main(String[] args) {
try {
//添加文件路径
File file = new File("D:/java/calcCharNum.txt");
//创建文件读取流
FileInputStream fis = new FileInputStream(file);
int numA = 0;//字母A的数量
int numa = 0;//字母a的数量
int len = 0;//每次读取的字节数量
while ((len=fis.read())!= -1) {
//统计字母a的数量
if (new String((char)len+"").equals("a")) {
numa++;
}
//统计字母A的数量
if (new String((char)len+"").equals("A")) {
numA++;
}
}
//打印出文件内字母的数量
System.out.println("a的数量是:"+numa);
System.out.println("A的数量是:"+numA);
System.out.println("a和A出现的总次数:"+(numA+numa));
fis.close();//关闭输入流
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.14 统计一个文件calcCharNum.txt(见附件)中各个字母出现次数:A(8),B(16),C(10)...,a(12),b(10),c(3)....,括号内代表字符出现次数
package com.xykj.lesson8;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class Test8 {
/**
* 统计一个文件calcCharNum.txt(见附件)中各个字母出现次数:
* A(8),B(16),C(10)...,a(12),b(10),c(3)....,括号内代表字符出现次数;
*
* 程序分析:
* 1.这里没中文字符,依然可以只用字节流来读取文件
* 2.不能保存相同的主键值,可以使用HashMap:key-value来实现
* 3.先获得该key的value,如果存在key的话value的值加1
* */
public static void main(String[] args) {
// 文件路径
File file = new File("D:/java/calcCharNum.txt");
try {
// 创建读取文件的输入流
FileInputStream fis = new FileInputStream(file);
// 创建集合HashMap类存放要保存的key-value
HashMap<string, integer=""> map = new HashMap<>();
// 读取文件
int len = 0;// 每次读取的文件长度
int count = 0;
while ((len = fis.read()) != -1) {
// 每次获取到的字母
char c = (char) len;
//这里使用try catch是因为 map.get(c + ""),第一次get不到东西会出现空指针
try {
// 通过每次的key值获取它的value值,
// 但是在它的key值没有时或报空指针错误,所以要try catch处理
// 当她有key值,就可以获取到相应的value值
count = map.get(c + "");
} catch (Exception e) {// 什么都不用输出
}
// 如果有它的key值对应的value值要加1
map.put(c + "", count + 1);
}
fis.close();
// 读完后把结果打印出来
//迭代器的使用
Iterator<entry<string, integer="">> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<string, integer=""> entry = iterator.next();
System.out.print(entry.getKey() + "(" + entry.getValue()+ ") \t");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.15 统计一个文件calcCharNum2.txt(见附件)中各个字母出现次数:A(8),B(16),C(10)...,a(12),b(10),c(3)....中(5),国(6),括号内代表字符出现次数
package com.xykj.lesson9;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class Test9 {
/**
* 统计一个文件calcCharNum2.txt(见附件)中各个字母出现次数:
* A(8),B(16),C(10)...,a(12),b(10),c(3)....中(5),国(6),
* 括号内代表字符出现次数;
*
* 程序分析:
* 1.这出现中文字符,依然只能用字符流来读取文件
* 2.不能保存相同的主键值,可以使用HashMap:key-value来实现
* 3.先获得该key的value,如果存在key的话value的值加1
* */
public static void main(String[] args) {
// 文件路径
File file = new File("D:/java/calcCharNum2.txt");
// 创建集合HashMap类存放要保存的key-value
HashMap<string, integer=""> map = new HashMap<>();
try {
// 创建字符流
FileReader fr = new FileReader(file);
// 每次读取的字符长度
int len = 0;
int count=0;//出现该字符的次数
while ((len = fr.read()) != -1) {
// 获取对应的字符
char c = (char) len;
try {
// 通过每次的key值获取它的value值,
// 但是在它的key值没有时或报空指针错误,所以要try catch处理
// 当她有key值,就可以获取到相应的value值
count = map.get(c + "");
} catch (Exception e) {// 什么都不用输出
}
// 如果有它的key值对应的value值要加1
map.put(c + "", count + 1);
}
// 读完后把结果打印出来
Iterator<entry<string, integer="">> iterator = map.entrySet().iterator();
//迭代器的使用
while (iterator.hasNext()) {
Entry<string, integer=""> entry = iterator.next();
System.out.print(entry.getKey() + "(" + entry.getValue()+ ") \t");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.16 使用随机文件流类RandomAccessFile将一个文本文件倒置读出
package com.xykj.lesson10;
import java.io.File;
import java.io.RandomAccessFile;
public class Test10 {
/**
* 使用随机文件流类RandomAccessFile将一个文本文件倒置读出。
*
* 程序分析:
* RandomAccessFile的seek方法能把读取文件的光标移动到具体的位置
* 但是还是有地点值得注意的是一个字母或数字是占用一个字节的, 一个汉字是占用两个字节的
* */
public static void main(String[] args) {
// 要读取的文件的地址
File file = new File("D:/java/calcCharNum2.txt");
try {
RandomAccessFile raf = new RandomAccessFile(file, "r");
long length = raf.length();
StringBuffer sb = new StringBuffer();
while (length > 0) {
length--;
raf.seek(length);
int c = (char) raf.readByte();
// 如果asc码<=255,>=0,则判断是个英文字符,添加到字符串中.
if (c >= 0 && c <= 255) {
sb.append((char) c);
} else {
// 如果不在asc码范围内,则判断是个汉字字符
// 汉字字符是占2个字节的,所以length再退一个字节
length--;
raf.seek(length);
byte[] cc = new byte[2];
// cc被复制为文件中连续的两个字节
raf.readFully(cc);
sb.append(new String(cc));
}
}
System.out.println(sb);
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.17 编写一个Java应用程序,可以实现Dos中的type命令,并加上行号。即将文本文件在控制台上显示出来,并在每一行的前面加上行号
package com.xykj.lesson1;
import java.io.File;
import java.io.IOException;
public class Test1 {
/**
* 1. 在电脑D盘下创建一个文件为HelloWorld.txt文件,
* 判断他是文件还是目录,再创建一个目录IOTest,
* 之后将HelloWorld.txt移动到IOTest目录下去;
* 之后遍历IOTest这个目录下的文件
*
* 程序分析:
* 1、文件创建使用File的createNewFile()方法
* 2、判断是文件用isFile(),判断是目录用isDirectory
* 3、创建目录用:mkdirs()方法
* 4、移动文件用:renameTo
* 5、遍历目录用:list()方法获得存放文件的数组,foreach遍历的方法把文件打印出来
* */
public static void main(String[] args) {
//在电脑D盘下创建一个文件为HelloWorld.txt文件
File file=new File("D:","HelloWorld.txt");
//创建文件,返回一个布尔值
boolean isCreate;
try {
isCreate = file.createNewFile();
if (isCreate) {
System.out.println("创建文件成功!");
}else {
System.out.println("创建文件失败!文件已经存在");
}
} catch (IOException e) {
System.out.println("创建文件失败!");
}
// 判断他是文件还是目录,
if (file.isFile()) {
System.out.println("这是一个文件");
} else {
System.out.println("这是一个目录");
}
//再创建一个目录IOTest
File file2=new File("D:/IOTest");
file2.mkdirs();
//HelloWorld.txt移动到IOTest目录下去?失败?》
if (file.renameTo(file2)) {
System.out.println("文件移动成功!");
} else {
System.out.println("文件移动失败");
}
//遍历IOTest目录下的文件
String[] arr=file2.list();
for (String string : arr) {
System.out.println(string);
}
}
}
13.18 输入两个文件夹名称,将A文件夹内容全部拷贝到B文件夹,要求使用多线程来操作
package com.xykj.lesson12;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.xykj.lesson2.FileUtils;
public class Test12 {
/*
* 输入两个文件夹名称,将A文件夹内容全部拷贝到B文件夹,要求使用多线程来操作。
*
* 程序分析:
* 1.拷贝文件里面的东西,要分析的东西还是蛮多的,要先建文件夹再拷贝里面的东西,而且要一层层的来搞
* 2.这里也需要文件遍历工具,直接调用第二题的工具类,不再重写
* 3.多线程的使用,可以直接在方法里面直接新建线程
* 4.对整个文件夹进行复制 文件夹分隔符可以用\\或/,其他的都是不对的
* 所有其中还对输入的分割符进行了替换
* 这题看起来比较长,分开看其实也不长
* */
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("要复制的文件夹:");
String fromDir = scanner.next();// 接收输入
System.out.println("要复制到哪里去:");
String toDir = scanner.next();// 接收输入
// 把输入的地址转化为File类型
File fromFile = new File(fromDir);
File toFile = new File(toDir);
//新建线程
new Thread(){
//里面做实际操作
public void run() {
// 判断如果要复制的是文件,直接复制就可以了
if (fromFile.isFile()) {
System.out.println("复制单个文件");
copy(fromFile, toFile);
} else {
// 要复制文件夹
// 要防止一种无法进行的复制:比如说,要把复制的文件复制到自己的子文件夹里面
// 举个例子:把D:/java/jsp文件夹复制到D:/java/jsp/js文件夹里面,
// 这会导致子文件不断增加的同时,而父文件也要不断增加,的一个死循环
// 如果反过来,就没事,相当于只是简单的覆盖而已
// 具体实现就是看:目的地地址包含复制的文件夹地址,就不允许操作
if (toDir.replace("/", "\\").toLowerCase()
.startsWith(fromDir.replace("/", "\\").toLowerCase())) {
return;
}
// 复制文件(包括文件和文件夹)操作
// 先获取所有的文件(包括文件和文件夹)
List<file> list = FileUtils.getAllFiles(fromDir);
// 创建一个线程池,加快复制的速度
ExecutorService threadPool = Executors.newFixedThreadPool(20);
// 需要对每一个文件的路径进行处理
for (File file : list) {
// 复制文件名
String name = file.getAbsolutePath();
// 把原来的文件路径换成新的文件路径
String toName = name.replace(fromFile.getParent(), toDir + "/");
System.out.println(name + "变成了" + toName);
// 如果是文件夹,直接创建
if (file.isDirectory()) {
new File(toName).mkdirs();
} else {
// 如果是文件,在线程里面复制
threadPool.execute(new Runnable() {
@Override
public void run() {
File copyFile = new File(toName);
// 先要有父文件夹
copyFile.getParentFile().mkdirs();
// 开始复制文件
copy(file, copyFile);
}
});
}
}
}
scanner.close();
};
}.start();//开始线程
}
//复制文件的操作
public static void copy(File fromFile, File toFile) {
// 定义一个输入流
FileInputStream fis = null;
// 定义一个输出流
FileOutputStream fos = null;
try {
// 把复制地址的File,封装后赋值给输入流对象
fis = new FileInputStream(fromFile);
// 把目的地的File,封装后复制给输出流的对象
fos = new FileOutputStream(toFile);
// 创建一个容量,
byte[] buf = new byte[1024];
// 每次读取/写入的字节长度
int len = 0;
// 边读边写
while ((len = fis.read(buf)) != -1) {// 判断是否还能读到数据
// 把输入放到输出流里面
fos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭输入流和输出流
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
13.19 查看D盘中所有的文件和文件夹名称,并且使用名称升序降序,文件夹在前和文件夹在后,文件大小排序等
package com.xykj.lesson13;
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.xykj.lesson2.FileUtils;
public class Test13 {
/**
* 查看D盘中所有的文件和文件夹名称,并且使用名称升序降序,
* 文件夹在前和文件夹在后,文件大小排序等。
*
* 程序分析:
* 1.查找文件和文件夹,需要例题二里遍历文件的工具类(这里直接调用,不在重写)
* 2.排序需要用到list集合里面的Collections工具类类的sort方法
* 3.这里有三重排序:首先是要按是否是文件夹来排序,然后按名称来排序,最后按大小来排序
* 其实这里还是会有问题的,按照某一个排序还没事,但是三个都排序就不一定有效!
实际应用中也是只按一种排序就可以了的
* */
public static void main(String[] args) {
List<file> list =FileUtils.getAllFiles("D:");
//按文件夹先显示的顺序:
Collections.sort(list, new Comparator<file>() {
@Override
public int compare(File o1, File o2) {
return (o2.isDirectory()?1:-1)-(o1.isDirectory()?1:-1);
}
});
//按文件名称显示的顺序:
Collections.sort(list, new Comparator<file>() {
@Override
public int compare(File o1, File o2) {
return (o1.getName()).compareTo(o2.getName());
}
});
//按文件名称显示的顺序:
Collections.sort(list, new Comparator<file>() {
@Override
public int compare(File o1, File o2) {
return (int)(o1.length()-o2.length());
}
});
//遍历集合的文件
for (File file : list) {
//打印排序后的文件或文件夹
System.out.println(file.getName());
}
}
}