Java之文件输入输出流的使用
File 类
一个 File 类的对象可以代表一个文件或者一个目录的路径,可以是相对路径也可以是绝对路径.当创建了一个对象后,就可以使用这个对象对其指定的目录/文件进行各种各样的操作了.
构造方法
方法 | 说明 |
---|---|
File(String pathname) | 根据一个路径得到File对象 |
File(String parent, String child) | 根据一个目录和一个子文件/目录得到File对象 |
File(File parent, String child) | 根据一个父File对象和一个子文件/目录得到File对象 |
就拿我电脑里的 “D:\tme\tmp\FileDemo.txt” 举例,第一个构造方法来获取对象这么写就行: File file = new File("D:/tme/tmp/FileDemo.txt")
第二个构造方法这么写: File file = new File("D:/tme/tmp","FileDemo.txt")
第三个构造方法需要现有一个 File 对象作为父级目录,然后再获得父级目录下面的子目录或子文件:
//先得dě有一个父级目录的对象
File par = new File("D:/tme/tmp");
//从父级目录获得子级对象
File file = new File(par, "FileDemo.txt");
参数地址也可以用斜杠而不用反斜杠,记得使用双斜杠转义一下:
new File("D:\\tme\\tmp\\FileDemo.txt")
new File("D:\tme\tmp\FileDemo.txt")
比较常用的方法
目录/文件创建
方法 | 说明 |
---|---|
boolean createNewFile() | 创建文件,如果存在则不创建 |
boolean mkdir() | 创建文件夹,如果存在则不创建 |
boolean mkdirs() | 创建文件夹,如果父文件夹不存在,会帮你创建出来 |
createNewFile()
使用该方法创建一个新文件,新文件的父级目录必须是已经存在的,记得写异常处理(IDE 生成即可)
//在指定目录创建一个txt文档
File file = new File("D:/tmp/tmp/FileDemo.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
如果父级目录不存在则会报错,最后一行指出错误的类名以及行数
java.io.IOException: 系统找不到指定的路径。
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:1012)
at File.FileCreateDemo.main(FileCreateDemo.java:10)
mkdir()
使用该方法创建一个新文件夹,新文件夹的父级目录必须是已经存在的
File file = new File("D:/tmp/tmp");
file.mkdir();
这里不需要异常捕捉,父级目录不存在不会报错但也不会创建新的目录
mkdirs()
使用该方法创建一个新文件夹,如果指定的父级目录不存在,照样给你创建出来
File file = new File("D:/tmp/tmp");
file.mkdirs();
不需要捕捉异常,我的电脑里 D 盘没有 tmp 这个文件夹,现在不仅有了而且还有一个 tmp 子文件夹
绝对地址/相对地址: 如果不写盘符或者根目录,则创建的文件/文件夹会产生于 IDE 的项目文件夹里
重命名和删除
方法 | 说明 |
---|---|
boolean renameTo(File dest) | 把文件重命名为指定的文件路径 |
boolean delete() | 删除文件或者文件夹 |
renameTo(File dest)
使用该方法对 File 对象进行重命名或者移动/重命名操作
如果目标对象指定的路径和源对象的路径相同,则进行重命名操作:
File file = new File("D:/tme/tmp/FileDemo.txt");
file.renameTo(new File("D:/tme/tmp/FileRenameDemo.txt"));
renameTo()
方法中传入的是 File 类的对象这里简写直接 new 了一个,也可以老老实实的创建对象后再使用:
File dest = new File("D:/tme/tmp/FileRenameDemo.txt");
file.renameTo(dest);
这样一来,FileDemo.txt 就被重命名为 FileRenameDemo.txt 了
如果目标对象指定的路径和源对象的路径不同,则进行移动操作,也可以移动的同时重命名:
File file = new File("D:/tme/tmp/FileRenameDemo.txt");
file.renameTo(new File("D:/tme/FileDemo.txt"));
D:/tme/tmp 文件夹下的 FileRenameDemo.txt 被移动到 D:/tme 文件夹并且重命名为 FileDemo.txt
delete()
使用该方法将会直接删除文件或文件夹,连回收站都找不到(不会走系统回收站)
File file = new File("D:/tme/tmp/FileRenameDemo.txt");
file.delete();
文件/文件夹属性判断
方法 | 说明 |
---|---|
boolean isDirectory() | 判断是否是目录 |
boolean isFile() | 判断是否是文件 |
boolean exists() | 判断文件(夹)是否存在 |
boolean canRead() | 判断文件(夹)是否可读 |
boolean canWrite() | 判断文件(夹)是否可写 |
boolean isHidden() | 判断文件(夹)是否隐藏 |
文件/文件夹属性获取
方法 | 说明 |
---|---|
String getAbsolutePath() | 获取文件(夹)绝对路径 |
String getPath() | 获取文件(夹)路径 |
String getName() | 获取文件(夹)名称 |
long length() | 获取文件(夹)长度(字节数) |
long lastModified() | 获取文件(夹)最后一次的修改时间(毫秒) |
String[] list(); | 获取文件夹下的所有文件或者文件夹的名称并存为数组 |
File[] listFiles() | 获取文件夹下的所有文件或者文件夹生成 File 对象并存为数组 |
File file = new File("D:/tme/tmp/FileDemo.txt");
File file2 = new File("D:/tme/tmp");
System.out.println("getAbsolutePath()获取文件绝对路径 " + file.getAbsolutePath());
System.out.println("getAbsolutePath()获取文件夹绝对路径 " + file2.getAbsolutePath());
System.out.println("getPath()获取文件路径 " + file.getPath());
System.out.println("getPath()获取文件夹路径 " + file2.getPath());
System.out.println("getName()获取文件名 " + file.getName());
System.out.println("getName()获取文件夹名 " + file2.getName());
System.out.println("length()获取文件长度 " + file.length());
System.out.println("length()获取文件夹长度 " + file2.length());
System.out.println("lastModified()获取文件最后修改时间 " + new Date(file.lastModified()));
System.out.println("lastModified()获取文件夹最后修改时间 " + new Date(file.lastModified()));
System.out.println("list()获取所有文件和文件夹的名称 " + Arrays.toString(file2.list()));
System.out.println("listFiles()获取所有文件和文件夹的File数组 "
+ Arrays.toString(file2.listFiles()));
输出结果:
getAbsolutePath()获取文件绝对路径 D:\tme\tmp\FileDemo.txt
getAbsolutePath()获取文件夹绝对路径 D:\tme\tmp
getPath()获取文件路径 D:\tme\tmp\FileDemo.txt
getPath()获取文件夹路径 D:\tme\tmp
getName()获取文件名 FileDemo.txt
getName()获取文件夹名 tmp
length()获取文件长度 6
length()获取文件夹长度 0
lastModified()获取文件最后修改时间 Mon Dec 24 20:49:13 CST 2018
lastModified()获取文件夹最后修改时间 Mon Dec 24 20:49:13 CST 2018
list()获取所有文件和文件夹的名称 [FileDemo.txt, 子文件夹]
listFiles()获取所有文件和文件夹的File数组 [D:\tme\tmp\FileDemo.txt, D:\tme\tmp\子文件夹]
流
大多数应用程序都需要和外部的设备进行数据交换,在 Java 中所有的 I/O 机制都是基于数据流的方式进行输入和输出的
流的分类
根据流动方向和传输格式的不同分为以下四种:
- 字节输入流
InputStream
- 字节输出流
OutputStream
- 字符输入流
Reader
- 字符输出流
Writer
字节流和字符流的区别
字节流是指 8 位的通用字节流,以字节为基本单位,能处理所有类型的数据
字符流是指 16 位的 Unicode 字符流,以字符(两个字节)为基本单位,仅能处理纯文本数据
字节流
InputStream
InputStream 是字节输入流,InputStream 类是一个抽象类,所有继承了该类的类都是 字节输入流
FileInputStream
FileInputStream 类是 InputStream 类的一个实现类,它是 文件输入流
方法 | 说明 |
---|---|
int read() | 读取一个字节并以整数的形式返回,到达文件末尾时则会返回-1 |
int read(byte[] buffer) | 读取很多个字节并存储到数组中,返回实际读取的字节数,读取前已到输入流的末尾则返回-1 |
int read(byte[] buffer, int offset, int length) | 读取 length 个字节存到数组,读取到输入流的末尾时返回-1 |
void close() | 关闭输入流,释放内存对象 |
例子:读取文本中的文字内容
try {
FileInputStream fileInputStream = new FileInputStream("D:/tme/tmp/FileDemo.txt");
byte[] input = new byte[12];
//读取12个字节存储到input数组里
fileInputStream.read(input);
String inputString = new String(input, "GBK");
System.out.println(inputString);
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
使用文件流必须要做好异常处理,这里使用的是 FileInputStream 类的 read(byte[] buffer) 方法,String(input,“GBK”) 限定了读取时的字符编码为 GBK,防止乱码产生,得到输出结果
成功了哇咔咔
顺便,之所以这里用 GBK 是因为我的那个文本文件用的是 GBK 编码,只要编码格式一致就不会出现乱码.输入流在使用完成后记得关闭: close()
OutputStream
OutputStream 是字节出流,OutputStream 类是一个抽象类,所有继承了该类的类都是 字节输出流
FileOutputStream
FileOutputStream 类是 OutputStream 类的一个实现类,它是 文件输出流
方法 | 说明 |
---|---|
void write(int b) | 往文件中写数据,一次写一个字节 |
void write(byte[] b) | 往文件中写数据,将byte数组中的数据全部写入到文件中 |
void write(byte[] b,int off ,int length) | 将指定byte数组中的数据从偏移量off开始的length个字节写入此输入流 |
void close() | 关闭流对象 |
例子:向磁盘中写入文件
File file = new File("fosd.txt");
String string = "尝试着写入文件";
try {
FileOutputStream fosd = new FileOutputStream(file);
byte[] bytes = string.getBytes();
fosd.write(bytes);
fosd.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
异常处理还是不能少.本例中,我并没有写 file.createNewFile()
,但是输出流会自动帮忙创建这个文件.输出流用完后记得关闭. getBytes()
方法可以指定读取特定的编码方式,比如 getBytes("utf-8")
FileOutputStream
构造方法中如果只写一个 File 对象,运行时会覆盖掉文件内容,多次运行上面这段代码,文本内容也只有一句「尝试着写入文件」
使用 FileOutputStream(File file,boolean append)
方法即可指定是否是在原文本内容上追加内容
使用字节流实现文件拷贝
//源文件
File file1 = new File("D:/0.mp4");
//目标地址,需要具体到文件名
File file2 = new File("D:/tme/1.mp4");
try {
FileInputStream inputStream = new FileInputStream(file1);
FileOutputStream outputStream = new FileOutputStream(file2);
byte[] bytes = new byte[1024];
int tmp = 0;
while ((tmp = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, tmp);
}
outputStream.close();
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
理一下细节:这里使用 tmp 来存储每次 read(bytes) 返回的值,其实前面每次返回的都是读取到的字节数量 1024,直到最后一次读取(最后一次读时读到的数量就是文件大小-n 个 1024),只要 tmp != -1,输出流就输出一次,从第 0 个字节开始输出 1024 个字节.
上一篇: IO流框架总结
下一篇: 4种CSS文字竖排方法
推荐阅读
-
Java实现拖拽文件上传dropzone.js的简单使用示例代码
-
在Python中操作文件之truncate()方法的使用教程
-
在Python程序中操作文件之flush()方法的使用教程
-
Python中操作文件之write()方法的使用教程
-
在Python程序中操作文件之isatty()方法的使用教程
-
在Python中操作文件之seek()方法的使用教程
-
在Python中操作文件之read()方法的使用教程
-
Java之JDK的下载与安装,java环境变量的配置,Editplus的下载与使用
-
Java开发之使用websocket实现web客户端与服务器之间的实时通讯
-
java实现导出文字+数据的excel文件并返回文件流