File类
- File类的使用
-
- File类的一个对象,代表一个文件或一个文件目录(俗称文件夹)
-
- File类声明在java.io包下
-
- File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,
-
并未涉及修改,写入或读取文件内容。如需要读取或写入,必须要IO流
-
- 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的终点
/*
* 1. 如何创建File类的实例
* File(String filePath)
* File(String parentPath, String childPath)
* File(File parentFile,String childPath)
*
* 2. 相对路径和绝对路径
*
* 3. 路径分隔符: \\, /
*
* */
@Test
public void test1(){
//构造器1:
File file1=new File("hello.txt"); //相对于当前module
// File file2=new File("D:\\workspace_idea1\\JavaSenior\\day08\\he.txt");
System.out.println(file1);
//构造器2:
// File file3=new File("D:\\workspace_idea1","JavaSenior");
}
File类常用方法
*如下的方法适用于文件目录
* public String[] list(): 获取指定目录下的所有文件或者文件目录的名称数组
* public File[] listFiles(): 获取指定目录下的所有文件或者文件目录的File数组
*
* public boolean renameTo(File dest): 把文件重命名为指定的文件路径
* 比如:file1.renameTo(file2)为例:
* 要想保住返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在
*
* public boolean isDirectory(): 判断是否是文件目录
* public boolean isFile(): 判断是否是文件
* public boolean exits(): 判断是否存在
* public boolean canRead(): 判断是否可读
* public boolean canWrite(): 判断是否可写
* public boolean isHidden(): 判断是否隐藏
*
* 创建文件目录
* public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
* public boolean mkdir(): 创建文件目录。如果此文件目录存在或者上层目录不存在,就不创建
* public boolean mkdirs(): 创建文件目录。如果上层文件目录不存在,一并创建
*
* 删除磁盘中的文件或文件目录
* public boolean delete(): 删除文件或文件夹
* 删除注意事项:
* Java中的删除不走回收站
File测试题
/**
* 判断指定目录下是否有后缀为.jpg的文件,如果有,就输出名称
* @create 2021-01-10 下午3:44
*/
public class FindJPGFileTest {
@Test
public void test1(){
File srcFile=new File("d\\code");
String[] fileNames=srcFile.list();
for (String name: fileNames){
if (name.endsWith(".jpg")){
System.out.println(name);
}
}
}
}
/**
* 遍历指定目录所有文件名称,包括子文件目录中的文件
* 拓展1: 并计算指定目录占用空间的大小
* 拓展2: 删除指定文件目录及其下的所有文件
*
* @create 2021-01-10 下午3:47
*/
public class ListFilesTest {
public static void main(String[] args) {
//递归: 文件目录
/* 打印出指定目录所有文件名称,包括子文件目录中的文件*/
//1. 创建目录对象
File dir=new File("/Users/Documents/JavaProject");
//2. 打印目录的子文件
printSubFile(dir);
}
private static void printSubFile(File dir) {
//打印目录的子文件
File[] subfiles=dir.listFiles();
for (File f:subfiles){
if (f.isDirectory()){
printSubFile(f);
}else {
System.out.println(f.getAbsolutePath());
}
}
}
//拓展1:求指定目录所在空间的大小
public long getDirectorySize(File file){
//file是文件,直接返回file.length()
//file是目录,吧它下一级的所有文件大小相加
long size=0;
if (file.isFile()){
size+=file.length();
}else {
File[] all=file.listFiles();
for (File f:all){
size+=getDirectorySize(f);
}
}
return size;
}
//拓展2:删除指定目录
public void deleteDirectory(File file){
//如果file是文件,直接delete()
//如果是目录,先把它下一级干掉,然后删除自己
if (file.isDirectory()){
File[] all=file.listFiles();
// 循环删除的是file的下一级
for (File f:all){
deleteDirectory(f);
}
}
//删除自己
file.delete();
}
}
IO 流
- 一、流的分类:
-
- 操作数据单位:字节流,字符流
-
- 数据的流向:输入流,输出流
-
- 流的角色:节点流,处理流
- 二、流的体系结构
- 抽象基类 节点流(或文件流) 缓冲流(处理流的一种)
- InputStream FileInputStream BufferedInputStream
- OutputStream FileOutputStream BufferedOutputStream
- Reader FileReader BufferedReader
- Writer FileWriter BufferedWriter
字节流
字符流
FileReader
/**
* @create 2021-01-10 下午5:10
*/
public class FileReaderWriterTest {
public static void main(String[] args) {
File file =new File("hello.txt"); //相较于当前工程
System.out.println(file.getAbsolutePath()); //cannot find
File file1=new File("day09/hello.txt");
System.out.println(file1.getAbsolutePath());
}
/*
* 将day09下的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("hello.txt"); //相较于当前Module
//2. 提供具体的流
fr = new FileReader(file);
//3. 数据的读入
//read(): 返回读入的一个字符,如果到达文件的末尾,返回-1
int data=fr.read();
while (data!=-1){
System.out.print((char)data);
data=fr.read();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 流的关闭
try {
if (fr!=null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//对read()操作升级,使用read()重载方法
@Test
public void testFileReader1() throws IOException {
FileReader fr= null;
try {
//1. File类的实例化
File file=new File("hello.txt");
//2. FileReader流的实例化
fr = new FileReader(file);
//3. 读入的操作
//read(char[] cbuf): 返回每次读入cbuf数组中的字符的个数。如果达到文件末尾,返回-1
char[] cbuf=new char[5];
int len;
while ((len=fr.read(cbuf))!=-1){
//错误的写法
// for (int i = 0; i < cbuf.length; i++) {
// System.out.println(cbuf[i]);
// }
//方式一
// for (int i = 0; i < len; i++) {
// System.out.println(cbuf[i]);
// }
//方式二
String str=new String(cbuf,0,len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr!=null){
//4. 资源的关闭
fr.close();
}
}
}
FileWriter
/*
* 从内存中写出数据到硬盘的文件里
* 说明:
* 1. 输出操作,对应File可以不存在,
* 2. 如果不存在,在输出过程中,会自动创建
* 如果存在:
* 如果使用的构造器是:FileWriter(file,false): 对原有文件覆盖
* FileWriter(file,false): 内容后添加
* */
@Test
public void testFileWriter() throws IOException {
//1. 提供File类的对象,指明写出到的文件
File file=new File("hello1.txt");
//2. 提供FileWriter的对象,用于数据的写出
FileWriter fw=new FileWriter(file);
//3. 写出的操作
fw.write("I have a dream! \n");
fw.write("you need to have a dream!\n");
//4. 流资源的关闭
fw.close();
}
// 文本文件复制
@Test
public void testFileReaderFileWriter() {
FileReader fr=null;
FileWriter fw=null;
try {
//1. 创建File类的对象,指明读入和写出的文件
File srcFile=new File("hello.txt");
File destFile=new File("hello2.txt");
//2. 创建输入流和输出流的对象
fr=new FileReader(srcFile);
fw=new FileWriter(destFile);
//3. 数据的读入和写出操作
char[] cbuf=new char[5];
int len;
while ((len=fr.read(cbuf))!=-1){
//每次写出len个字符
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 流资源的关闭
if (fw!=null){
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
字节流
** 1、对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
2、对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt),使用字节流处理**
/**
* 测试FileInputStream和FileOutputStream的使用
*
* 结论:
* 1、对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
* 2、对于非文本文件(.jpg,.mp3,.mp4,.avi,.doc,.ppt),使用字节流处理
*
*/
public class FileInputOutputStreamTest {
@Test
public void testFileInputStream() {
FileInputStream fis= null;
try {
//1. 造文件
File file=new File("hello.txt");
//2. 造流
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);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 关闭资源
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
实现对图片的复制
* */
@Test
public void testFileInputOutputStream(){
FileInputStream fis= null;
FileOutputStream fos= null;
try {
//
File srcFile=new File("01.jpg");
File destFile=new File("02.jpg");
//
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//复制的过程
byte[] buffer=new byte[5];
int len;
while ((len=fis.read(buffer))!=-1){
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();
}
}
}
}
//指定路径下文件的复制
public void copyFile(String srcPath,String destPath){
FileInputStream fis= null;
FileOutputStream fos= null;
try {
//
File srcFile=new File(srcPath);
File destFile=new File(destPath);
//
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
//复制的过程
byte[] buffer=new byte[5];
int len;
while ((len=fis.read(buffer))!=-1){
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();
}
}
}
}
}
练习
获取文本上每个字符出现的次数
public class WordCount {
@Test
public void testWordCount(){
BufferedReader br= null;
BufferedWriter bw= null;
try {
br = new BufferedReader(new FileReader("hello.txt"));
bw = new BufferedWriter(new FileWriter("hello1.txt"));
int c;
HashMap<Character,Integer>count=new HashMap<>();
while ((c=br.read())!=-1){
char ch=(char)c;
if (count.containsKey(ch)){
count.put(ch,count.get(ch)+1);
}else {
count.put(ch,1);
}
}
Set<Map.Entry<Character,Integer>> entrySet=count.entrySet();
for (Map.Entry<Character,Integer>entry:entrySet){
switch (entry.getKey()){
case ' ':
bw.write("whitespace="+entry.getValue());
break;
case '\t':
bw.write("tab="+entry.getValue());
break;
case '\r':
bw.write("enter="+entry.getValue());
break;
case '\n':
bw.write("line="+entry.getValue());
break;
default:
bw.write(entry.getKey()+"="+entry.getValue());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
缓冲流
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
- 作用:提供流的读取:写入的速度
-
提高读写速度的原因:内部提供了一个缓冲区
使用BufferedInputStream和BufferedOutputStream
public class BufferedTest {
/*
实现非文本文件的复制
* */
@Test
public void BufferedStreamTest(){
BufferedInputStream bis= null;
BufferedOutputStream bos= null;
try {
//1. 造文件
File srcFile=new File("2101608177836_.pic_hd.jpg");
File destFile=new File("2101608177836_2pic_hd.jpg");
//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[10];
int len;
while ((len=bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 资源关闭
//要求:先关闭外层的流,再关闭内层的流
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//说明:关闭外层流的同时,内层流也会自动关闭,所以可省略
// fos.close();
// fis.close();
}
//实现文件复制的方法
public void copyFileWithBuffered(String srcPath,String destPath){
BufferedInputStream bis= null;
BufferedOutputStream bos= null;
try {
//1. 造文件
File srcFile=new File(srcPath);
File destFile=new File(destPath);
//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[10];
int len;
while ((len=bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4. 资源关闭
//要求:先关闭外层的流,再关闭内层的流
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis!=null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BufferedReader和BufferedWriter
/*
* 使用BufferedReader和BufferedWriter实现文本文件的复制
* */
@Test
public void TestBufferedReaderBufferedWriter(){
BufferedReader br= null;
BufferedWriter bw= null;
try {
//
br = new BufferedReader(new FileReader(new File("hello.txt")));
bw = new BufferedWriter(new FileWriter(new File("hello1.txt")));
//读写操作
//方式一
// char[] cbuf=new char[1024];
// int len;
// while ((len=br.read(cbuf))!=-1){
// bw.write(cbuf,0,len);
// }
//方式二
String data;
while ((data=br.readLine())!=null){
//方式一
// bw.write(data+"\n"); //data不包含换行符
//方式二
bw.write(data);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if (bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
转换流
-
- 转换流: 属于字符流
-
InputStreamReader:将一个字节的输入流转换为字符的输入流
- 解码:字节、字节数组–>字符数组,字符串
-
OutputStreamWriter:将一个字节的输出流转化为字符的输出流
- 编码:字符数组、字符串–>字节,字节数组
-
- 作用:提供字节流和字符流之间的转换
public class InputStreamReaderTest {
//InputStreamReader的使用,实现了字节的输入流到字符的输入流的转换
@Test
public void test1() throws IOException {
FileInputStream fis=new FileInputStream("hello.txt");
//参数2指明了字符集
InputStreamReader isr=new InputStreamReader(fis,"UTF-8"); //使用系统默认字符集
char[] cbuf=new char[20];
int len;
while ((len=isr.read(cbuf))!=-1){
String str=new String(cbuf,0,len);
System.out.println(str);
}
isr.close();
}
@Test
public void test2() throws IOException {
//1. 造文件,造流
File file1=new File("hello.txt");
File file2=new File("hello_gbk.txt");
FileInputStream fis=new FileInputStream(file1);
FileOutputStream fos=new FileOutputStream(file2);
InputStreamReader isr=new InputStreamReader(fis,"utf-8");
OutputStreamWriter osw=new OutputStreamWriter(fos,"gbk");
//2. 读写过程
char[] cbuf=new char[20];
int len;
while ((len=isr.read(cbuf))!=-1){
osw.write(cbuf,0,len);
}
//3. 关闭资源
isr.close();
osw.close();
}
}
其他流的使用
-
- 标准的输入、输出流
-
- 打印流
-
- 数据流
-
- 标准的输入、输出流
1.1
System.in
System.out
1.2
System类的setIn(InputStream is)/ setOut(PrintStream ps)的方式
1.3 练习:
从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,
直至输入"e"或者"exit"时,退出程序
方法一:Scanner --> next()返回一个字符串
方法二:System.in --> BufferedReader的readLine()
- 标准的输入、输出流
public static void main(String[] args) {
BufferedReader br= null;
try {
InputStreamReader isr=new InputStreamReader(System.in);
br = new BufferedReader(isr);
while (true){
String data=br.readLine();
if ("e".equalsIgnoreCase(data)||"exit".equalsIgnoreCase(data)){
System.out.println("Program end");
}
String upperCase=data.toUpperCase();
System.out.println(upperCase);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
* 2. 打印流:PrintStream和PrintWriter
*
* 2.1 提供了一系列重载的print()和println()
* 2.2 练习:
@Test
public void test2(){
PrintStream ps=null;
try {
FileOutputStream fos=new FileOutputStream(new File("D:\\IO\\text.txt"));
// 创建打印输出流,设置为自动刷新模式(写入换行符或字节'\n'时都会刷新缓冲区)
ps=new PrintStream(fos,true);
if (ps!=null){
System.setOut(ps);
}
for (int i = 0; i < 255; i++) { // 输出ASCII字符
System.out.println((char) i);
if (i%50==0){ // 每50个数据一行
System.out.println(); // 换行
}
}
} catch (FileNotFoundException e){
e.printStackTrace();
} finally {
if (ps != null){
ps.close();
}
}
}
/*
* 3. 数据流
* 3.1 DataInputStream和DataOutputStream
* 3.2 作用:用于读取或写出基本数据类型的变量或字符串
*
* 练习:将内存中的字符串,基本数据类型变量写出到文件中
* */
@Test
public void test3() throws IOException {
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("xxx");
dos.writeInt(13);
dos.writeBoolean(true);
dos.flush();
dos.close();
}
@Test
public void test4() throws IOException {
//1.
DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
//2.
String name = dis.readUTF();
int age = dis.readInt();
boolean isMale = dis.readBoolean();
System.out.println(name);
System.out.println(age);
System.out.println(isMale);
//3.
dis.close();
}