目录
DataOutputStream和DataInputStream
一、文件基本信息:
(1) 获取文件或目录的详细信息
getName()
length()
isHidden()
exists
(2) 获取文件或目录的路径
getPath()
getAbsolutePath()
getCanonicalPath()
(3) 创建、删除、重命名
createNewFile():只能用来创建文件
mkdir(): 创建文件夹,只能创建一级目录
mkdirs(): 创建多级目录
delete(): 可以删除文件
可以删除空目录
renameTo(File dest) 可以给文件和目录重命名
(4) 判断是文件还是目录
isDirectory() : 是存在的一个文件夹,返回true
isFile() : 是存在的一个文件,返回true
(5) 不存在的一个文件或目录
你获取他的name,path这些是有值的,因为这些属性是通过构造器创建File时指定的
而其他的属性都是默认值
package IOTest;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test01File {
@Test
public void test10() {
File file = new File("H:\\IOGUIGU\\java/3.txt");
if (file.isDirectory()) {
System.out.println("file是一个文件夹");
}
if (file.isFile()) {
System.out.println("file是一个文件");
}
}
@Test
public void test09() {
File file = new File("H:\\IOGUIGU\\java/2.txt");
File dest = new File("H:\\IOGUIGU\\python/3.txt");
file.renameTo(dest);
}
@Test
public void test08() {
// 想直接删除testIO这个根目录,其里面还有子文件夹
// 运行失败,因为里面还有内容
File file = new File("H:/testIO");
file.delete();
}
@Test
public void test07() {
// 只能删除最后一级目录
File file = new File("H:/testIO/java/haha");
file.delete();
}
@Test
public void test06() {
File file = new File("H:/1.txt");
file.delete();
}
@Test
public void test02() {
File file = new File("H:/尚硅谷资料/02_每日上课\\01_JavaSe+JDBC\\day22_全天上课资料\\day22_video/day22_01java.io.File类.avi");
System.out.println("文件名:" + file.getName());
System.out.println("文件大小:" + file.length());
System.out.println("文件是否是隐藏文件:" + file.isHidden());
System.out.println("文件是否存在:" + file.exists());
System.out.println("文件是否可读:" + file.canRead());
System.out.println("文件是否可写:" + file.canWrite());
String parent = file.getParent();
File parentFile = file.getParentFile();
System.out.println("文件的父目录:" + parent);
System.out.println("文件最后修改时间:" + file.lastModified() + "毫秒");
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:sss");
System.out.println("文件最后修改时间:" + sf.format(new Date(file.lastModified())));
}
@Test
public void test01() throws IOException {
//相对路径:相对当前的项目
File file = new File("后续笔记/第一张.txt");
System.out.println("文件的路径:" + file.getPath());
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("文件的规范路径:" + file.getCanonicalPath());
/**
* 文件的路径:后续笔记\第一张.txt
文件的绝对路径:G:\ProjectTest\com.aiyunxiao.0118test\后续笔记\第一张.txt
文件的规范路径:G:\ProjectTest\com.aiyunxiao.0118test\后续笔记\第一张.txt
*/
}
@Test
public void test03() throws IOException {
//
File file = new File("../../后续笔记/第一张.txt");
System.out.println("文件的路径:" + file.getPath());
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("文件的规范路径:" + file.getCanonicalPath());
/**
* 文件的路径:..\..\后续笔记\第一张.txt
文件的绝对路径:G:\ProjectTest\com.aiyunxiao.0118test\..\..\后续笔记\第一张.txt
文件的规范路径:G:\后续笔记\第一张.txt
*/
}
@Test
public void test04() throws IOException {
File file = new File("H:/1.txt");
if (!file.exists()) {
System.out.println("文件不存在,创建这个文件");
file.createNewFile();
}
}
@Test
public void test05() {
File file = new File("H:/testIO/java/haha");
if (!file.exists()) {
System.out.println("文件夹不存在,创建这个文件夹");
file.mkdirs();
}
}
}
获取文件下一级
-
String[] list(); 得到下一级文件或目录的名称
-
File[] listFiles(); 得到下一级文件或目录的File对象
求一个目录的总大小
删除一个包含子目录,子文件的文件夹
public class Test02Dir {
@Test
public void test04(){
File file = new File("H:\\IOGUIGU");
deleteDir(file);
}
public void deleteDir(File dir){
// 如果是文件夹,先把他的下一级删除
if(dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
deleteDir(file);
}
}
// 如果是文件或者空文件夹,直接删除
dir.delete();
}
@Test
public void test03(){
File dir = new File("H:\\尚硅谷资料\\01_尚硅谷大数据之各个模块\\01_尚硅谷大数据之JavaSE_柴林燕\\笔记");
long size = getSize(dir);
System.out.println(size);
}
public long getSize(File file){
if(file.isFile()){
return file.length();
}else if(file.isDirectory()){
long sum = 0;
File[] files = file.listFiles();
for (File sub : files) {
sum += getSize(sub);
}
return sum;
}
return 0;
}
@Test
public void test02(){
File dir = new File("H:\\尚硅谷资料\\01_尚硅谷大数据之各个模块\\01_尚硅谷大数据之JavaSE_柴林燕\\笔记");
listAllSub(dir);
}
public void listAllSub(File dir){
if(dir.isDirectory()){
File[] files = dir.listFiles();
for (File file : files) {
listAllSub(file);
}
}else {
System.out.println(dir);
}
}
@Test
public void test01(){
File dir = new File("H:\\尚硅谷资料\\01_尚硅谷大数据之各个模块\\01_尚硅谷大数据之JavaSE_柴林燕\\笔记");
String[] list = dir.list();
for (String sub : list) {
System.out.println(sub);
}
}
}
文件过滤器
public class TestIOFilter {
@Test
public void test01(){
// 列出指定目录底下的.java文件
File dir = new File("H:\\尚硅谷资料\\02_每日上课\\01_JavaSe+JDBC\\day22_全天上课资料\\day22_code\\src\\com\\atguigu\\test01");
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java");
}
});
for (File file : files) {
System.out.println(file);
}
}
}
二、IO
IO概述:
1、操作数据的单位:
字节流和字符流
- 字节流:以字节为单位byte
- 字符流:以字符为单位char
字符流只能用于读、写纯文本数据
- 纯文本数据:内容全部是字符
- 纯文本文件:.txt .html .xml .properties等都是纯文本文件。 .doc .xls .ppt都不是
注意:字节流适用于任何类型的文件,但是如果是纯文本文件用字符流快
2、 功能角色 : 节点流和处理流
- 节点流:和某个节点关联,例如:文件流。。。
- 处理流:在节点流的基础上,加其他的处理功能的,加装饰功能的,例如:缓冲流,序列化与反序列化等
3、IO流有四大抽象的基类 超类 父类
- InputStream:字节输入流
- OutputStream:字节输出流
- Reader:字符输入流
- Writer:字符输出流
例如:文件IO流
- FileInputStream:文件字节输入流
- FileOutputStream:文件字节输出流
- FileReader:文件字符输入流
- FileWriter:文件字符输出流
例如:缓冲IO流
- BufferedInputStream:字节缓冲输入流
- BufferedOutputStream:字节缓冲输出流
- BufferedReader:字符缓冲输入流
- BufferedWriter:字符缓冲输出流
。。。
文件的IO操作
Reader系列:
- int read() : 读取一个字符,正常返回的是该字符的Unicode编码值
- int read(char[ ] dbuf) : 读取多个字符,读取的字符放到dbuf数组中,从cbuf的【0】开始存储,最多读取cbuf.length个字符。返回本次读取的字符的个数。
- int read(char[ ] cbuf, int off, int len): 读取多个字符,读取的字符放到cbuf数组中,从cbuf的【off】开始 实际返回本次读取的字符的个数。
注意:如果流中没数据,统统返回-1.
读取一个纯文本的文件步骤:
- 选择IO流,创建IO对象
- 读、写操作
- 关闭IO流,释放资源
public class Test05 {
@Test
public void test04() throws IOException {
FileReader fr = new FileReader("H:/1.txt");
char[] arr = new char[10];
while (true) {
int len = fr.read(arr);
if (len == -1){
break;
}
System.out.println(new String(arr,0,len));
}
fr.close();
}
@Test
public void test03() throws IOException {
FileReader fr = new FileReader("H:/1.txt");
char[] arr = new char[10];
// 从文件的最开始位置开始读取,只读取3个字符,放到数组的第五个位置开始放
int read = fr.read(arr, 5, 3);
System.out.println(arr);
System.out.println(read);
}
@Test
public void test02() throws IOException {
FileReader fr = new FileReader("H:/1.txt");
char[] arr = new char[10];
// 返回实际读取的字符的个数
int read = fr.read(arr);
System.out.println(arr);
System.out.println(read);
}
@Test
public void test01() throws IOException {
// 1、选择IO流
// 选择IO流,因为是操作纯文本文件,这里选择字符流
// 又因为是读取操作,这里使用FileReader
FileReader fr = new FileReader("H:/1.txt");
//2、读取文件内容
// 数据流向:1.txt --> fr流中 --> 从流中开始读取
int data = fr.read();
System.out.println(data);
// 3、关闭
fr.close();
}
}
Writer系列
// 写单个字符 c
void write(int c)
// 把整个字符数组的内容都写进去
void write(char[] cbuf)
// 把cbuf[off]开始。len个字符写进去
void write(char[] cbuf, int off, int len)
// 把str 的内容都写出去
void write(String str)
// 把str从[off]开始len个字符写进去
void write(String str, int off, int len)
// 关闭
void close()
// 刷新
void flush()
public class FileWriterTest {
@Test
public void test02() throws IOException {
String str = "今天天气不错";
FileWriter fw = new FileWriter("H:/1.txt", true);
fw.write("\n");
fw.write(str);
fw.close();
}
@Test
public void test01() throws IOException {
String str = "据说周末下雨";
// 1、选择IO流,并创建对象
FileWriter fw = new FileWriter("H:/1.txt");
// 2、写数据
fw.write(str);
// 3、关闭
fw.close();
}
}
复制文件
public class FileCopy {
@Test
public void test01() throws IOException {
String srcFile = "H:/1.txt";
String destFile ="H:/2.txt";
copy(srcFile,destFile);
}
public void copy(String srcFileName,String destFileName) throws IOException {
// 1、选择IO流,并创建IO流
FileReader fr = new FileReader(srcFileName);
FileWriter fw = new FileWriter(destFileName);
// 2、一边读一边写
char[] str = new char[10];
int len;
// 数据从 srcFile --> fr --> str数组 --> fw --> destFile
while ((len=fr.read(str))!=-1){
fw.write(str,0,len);
}
// 3、关闭流
fw.close();
fr.close();
}
}
InputStream
// 一次读取一个字节,返回本次读取的字节的值
int read()
// 一次读取多个字节,返回本次实际读取字节数,读取的字节存到b数组中,从[0]开始存储,一次最多读取b.length个字节
int read(byte[] b)
// 一次读取多个字节,返回本次实际读取字节数,读取的字节存到b数组中,从[off] 开始存储,一次最多读取len个字节
int read(byte[] b, int off, int len)
// 关闭流
void close()
// 如果到达流末尾,返回-1
public class InputStreamTest {
@Test
public void test01() throws IOException {
FileInputStream fis = new FileInputStream("H:/1.txt");
byte[] arr = new byte[10];
int len;
while ((len=fis.read(arr))!=-1){
//System.out.println(Arrays.toString(arr));
// 字节数组 --> 字符串: new String(byte[],off,len)
System.out.println(new String(arr,0,len));
}
fis.close();
}
}
OutputStream
// 写一个字节
void write(int b)
// 写一个字节数组的所有
void write(byte[] b)
// 写一个字节数组的部分
void write(byte[] b, int off, int len)
// 关闭
void close()
// 刷新
void flush()
复制文件V2
public class FileCopy2 {
@Test
public void test01() throws IOException {
FileInputStream fis = new FileInputStream("H:/1.txt");
FileOutputStream fos = new FileOutputStream("H:/3.txt");
byte[] arr = new byte[10];
int len;
while ((len=fis.read(arr))!=-1){
fos.write(arr,0,len);
}
fis.close();
fos.close();
}
}
缓冲IO流
缓冲流是处理流,负责在其他IO流基础上增加缓冲功能。默认的缓冲区大小为8192字节/字符
- BufferedReader --> Reader
- BufferedWriter --> Writer
- BufferedInputStream --> InputStream
- BufferedOutputSream --> OutputStream
注意:BufferedReader除了继承了Reader的那些读的方法,还增加了一个:String readLine()读取一行
@Test
public void test01() throws IOException {
FileReader fr = new FileReader("H:/1.txt");
BufferedReader br = new BufferedReader(fr);
// 数据:1.txt --> fr --> br
String str;
while ((str=br.readLine())!=null){
System.out.println(str);
}
br.close();
fr.close();
}
文件复制:使用缓冲流
@Test
public void copy() throws IOException {
FileReader fr = new FileReader("H:/1.txt");
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("H:/4.txt");
BufferedWriter bw = new BufferedWriter(fw);
// 数据:1.txt --> fr --> br --> bw --> fw --> 4.txt
String str;
while ((str = br.readLine())!=null){
bw.write(str);
bw.newLine(); // 换行
}
bw.close();
fw.close();
br.close();
fr.close();
}
注意:使用buffered***写数据时,如果不手动添加 bw.newLine() 则所有的数据都在一行。
字节流与字符流的转换
- InputStreamReader()
- OutputStreamWriter()
这两个只能用于处理纯文本数据的编码和解码
解码:字节输入流转字符输入流的转换流,同时还能指定编码方式
@Test
public void test01() throws IOException {
FileInputStream fis = new FileInputStream("H:/1.txt");
InputStreamReader isr = new InputStreamReader(fis, "GBK");
// 数据:1.txt(GBK) --> fis(纯字节) --> isr(GBK)解成字符流 -->按字符读取
char[] arr = new char[10];
int len = isr.read(arr);
System.out.println(new String(arr,0,len));
isr.close();
fis.close();
}
编码: 字符 --> 字节
@Test
public void test02() throws IOException {
String str = "蔡老师永远18岁";
FileOutputStream fos = new FileOutputStream("H:/1.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
// 数据: str(字符) --> oos(字符)按照GBK编码为字节流 --> fos --> 1.txt
osw.write(str);
osw.close();
fos.close();
}
DataOutputStream和DataInputStream
- DataOutputStream在OutputStream的基础上,增加了很多方法:writeXxx(...)
- DataInputStream在InputStream的基础尚自,增加了很多方法: readXxx(...)
注意:Java中IO流的类的体系设计,隐含了一个设计模式:装饰者设计模式
应用场景:
* 程序中有这样一组数据:
* int num = 10;
* char c = '好';
* double d = 88.88;
* String info = "尚硅谷真好!";
* boolean good = true;
* 程序运行过程中,想要临时退出,下次希望从这个状态继续恢复执行。
* 希望Java能够输出各种数据类型的数据,读取时,能还原各种数据类型的数据。
* 因为这些数据不是纯文本,那么只能选择字节流。
要求:
- 用DataOutputStream写的文件或数据,得用DataInputStream来读取。
- 并且要求读的顺序与写的顺序要一致。
public class TestData {
@Test
public void test02()throws IOException{
FileInputStream fis = new FileInputStream("data.dat");
DataInputStream dis = new DataInputStream(fis);
int num = dis.readInt();
char c = dis.readChar();
double d = dis.readDouble();
String s = dis.readUTF();
boolean b = dis.readBoolean();
System.out.println(num);
System.out.println(c);
System.out.println(d);
System.out.println(s);
System.out.println(b);
dis.close();
fis.close();
}
@Test
public void test01()throws IOException{
int num = 10;
char c = '好';
double d = 188.88;
String info = "尚硅谷真好!";
boolean good = true;
FileOutputStream fos = new FileOutputStream("data.dat");
/*fos.write(num);//错误的
fos.write(c);
fos.write((byte)d);*/
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(num);
dos.writeChar(c);
dos.writeDouble(d);
dos.writeUTF(info);
dos.writeBoolean(good);
dos.close();
fos.close();
}
}