File:对文件和文件夹的抽象
public class Demo01File {
/*File:对文件和文件夹的抽象
*属性:
* static String separator :获取当前操作系统的路径分隔符
*构造方法:
* File(File parent, String child)
File(String pathname) :参数指定file的路径
File(String parent, String child)
普通方法:
* boolean createNewFile() : 创建新文件 不能创建文件夹
* boolean delete() : 删除文件/文件夹 删除文件夹时 文件夹必须为空
* boolean exists() :判断是否存在
* String getAbsolutePath() :获取绝对路径
* String getName() :获取文件夹/文件名字 不带目录
* String getPath() :获取创建file对象时的构造方法的参数列表
* boolean isDirectory() :判断是否为目录: file必须存在
* boolean isFile() :判断是否为文件: file必须存在
* long length() :获取文件的字节个数:只能获取文件的字节个数
* File[] listFiles() :获取当前文件夹下的所有直接子文件/文件夹
*
* boolean mkdir() :只能创建一层文件夹
* boolean mkdirs() :创建多层文件夹
*
* boolean renameTo(File dest) :重命名
* */
file类的练习
//写一个方法遍历文件夹
public static void show(String fileName) {
//获取file对象
File file=new File(fileName);
//判断是否存在
if(!file.exists()) {
throw new RuntimeException(fileName+"文件不存在");
}
//判断是文件还是文件夹
if(file.isFile()) {
System.out.println("文件:"+file.getAbsolutePath()+"::大小"+file.length()+"字节");
return;
}
//文件夹
System.out.println("文件夹:"+file.getAbsolutePath());
//获取所有的直接子文件
File[] zis=file.listFiles();
for (File zi : zis) {
//判断zi 是文件还是文件夹 是文件直接打印 是文件夹 继续获取所有的子文件/子文件夹
//和当前方法的作用完全相同 使用递归
show(zi.getAbsolutePath());
}
}
IO流:计算机数据传输的抽象
public class Demo03IO {
/*IO流:计算机数据传输的抽象
* 流是一组有序的,有起点和重点的字节集合,是对计算机中数据传输的总称或者抽象 即数据在两个设备间的传输称为流,流的本质是数据传输。
*
*IO流分类: i--in o--out
*按流传输方向分类: 参考对象是计算机内存
* 输入流:把源文件中的信息读到内存中
* ---父类:InputStream/Reader
* 输出流:把内存中的信息写到目的文件中
* ---父类:OutputStream/Writer
*按流操作的基本单位分类:
* 字节流:传输的基本单位是字节
* ----父类: InputStream/OutputStream
* 字符流:传输时把同一个字符对应的多个之间作为整体来传输
* ----父类: Reader/Writer
*按流关联的对象分类:
* 节点流:创建流时关联的是文件对象---毛坯房
* 过滤流/装饰流:创建流时关联的是其他流---精装房
*/
Stream 字节流
/*FileInputStream:字节输入流
* 构造方法:
* FileInputStream(File file)
FileInputStream(String name)
普通方法:
* void close() :关闭流释放资源
* int read() :每次读取一个字节 到达文件末尾返回-1
int read(byte[] b)
*FileOutputStream:字节输出流
* 构造方法:
* FileOutputStream(File file)
* FileOutputStream(String name)
FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)
普通方法:
void close() 关闭流 释放资源
void write(byte b) :一次写一个字节
void write(byte[] b, int off, int len) 一次写一个字节数组的一部分
void write(byte[] b) 一次写一个字节数组
* */
public class Demo01Stream {
public static void main(String[] args)throws Exception {
//实现文件的复制:把src/test/3.txt复制到4.txt中
//FileInputStream+FileOutputStream
//1 创建流与文件关联
FileInputStream fin=new FileInputStream("src\\test\\3.txt");//相对路径:相对的是当前项目
FileOutputStream fout=new FileOutputStream("src\\test\\5.txt",true);//fileoutputstream可以自动创建目的文件
//FileOutputStreamd的第二个参数指定是否支持续写
//2选择读写方式:逐个字节数组的读写
long lon1=System.currentTimeMillis();
// while(true){
// //定义一个字节数组来记录读取的信息
// byte[] arr=new byte[1024];
// int n=fin.read(arr);//读取最多arr.length个字节 装入arr中 返回值是本次读取的有效字节数 如果到达文件末尾 返回-1
// if(n==-1) {
// break;
// }
// fout.write(arr, 0, n);//把arr的前n个有效字节写出去
// }
byte[] arr=new byte[1024];//定义一个数组装读取的字节信息
int n;//定义一个变量记录每次读取的有效字节数
while((n=fin.read(arr))!=-1){
fout.write(arr, 0, n);
}
long lon2=System.currentTimeMillis();
System.out.println(lon2-lon1);
//3关闭流
fin.close();
fout.close();
}
private static void testStreamByByte() throws FileNotFoundException, IOException {
//实现文件的复制:把src/test/3.txt复制到4.txt中
//FileInputStream+FileOutputStream
//1 创建流与文件关联
FileInputStream fin=new FileInputStream("src\\test\\3.txt");//相对路径:相对的是当前项目
FileOutputStream fout=new FileOutputStream("src\\test\\4.txt");
//2选择读写方式:逐个字节的读写
long lon1=System.currentTimeMillis();
// while(true) {
// int b=fin.read();
// if(b==-1) {
// break;
// }
// fout.write(b);
// }
int b;//定义一个变量记录每次读取的字节信息
while((b=fin.read())!=-1) {//1:fin.read()读取一个字节 2:b=fin.read()把读取的字节赋值给变量b 3:判断变量b是否等于-1 等于-1到达文件末尾
fout.write(b);
}
long lon2=System.currentTimeMillis();
System.out.println(lon2-lon1);
//3关闭流
fin.close();
fout.close();
}
}
FileReader
public class Demo02FileReader {
/*
* FileReader:字符输入流 只能操作文本类型的文件
* 构造方法:
* FileReader(File file)
FileReader(String fileName)
普通方法:
* String getEncoding() :获取编码集
int read() :每次读取一个字符 如果到达文件末尾 返回-1
int read(char[] cbuf) :读取最多cbuf.length个字符装入cbuf中 返回值是本次读取的有效字符数 如果到达文件末尾 返回-1
void close() :关闭流释放资源
FileWriter:字符输出流
构造方法:
FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)
普通方法:
String getEncoding() :获取编码集
void close() :关闭流释放资源
void write(int c) :一次写一个字符
void write(char[] cbuf, int off, int len) :一次写一个字符数组的一部分
void write(String str, int off, int len) :一次写一个字符串的一部分
void write(String str) :一次写一个字符串
void write(char[] cbuf) :一次写一个字符数组
void flush() :刷新 :处理fileoutputstream 其他输出流都要flush
* */
public static void main(String[] args)throws Exception {
//1 创建流与文件关联
FileWriter fout=new FileWriter("src\\test\\6.txt");
System.out.println(fout.getEncoding());
//2 选择写方式
fout.write(98);//一次写一个字符
fout.flush();
fout.write(38999);
fout.flush();
fout.write("\r\n");
fout.flush();
fout.write("你好吗?");//一次写一个字符串
fout.flush();
fout.write("\r\n");
fout.write("abcdefghijk", 2, 4);//一次写一个字符串的一部分
char[] arr="1234567890".toCharArray();
fout.write(arr);//一次写一个字符数组
fout.write("\r\n");
fout.write(arr,3,3);//一次写一个字符数组
//3关闭流释放资源
fout.close();
}
private static void TestFileReader() throws FileNotFoundException, IOException {
//1 创建流与文件关联
FileReader fin=new FileReader("src\\test\\4.txt");
// //2 选择读的方式:逐个字符
// int b;
// while((b=fin.read())!=-1) {
// System.out.print((char)b);
// }
//2 选择读的方式:逐个字符数组
char[] arr=new char[1024];
int n;
while((n=fin.read(arr))!=-1) {
//把arr中读取的前n个有效字符写出去
System.out.print(new String(arr, 0, n));
}
//3关闭流
fin.close();
}
}
转换流InputStreamReader、OutputStreamWriter
public class Demo03 {
/*转换流:把字节流转换为字符流
* 根据编码表把字节转换为字符
*InputStreamReader:把字节输入流转换为字符输入流
*OutputStreamWriter:把字节输出流转换为字符输出流
*
*OutputStreamWriter:
* 构造方法:
* OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out, String charsetName)
普通方法:和FileWriter完全相同
void close()
void flush()
String getEncoding()
void write(char[] cbuf, int off, int len)
void write(char[] cbuf)
void write(int c)
void write(String str, int off, int len)
void write(String str)
*InputStreamReader:
*构造方法:
* InputStreamReader(InputStream in)
InputStreamReader(InputStream in, String charsetName)
普通方法:和FileReader完全相同
* void close()
String getEncoding()
int read()
int read(char[] cbuf, int offset, int length)
int read(char[] cbuf)
* */
public static void main(String[] args)throws Exception {
//test01();
//把键盘输入的字符分类写到不同的文件中:数字一个文件 字母一个文件 其他一个文件
//方法一:通过scanner每次读取一个字符串 逐个字符判断 写入到不同的输出流中
//方法二: 逐个字符判断 写入到不同的输出流中
InputStream in=System.in;//获取系统输入流
InputStreamReader reader=new InputStreamReader(in);//写入到不同的输出流中
//创建三个输出流 分别与三个目的文件关联
FileOutputStream szStream=new FileOutputStream("src/test/数字.txt");
FileOutputStream zmStream=new FileOutputStream("src/test/字母.txt");
FileOutputStream qtStream=new FileOutputStream("src/test/其他.txt");
//把字节输出流转换为字符输出流
OutputStreamWriter sz=new OutputStreamWriter(szStream);
OutputStreamWriter zm=new OutputStreamWriter(zmStream);
OutputStreamWriter qt=new OutputStreamWriter(qtStream);
//选择读的方式:逐个字符数组的读写
int b;//定义变量记录每次读取的有效字节数
char[] arr=new char[10];//定义字符书序记录每次读取字节信息
while(true) {//系统输入流没有末尾
b=reader.read(arr);
String message=new String(arr, 0, b);//把读取的信息转换为字符串
for (int i=0;i<b;i++) {
char c=arr[i];
if(Character.isDigit(c)) {
sz.write(c); sz.flush();
}else if(Character.isUpperCase(c)||Character.isLowerCase(c)) {
zm.write(c);zm.flush();
}else {
qt.write(c);qt.flush();
}
}
if(message.indexOf("~")!=-1) {//定义一个结束的标志
break;
}
//System.out.println("message="+message);
//System.out.println(message.length());
}
//关闭流
qt.close();sz.close();zm.close();
}
private static void test01() throws IOException {
//把键盘输入的字符分类写到不同的文件中:数字一个文件 字母一个文件 其他一个文件
//方法一:通过scanner每次读取一个字符串 逐个字符判断 写入到不同的输出流中
//方法二: 逐个字符判断 写入到不同的输出流中
InputStream in=System.in;//获取系统输入流
InputStreamReader reader=new InputStreamReader(in);//写入到不同的输出流中
//创建三个输出流 分别与三个目的文件关联
FileWriter sz=new FileWriter("src/test/数字.txt");
FileWriter zm=new FileWriter("src/test/字母.txt");
FileWriter qt=new FileWriter("src/test/其他.txt");
//选择读的方式:逐个字符的读写
int b;//定义变量记录每次读取的信息
while((b=reader.read())!=-1) {
if(Character.isDigit(b)) {
sz.write(b); sz.flush();
}else if(Character.isUpperCase(b)||Character.isLowerCase(b)) {
zm.write(b);zm.flush();
}else {
qt.write(b);qt.flush();
}
}
//关闭流
qt.close();sz.close();zm.close();
}
}
高效流(缓冲流) BufferedInputStream、 BufferedOutputStream
public class Demo04Buffered {
/*
* 高效流:输入装饰流;关联的是其他流
* 特点:高效
* 高效字节流:
* BufferedInputStream: 装饰流 对FileInputStream的封装:
* 除了效率更高 方法和FileInputStream完全相同
* BufferedOutputStream: 装饰流 对FileOutputStream的封装:
* 除了效率更高 方法和FileOutputStream完全相同
* 注意:BufferedOutputStream每读一次 需要flush一次
*
* 高效字符流:
* BufferedReader: 对FileReader的封装
* 方法和FileReader基本相同
* int read()
int read(char[] cbuf, int off, int len)
int read(char[] cbuf)
特有方法:
String readLine():一次读取一行 读到null到达文件末尾
* BufferedWriter:对FileWriter的封装
* 方法和FileWriter基本相同
* void close()
void flush()
void write(char[] cbuf, int off, int len)
void write(char[] cbuf)
void write(int c)
void write(String s, int off, int len)
void write(String s)
特有方法:
void newLine() :写一个行分隔符:等价于write("\r\n")
* */
文件复制
public static void main(String[] args)throws Exception {
//testBuffered1();
//使用字符高效流实现文件复制
//1创建节点流与文件关联
//2创建高效流与节点流关联
BufferedReader bin=new BufferedReader(new FileReader("src\\test\\4.txt"));
BufferedWriter bout=new BufferedWriter(new FileWriter("src\\test\\8.txt"));
//3 选择读写方式:逐个字符 逐个字符数组 逐个字符串 逐行
String line;//定义引用记录本行读取的信息
while((line=bin.readLine())!=null) {//readLine()读取的信息中没有换行字符
bout.write(line);
bout.flush();
bout.newLine();
bout.flush();
}
//4 关闭流
bin.close();
bout.close();
}
private static void testBuffered1() throws FileNotFoundException, IOException {
//使用字节高效流实现文件复制
//1 创建节点流与文件关联
FileInputStream fin=new FileInputStream("src\\test\\4.txt");
FileOutputStream fout=new FileOutputStream("src\\test\\7.txt");
//2 创建高效流与节点流关联
BufferedInputStream bin=new BufferedInputStream(fin);
BufferedOutputStream bout=new BufferedOutputStream(fout);
//3 选择读写方式:逐个字节读写 逐个字节数组读写
int n;
byte[] arr=new byte[1024];
while((n=bin.read(arr))!=-1) {
bout.write(arr, 0, n);
bout.flush();
}
//4 关闭流:只需要关闭装饰流即可
bin.close();
bout.close();
}
}
文件/文件夹 复制
public static void copy(File yuan,File muDiDir)throws Exception{
if(!muDiDir.exist()){
if(!muDiDir.mkdirs()){
throw new RuntimeException(muDiDir+"无法创建!");
}
}
File muDi=new File(muDiDir,yuan.getName());
if(yuan.isFile()){
//创建文件
muDi.createNewFile();
//把yuan中的内容复制到muDi中
//创建流与文件关联
BufferedInputStream bin=new BufferedInputStream(new FileInputStream(yuan));
BufferedOutputStream bout=new BufferedOutputStream(new FileOutputStream(muDi));
//选择读写方式
byte[] arr=new byte[1024]; int b;
while((b=bin.read(arr))!=-1){
bout.write(arr,0,b);
bout.flush();
}
//关闭流
bin.close();bout.close();
return;
}
//创建目的文件夹
muDi.mkdirs();
File[] zis=yuan.listFiles();
for(File zi:zis){
//把zi复制到muDi下
copy(zi,muDi);
}
}
PrintWriter:打印输出流
public class Demo05PrintWriter {
/*
* PrintWriter:打印输出流
* 特点1: 所有流都是成对的 但打印输出流不是
* 特点2:PrintWriter既可以是装饰流 也可以是节点流
* 特点3:可以保证数据的原始格式
*
*
* 特有方法:
* void print(boolean b)
* 其他方法和FileWriter完全相同
* */
public static void main(String[] args)throws Exception {
PrintWriter pw=new PrintWriter("src/test/9.txt");
FileWriter fw=new FileWriter("src/test/10.txt");
fw.write("舒适化123\r\n");
pw.write("舒适化123\r\n");
fw.write(true+"");
fw.write("\r\n");
pw.print(true);
pw.write("\r\n");
fw.write(98);//b
fw.write("\r\n");
pw.print(98);//98
pw.write("\r\n");//PrintWriter的print(n)等价于write(n+"")
pw.close();
fw.close();
}
}
序列化流、反序列化流
public class Demo07ObjectStream {
序列化流:把内存中对象的信息写到外部存储设备上
反序列化流:把外部存储设备上的信息读到内存中重构成对象
内存中对象的信息是字节形式存储
序列化流和反序列化流实现---实现内存中的对象持久存储到硬盘上
/*
*ObjectInputStream:
* Object readObject()
* ObjectInputStream(InputStream in)
*ObjectOutputStream:
* ObjectOutputStream(OutputStream out)
* void writeObject(Object obj)
*
*注意事项1: 序列化流和反序列化流的作用
* 2:序列化和反序列化操作的对象的类必须实现序列化接口Serializable
* 3:反序列化流ObjectInputStream的readObject方法读到文件末尾时 会抛出异常EOFException
*
*
*
* */
public static void main(String[] args)throws Exception {
// //java.io.NotSerializableException: com.zhiyou100.day15_thread.Student
ArrayList<Student> list=new ArrayList<>();
// for (int i = 0; i <10; i++) {
// list.add(new Student((int)(Math.random()*10+10),Math.random()>0.5?'男':'女',"韩梅"+i));
// }
// //把这10个学生对象的内存信息持久化保持到硬盘中d:\\stu.obj
// //创建一个序列化流与目的文件关联
// ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream("d:\\stu.obj"));
// //选择写方式:逐个对象的写
// for (Student s : list) {
// oo.writeObject(s);
// oo.flush();
// }
// oo.close();
//把硬盘中对象的信息读到内存中并重构成对象
//创建反序列化流与源文件关联
ObjectInputStream oi=new ObjectInputStream(new FileInputStream("d:\\stu.obj"));
//选择读的方式:逐个对象的读取
Object o;
while(true) {
try {
o=oi.readObject();//到达文件末尾 抛出异常EOFException
} catch (EOFException e) {
break;
}
System.out.println(o);
list.add((Student)o);
}
oi.close();
}
}
class Student implements Serializable{
int age;
char sex;
protected String name;
@Override
public String toString() {
return "Student [age=" + age + ", sex=" + sex + ", name=" + name + "]";
}
public Student() {
}
public Student(int age, char sex, String name) {
this.age = age;
this.sex = sex;
this.name = name;
}
}