第七天Java基础(File、递归、IO流)
1. File类
创建文件、删除文件、获取文件、判断文件、文件遍历、文件大小
file:文件、directory:文件夹/目录、path:路径
1.1 与系统相关的符号
Linux系统和window系统的系统符号不同,所以路径不能写死
1.String a = File.pathSeparator;//分号分隔符
Char a = File.pathSeparatorChar;//
2.String b = File.separator;//正或反斜杠分隔符
Char b = File.separatorChar;//
1.2 绝对路径和相对路径
1.3 File类的构造方法
1.带一个参数的构造方法
File one = new File(String str);//路径
2.带两个参数的构造方法
File one = new File(String fu,String zi);//父子路径拼接
File one = new File(File fu,String zi);//还是父子路径拼接,父类型为File
1.4 File类常用的方法
1.获取的方法
getAbsolutePath();//返回绝对路径不分绝对相对
getPath();//返回路径串,分绝对相对
getName();//文件名或目录名称,
length();//文件长度
2.判断的方法
exists();//判断路径是否存在
isDirectory();//判断路径是否为目录
isFile();//路径是否为文件
3.创建与删除文件
createNewFile();//文件不存在时,创建文件
delete();//删除文件或目录
mkdir();//创建单级文件夹
mkdirs();//创建多级文件夹
1.5 遍历文件夹或目录
file.list();//遍历文件夹中的文件或文件夹,返回String数组
flie.listFiles();//返回的是File类型的数组,把目录中的文件或者文件夹封装为File
2. 递归
1.练习:1加到n的和
public static int sum(int n){
if(n == 1 ){
return 1;
}
return n+sum(n-1);
}
2.练习:递归遍历File
//1.结束条件 f 不是文件夹时不在递归
//2.目的 获取下一个文件夹
public static void gerFileAll(File file){
System.out.println(file.getName());
File[] files = file.listFiles();//获取该路径下的文件或文件夹
for (File f : files) {
if(f.isDirectory()){//如果遍历出来的File中有文件夹
gerFileAll(f);
}
System.out.println(f.getName());
}
}
3.练习:搜索文件
public static void gerFileAll(File file){
File[] files = file.listFiles();
for (File f : files) {
if(f.isDirectory()){
gerFileAll(f);
}else{
String name = f.getName();
boolean b = name.endsWith(".java");//判断是否为.java结尾
if (b){
System.out.println(f.getName());
}
}
}
}
3. 文件过滤器(FileFilter)
1.两种方式
//使用file.listFiles(new FileFilter() {}
public static void gerFileAll(File file){
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if(pathname.isDirectory()){
return true;
}
return pathname.toString().endsWith(".java");
}
});
for (File f : files) {
if(f.isDirectory()){
gerFileAll(f);
}else{
// String name = f.getName();
// boolean b = name.endsWith(".java");//判断是否为.java结尾
// if (b){
// System.out.println(f.getName());
// }
System.out.println(f);
}
}
}
//使用file.listFiles(new FilenameFilter() {
public static void gerFileAll(File file){
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File pathname ,String name) {
return new File(pathname,name).isDirectory()|| name.endsWith(".java");
}
});
for (File f : files) {
if(f.isDirectory()){
gerFileAll(f);
}else{
// String name = f.getName();
// boolean b = name.endsWith(".java");//判断是否为.java结尾
// if (b){
// System.out.println(f.getName());
// }
System.out.println(f);
}
}
}
//简化后的代码
//1.
File[] files = file.listFiles((File pathname ,String name) -> new File(pathname,name).isDirectory()|| name.endsWith(".java"));
//2.
File[] files = file.listFiles((File pathname) -> {
if(pathname.isDirectory()){
return true;
}
return pathname.toString().endsWith(".java");
});
4. IO流
4.1四个顶层的父类(InputStream、OutputStream、Reader、Writer)
1.OutputStream类
抽象类、所有
方法:
close();关闭流
flush();
write(byte[]);
子类:
FileOutputStream,把内存中的数据写入到硬盘当中
FileOutputStream(String name);
FileOutputStream(File file);
FileOutputStream(String name,boolean append);//append为追加标识
FileOutputStream(File file,boolean append);//覆盖还是续写
写入数据的目的地,文件路径
构造方法的作用:
创建对象,根据路径创建文件,指向创建好的文件
使用方式:
FileOutputStream fs = new FileOutputStream("D:\\word\\a.txt",true);//追加标识
byte[] b = "你好".getBytes();
fs.write(b);
fs.write("\r\n".getBytes());//换行
fs.write(b);
fs.close();
2.InputStream类
子类:
FileInputStream,把硬盘中的数据读取到内存中
使用方式:
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\word\\a.txt");
int read = 0;
while((read = fis.read())!=-1){
System.out.println((char)read);
}
fis.close();
}
3.把byte[]转化为String
String的构造方法中提供了该功能
new String(byte[] b);
new String(byte[] b,int offset,int length);
4.读流的控制:
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("D:\\word\\a.txt");
int read = 0;
byte []b = new byte[2];//每次读取的长度
while((read = fis.read(b))!=-1){//把长度作为参数传递给read(b)中
//结果存在b当中,0代表起始位置,read代表有效字节个数
System.out.println(new String(b,0,read));
}
fis.close();
}
5.练习文件复制
public static void main(String[] args) throws IOException {
long l = System.currentTimeMillis();
//读流
FileInputStream fis = new FileInputStream("D:\\word\\a\\001.mp3");
//写流
FileOutputStream fos = new FileOutputStream("D:\\word\\b\\001.mp3");
byte []b = new byte[1024];
int coun = 0;
while((coun=fis.read(b))!=-1){
//写流
fos.write(b);
}
fis.close();
fos.close();
long l1 = System.currentTimeMillis();
System.out.println("共耗时:"+(l1-l));
}
6.字符输入流(Reader)主要解决字节流乱码的麻烦
字符输入流的顶层父类
抽象类
方法:
read();//读取单个字符
read(char[] c);//读取多个字符
close();//关闭流
子类:
FileReader
构造方法:
FileReader(String fileName);//
FileReader(File file);//
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:\\word\\a\\a.txt");
int len = 0;
char[]chars = new char[1024];
while((len = reader.read(chars))!=-1){
System.out.print(new String(chars,0,len));
}
}
7.字符输出流(Writer)
写的时候时写入到缓存中,在缓存中完成字节转换。
public static void main(String[] args) throws IOException {
File file = new File("D:\\word\\a\\b.txt");
file.createNewFile();//创建文件
FileWriter fw = new FileWriter(file);
fw.write("你好吗!");//写入到缓存中
fw.flush();//从缓存中写入到磁盘中
fw.close();//关闭流
}
write的四种参数
9.流的异常处理方式
try{
//可能会出现的异常代码块
}catch(...){...}finally{
//资源释放
}
10.jdk1.7后的特性try(){}
把字符流对象的定义在try()的小括号中
public static void main(String[] args) {
try(
FileInputStream fis = new FileInputStream("");
FileOutputStream fos = new FileOutputStream("");
){
int lan = 0;
byte b[] = new byte[2];
while((lan = fis.read(b))!=-1){
fos.write(b);
}
}catch(IOException e){
System.out.println(e.toString());
}
}
5. Properties集合
唯一和IO流结合的集合
可以保存在流中或加载在流中
extend Hashtable集合
键值对默认都是字符串
将集合写入到磁盘中
public static void main(String[] args) throws IOException {
Properties pp = new Properties();
pp.setProperty("赵丽颖","十八");
pp.setProperty("迪丽热巴","二八");
pp.setProperty("古力娜扎","三八");
Set<String> strings = pp.stringPropertyNames();
for (String string : strings) {
String property = pp.getProperty(string);
System.out.println(string+":"+property);
}
FileWriter fw = new FileWriter("D:\\word\\a\\c.txt");
pp.store(fw,"注释");//将字符流写入到磁盘中
fw.close();
}
把集合从磁盘中读取出来
public static void main(String[] args) throws IOException {
Properties pp = new Properties();
FileReader fw = new FileReader("D:\\word\\a\\c.txt");
pp.load(fw);
Set<String> strings = pp.stringPropertyNames();
for (String string : strings) {
String property = pp.getProperty(string);
System.out.println(property);
}
fw.close();
}
6. 缓冲流
1.BufferedInputStream类
2.BufferedOutputStream类
3.BufferedWriter类,该类有个独有的方法newLine()表示换行bw.newLine()
等效于bw.write("\r\n");
4.BufferedReader类,该类独有的方法readLine()表示读取一行数据。
四种缓存流的用法类似,下面举一例
public static String PATH = "D:\\word\\a\\001.mp3";
public static String PATH02 = "D:\\word\\b\\001.mp3";
public static void main(String[] args) throws IOException {
long out = System.currentTimeMillis();
FileInputStream fis = new FileInputStream(PATH);
FileOutputStream fos = new FileOutputStream(PATH02);
BufferedOutputStream bos = new BufferedOutputStream(fos);
BufferedInputStream bis = new BufferedInputStream(fis);
int len = 0;
byte[]bytes = new byte[1024];
while((len = bis.read(bytes))!= -1){
bos.write(bytes);
}
bos.close();
bis.close();
long ne = System.currentTimeMillis();
System.out.println(ne-out);
}
7.练习
public static void main(String[] args) throws IOException {
HashMap<String,String> map = new HashMap<>();
BufferedReader br = new BufferedReader(new FileReader("D:\\word\\a\\a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\word\\b\\b.txt"));
String line = null;
while((line = br.readLine())!=null){
if(line!=null&&!"".equals(line)){//排除空格和换行
String[] split = line.split("\\.");
map.put(split[0],split[1]);
}
}
Set<String> strings = map.keySet();
for (String string : strings) {
String s = map.get(string);
bw.write(string+"."+s);
bw.newLine();
}
br.close();
bw.close();
}
7. 转化流
1.OutputStreamWriter类
继承了Writer
写流
把字符转化为字节
可以设置编码格式
构造方法
OutputStreamWriter(OutputStream out);//默认编码
OutputStreamWriter(OutputStream out,String charsetName);//charsetName编码名称
使用方法和BuffOutputStream差不多
2.InputStreamWriter类
3.小练习字符编码转换
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\word\\a\\gbk.txt"),"GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\word\\a\\UTF8.txt"),"UTF-8");
int len = 0;
char[] chars = new char[2];
while((len = isr.read(chars))!=-1){
osw.write(chars);
}
isr.close();
osw.close();
}
8. 序列化流(保存对象的流)
1.ObjectInputStream
需要反序列化的类必须实现Serializable,才能进行序反列化
public static void main(String[] args) throws IOException, ClassNotFoundException {
File file = new File("D:\\word\\c\\d");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file+"\\a.txt"));
Porter porter = (Porter) ois.readObject();
System.out.println(porter.getName()+":"+porter.getAge());
ois.close();
}
2.ObjectOutputStream
需要序列化的类必须实现Serializable,才能进行序列化
public class Porter implements Serializable {
private static final long serialVersionUID = 1L;//自定义的序列号
private String name;
private Integer age;
public Porter(){
写流
public static void main(String[] args) throws IOException{
File file = new File("D:\\word\\c\\d");
file.mkdirs();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file.getAbsoluteFile()+"\\a.txt"));
Porter porter = new Porter("我的", 15);
oos.writeObject(porter);
oos.close();
}
3.关键字( transient 、static)
当成员变量不想被序列化,可以用transient修饰,变量值不会被保存,和静态的static效果一样,但是没有静态的含义
4.使用数组保存对象进行序列化
public static void main(String[] args) throws IOException, ClassNotFoundException {
ArrayList<Porter> list = new ArrayList<>();
File file = new File("D:\\word\\c\\d");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file+"\\a.txt"));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file+"\\a.txt"));
list.add(new Porter("A",15));
list.add(new Porter("B",16));
list.add(new Porter("C",17));
oos.writeObject(list);
oos.close();
Object o = ois.readObject();
ArrayList<Porter> list2 = (ArrayList<Porter>) o;
for (Porter porter : list2) {
System.out.println(porter.toString());
}
ois.close();
}
9. 打印流(PrintStream)
1.PrintStream,只打印,不抛异常,特有的方法print()、println(),输出任意类型的值。
2.构造方法:
PrintStream(File file);//输出目的地File
PrintStream(OutputStream out);//输出目的地OutputStream
PrintStream(String fileName);//输出目的地
public static void main(String[] args) throws FileNotFoundException {
File file = new File("D:\\word\\c\\d");
PrintStream ps = new PrintStream(file+"\\a.txt");
ps.write(88);
ps.close();
}