[TOC]
# 文件操作
## 什么是文件
文件是计算机中基本的数据存储形式,在实际的存储数据中,如果对数据的读写速度要求不高,而且存储的数据量也不是很大,此时,可以选择使用文件这种持久化的存储方式。
所谓**持久化**,就是当程序退出,或者计算机关机以后,数据还是存在的。但是在程序内存中的数据会在程序关闭或计算机退出时丢失。
文件的组成:路径+文件的全名(文件名和文件后缀)。
关于文件后缀:只是定义了文件的打开方式不一样,如果更改后缀不会对文件的内部数据产生变化。
在不同的操作系统中,文件的路径表示形式是不一样的。
比如:
`windows c:\windows\system\driver.txt`
`Linux /user/my/tomcat/startup.txt`
> 如果程序需要在不同的操作系统中运行,那么如果出现文件路径相关的设置时,必须要进行操作系统的判断,特别是windows和Linux关于斜杠的区别。
## 绝对路径和相对路径
绝对路径指文件的完整路径,例如:c:\hello\hello.java。该路径包含文件的路径和文件的文件名即后缀。
使用该路径可以唯一的找到该文件。但是,在不同的操作系统下,文件的绝对路径表现形式是不一样的。这样就会比较麻烦。
相对路径是书写文件的部分路径:
如下文件结构
~~~
D
└─test
│ a.txt
│
└─A
b.txt
~~~
如使用 `D:\test` 作为基准目录
* a.txt 相对路径:a.txt
* b.txt 相对路径:A\b.txt
如使用D:\text\A作为基准目录
* a.txt的相对路径:..\a.txt
* b.txt的相对路径:b.txt
> 在Java中\是转义字符,如果要是\进行路径的描述时,要使用“\\”表示。
> 可以通过System.getProperty("file.separator")的通用方式获取不同操作系统的文件分隔符(如Linux/windows\)
**相对路径**
Java 中文件的相对路径是相对 JVM 的启动路径而言的。
表现当前路径的方式:`.` 、`.\`、 `不使用任何的符号`;
一个点表示当前路径,两个点”..”表示上级目录。
在大部分的应用程序中,我们都会使用相对路径去构建文件。
通过 `Clazz.class` 获取类的元数据,然后调用 `Clazz.class.getResource("相对路径")` 获取绝对路径,进行文件创建。
## File 类
为了方便的通过Java对文件进行基本的处理,在 java.io 包中设计了 File 类。
> File只能表现文件本身和目录(文件中的内容不在File类的管理范畴内)
### 文件常用的操作方法
~~~
public class FileClient1 {
public static void main(String[] args) throws IOException {
}
/**
* 创建一个新文件
* @param path
* @throws IOException
*/
public static void createNewFile(String path) throws IOException {
File file = new File(path);
boolean createFlag = file.createNewFile();
System.out.println(createFlag);
}
/**
* 删除一个文件
* @param path
* @throws IOException
*/
public static void deleteFile(String path) throws IOException {
File file = new File(path);
boolean delteFlag = file.delete();
// 返回true表示删除成功 false表示删除失败,失败的原因大部分是文件不存在
System.out.println(delteFlag);
}
/**
* 判断一个文件后者路径是否存在
* @param path
*/
public static void existsFile(String path) {
File file = new File(path);
System.out.println(file.exists());
}
/**
* 获取文件的绝对路径
* @param path
*/
public static void getAbsolutePath(String path) {
File file = new File(path);
System.out.println(file.getAbsolutePath());
}
/**
* 获取文件名
* @param path
*/
public static void getFileName(String path) {
File file = new File(path);
System.out.println(file.getName());
}
/**
* 获取父路径
*/
public static void getParent(String path) {
File file = new File(path);
System.out.println(file.getParent());
}
/**
* 判断一个文件对象是否是目录
*/
public static void isDirectory(String path) {
File file = new File(path);
System.out.println(file.isDirectory());
}
/**
* 判断一个文件对象是否是文件
* @param path
*/
public static void isFile(String path) {
File file = new File(path);
System.out.println(file.isFile());
}
/**
* 获取文件目录下的所有文件和目录清单
* @param path
*/
public static void list(String path) {
File file = new File(path);
String[] files = file.list();
for (String fileName : files) {
System.out.println(fileName);
}
}
/**
* 获取文件目录下的所有文件和目录清单(文件名)
* @param path
*/
public static void listFiles(String path) {
File file = new File(path);
File[] files = file.listFiles();
for (File fileName : files) {
System.out.println(fileName.getAbsolutePath());
}
}
/**
* 创建目录
* @param path
*/
public static void mkdir(String path) {
File file = new File(path);
System.out.println(file.mkdir());
}
/**
* 创建目录(如果父目录不存在,则创建父目录)
* @param path
*/
public static void mkdirs(String path) {
File file = new File(path);
System.out.println(file.mkdirs());
}
/**
* 文件重命名
* @param oldFileName
* @param newFileName
*/
public static void renameTo(String oldFileName, String newFileName) {
File oldFile = new File(oldFileName);
File newFile = new File(newFileName);
System.out.println(oldFile.renameTo(newFile));
}
/**
* 设置文件只读
* @param path
*/
public static void setReadonly(String path) {
File file = new File(path);
System.out.println(file.setReadOnly());
}
}
~~~
### 文件的递归读取和递归删除
递归遍历文件
~~~
public static void main(String[] args) {
printAllFile(new File("D:\\test"));
}
public static void printAllFile(File file) {
String filePath = file.getAbsolutePath();
System.out.println(filePath);
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File lf : files) {
printAllFile(lf);
}
}
}
~~~
递归删除文件
~~~
public static void main(String[] args) {
deleteAllFile(new File("D:\\test"));
}
public static void deleteAllFile(File file) {
if (file.isFile()) {
// 直接删除文件
file.delete();
} else {
File[] files = file.listFiles();
for (File fl : files) {
deleteAllFile(fl);
}
// 删除目录
file.delete();
}
}
~~~
## 文件读取
文件的类型:字符型文件(简单立即就是记事本可以打开的文件,比如.java文件)、二进制文件(可以简单理解为编译过的文件,如 .class 文件、 .jpg 等图片文件、 .exe 可执行文件...)
对于文件读取操作,使用输入对应的子类:FileInputStream 和 FileReader 实现。
在Java的IO编程中,读取文件分为:
1. 将文件中的数据转换为流;
2. 读取流内部的数据。
其中第一步是系统自动完成的,读取流内部数据需要程序控制;
在通过输入流进行编程时,分为3个部分
1. 创建流对象;
2. 读取流对象内部的数据;
3. 关闭流。
代码示例
~~~
public static void main(String[] args) {
// 声明一个流对象
FileInputStream fis = null;
File file = new File("D:\\test1\\a.txt");
try {
// 通过File对象构建一个流对象
fis = new FileInputStream(file);
// 读取数据,并将读取的数据存储在数组中
byte[] data = new byte[(int)file.length()];
// 读取流中的第一个字节数据
int n = fis.read();
// 读取的游标位置
int i = 0;
// 判断是否读到最后一个字符
while(n != -1) {
data[i] = (byte)n;
i++;
n = fis.read();
}
String rs = new String(data, "GBK");
System.out.println(rs);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭流,释放资源
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
## 文件写入
~~~
public static void main(String[] args) {
String s = "Hello,Java!";
// 声明一个输出流
FileOutputStream fos = null;
File file = new File("d:\\test1\\a.txt");
try {
// 根据文件创建一个输出流对象
fos = new FileOutputStream(file);
byte[] data = s.getBytes();
fos.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
~~~
## Java中常见的编码格式
在计算机系统中,ASCII码是最基础的编码格式,8bit存储一个字节数据,能够表示的字符范围为 255。
由于 ASCII 所变现的字符较少,随后就出现了包括 `ISO-8859-1` 、`GB2312`、`GBK`、`GB18030`、`UTF-16`、`UTF-8` 等编码格式。
目前在应用开发中,使用 UTF-8 的编码方式是最常见的,其次为 GBK。
我们在标识符定义中所说的 unicode 字符集就是指的的 UTF 编码方式。
除了 ASCII 码是用一个字节表示数据的,其他都是 2-4 个字节表示。
在文件字节流中读取的 `byte[]` 数据,最后通过 `new String(byte[], charsetName)` 方法构建的对象,第二个参数就是文件的编码方式。(把一个字节数组转化为字符串,如果不显式的指明字节的编码方式,则用系统默认的编码方式)。
在控制台输入chcp命名可以查询到系统目前使用的文字编码方式 936 表示的是 GBK。
~~~
String rs = new String(data, "GBK");
~~~
## 字节流和字符流
字符流其实是字节流的一种特殊表现。
在IO流中,字符流的输入输出使用的 Writer/Reader,字节流使用InputStream/OutputStream。
* 输入流:只能做读操作
* 输出流:只能做写操作
## 使用RandomAccessFile类进行数据的追加
~~~
File file = new File("D:\\work\\Trade\\ws01\\JAVA88-1\\src\\test0613\\a1.txt");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(raf.length());
raf.writeBytes("\r\nend");
raf.close();
~~~
- 前言
- 计算机概论
- 数据库
- 数据库介绍
- MySQL的安装
- SQL
- 表基本操作
- 修改数据语句
- 数据检索操作
- 多表数据操作
- 表结构设计
- 综合应用
- JAVA
- JAVA 介绍
- JAVA 运行原理
- JDK 配置
- 类和对象
- 数据类型
- 变量
- 直接量
- 运算符
- 流程控制
- 数组结构
- 面向对象
- 隐藏和封装
- 深入构造器
- 类的继承
- 多态
- 包装类
- final 修饰符
- 抽象类
- 接口
- 集合框架
- 常用类学习
- 异常处理
- 设计模式-单例模式
- JDBC
- JSP&Servlet
- Web应用
- Tomcat
- JSP
- Scriptlet
- Page 指令
- 包含指令
- 跳转指令
- 用户注册实例
- JSP练习
- 内置对象
- Servlet
- 过滤器
- Web分层思想
- EL表达式
- JSTL
- 分页实现
- AJAX&JSON
- 开发步骤
- 路径问题
- Log4j
- 电子书城
- 案例分析
- 核心代码
- Java 高级
- 文件操作
- 泛型
- 类加载机制和反射
- 注解 Annotation
- Mybatis框架
- 框架介绍
- Mybatis简单实现
- 表基本操作
- 优化配置文件
- 表字段名与实体类属性名不同的解决方案
- 一对一关联
- 一对多关联
- 教学管理
- 学员名录
- 周测统计
- 2017-10-27
- 2017-11-03
- 2017-11-10
- 2017-11-17
- 课堂作业
- 班会纪要
- 2017-10-24
- 缺勤记录
- 班级备忘录
- 违纪统计
- 编程素养
- Day001
- Day002
- Day003
- Day004
- Day005
- Day006
- Day007
- Day008
- Day009
- Day010
- Day011
- Day012
- Day013
- Day014
- Day015
- Day016
- Day017
- Day018
- Day019