25、IO流(上)
概述
IO流(Input Output)流
IO流用来设备间的数据传输
Java对数据的操作通过流的方式
Java操作流的对象都在IO包中
流按操作数据分为两种:
字节流和字符流
流按流向分为:
输入流和输出流
IO流常用基类:
字节流的抽象基类:InputStream OutputStream
字符流的抽象基类:Reader Writer
既然IO流是用于操作数据的,那么数据最常见的体现形式是,以操作文件为主来演示
需求:在硬盘上,创建一个文件,并写入一些文字数据
找到一个专门用于操作文件的Writer子类对象叫做FileWriter,后缀名是父类名。 前缀名是该流对象的功能。
步骤:
1、创建一个FileWriter对象,该对象一旦初始化就必须要明确操作的文件,而且该文件会被创建在指定目录下。如果该目录已有同名文件,将被覆盖,其实该步就是要明确数据存放目的地
2、调用write方法,将字符串写入到流中
3、刷新流对象中缓冲区的数据,将数据刷到目的地中
4、Close:关闭流资源,但是关闭之前会刷新一次,内部中的缓冲数据
5、Close和flush的区别:flush刷新后,流可以继续使用,close刷新后,流将关闭
package days11;
import java.io.*;
public class FileWriter1
{
public static void main(String[]args)throws IOException
{
FileWriter fw=new FileWriter("C:\\demo.txt");
fw.write("abcde");
fw.flush();
fw.write("你好IO!!!");
fw.flush();
fw.close();
}
}
package days11;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class IOEx
{
public static void main(String[]args) throws IOException
{FileWriter fw=null;
try
{
fw=new FileWriter("C:\\demo.txt");
fw.write("abcdefg");
}
catch(IOException e)
{
System.out.println(e.toString());
}
finally
{
fw.close();
}
}
}
文件的续写
package days11;
import java.io.*;
public class FileWriter2
{
public static void main(String[]args) throws IOException
{
FileWriter fw=new FileWriter("C:\\demo.txt",true);
fw.write(" haha");
fw.write("\r\nhaha");
fw.close();
}
}
FileWriter fw=new FileWriter("C:\\demo.txt",true);
传递一个true参数,代表不覆盖已有文件,并在已有文件的结尾处,进行数据续写
文件文本读取方式
package days11;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Filereader1
{
public static void main(String[]args) throws IOException
{
FileReader fr=new FileReader("C:\\demo.txt");
int ch=fr.read();
System.out.println("ch="+ch);
while(true)
{
int ch1=fr.read();
if(ch1==-1)
{
break;
}
System.out.print((char)ch1);
}
}
}
创建一个文本读取流对象,和指定名称的文件相关联,要保证该文件是否已经存在,如果不存在,会发生文本未找到异常
Read():一次读一个字符,而且会自动往下读。
package days11;
import java.io.*;
public class FileReader2
{
public static void main(String[]args)throws IOException
{
FileReader fr=new FileReader("C:\\demo.txt");
char[]buf=new char[3];
int num=fr.read(buf);
System.out.println("num="+num+"..."+new String(buf));
while((num=fr.read(buf))!=-1)
{
System.out.print(new String(buf,0,num));
}
fr.close();
}
}
通过字符数组进行读取
拷贝文本文件
将C盘的一个文本文件复制到D盘
复制的原理:将C盘的文件数据存储到D盘的一个文件中
步骤:1、在D盘创建一个文件,用于存储C盘文件的数据
2、定义读取流和C盘关联
3、通过不断读写完成数据存储
4、关闭资源
package days11;
import java.io.*;
public class RW
{
public static void main(String[]args) throws IOException
{
copy1();
copy2();
}
public static void copy1() throws IOException
{
FileReader fr=new FileReader("C:\\demo.txt");
FileWriter fw=new FileWriter("D:\\demo.txt");
int ch=0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
public static void copy2()throws IOException
{
FileWriter fw=null;
FileReader fr=null;
try
{
fw=new FileWriter("D:\\demo2.txt");
fr=new FileReader("C:\\demo.txt");
int len=0;
char[]buf=new char[1024];
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch(IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
fr.close();
fw.close();
}
}
}
BufferedWriter
字符流缓冲区
缓冲区的出现是为了提高流的操作效率
缓冲区的出现提高了对数据的读写率,所以在创建缓冲区之前,要先有流对象
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用
步骤:
1、创建一个流对象
2、只要将需要提高效率的流对象作为参数传递给缓冲区的构造函数即可
3、只要用到缓冲区,就要记得刷新
4、关闭缓冲区就是关闭缓冲区的流对象
package days13;
import java.io.*;
public class BufferedWriter1
{
public static void main(String[]args) throws IOException
{
FileWriter fw=new FileWriter("C:\\buf.txt");
BufferedWriter bufw=new BufferedWriter(fw);
bufw.write("abc\r\nde");
bufw.write("gogogo");
bufw.newLine();
for(int x=1;x<5;x++)
{
bufw.write("abcd"+x);
bufw.newLine();
bufw.flush();
}
}
}
BufferedReader
步骤:
1、创建一个读取流对象和文件相关联
2、为了提高效率,加入缓冲技术,将字符读取流对象作为参数,传递给缓冲对象的构造函数
3、该缓冲区提供了一个一次读一行的方法,readLine,方便于对文本数据的获取,当读到null时,表示读到文件末尾
package days13;
import java.io.*;
public class BufferedReader1
{
public static void main(String[]args) throws IOException
{
FileReader fr=new FileReader("C:\\buf.txt");
BufferedReader bufr=new BufferedReader(fr);
String line=null;
while((line=bufr.readLine())!=null)
{
System.out.println(line);
}
String s=bufr.readLine();
System.out.println("s="+s);
bufr.close();
}
}
通过缓冲区复制文本文件
package days11;
import java.io.*;
public class RW
{
public static void main(String[]args) throws IOException
{
copy1();
copy2();
}
public static void copy1() throws IOException
{
FileReader fr=new FileReader("C:\\paixu.java");
FileWriter fw=new FileWriter("D:\\demo.txt");
int ch=0;
while((ch=fr.read())!=-1)
{
fw.write(ch);
}
fw.close();
fr.close();
}
public static void copy2()throws IOException
{
FileWriter fw=null;
FileReader fr=null;
try
{
fw=new FileWriter("D:\\demo2.txt");
fr=new FileReader("C:\\demo.txt");
int len=0;
char[]buf=new char[1024];
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch(IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
fr.close();
fw.close();
}
}
}
readLine方法返回时只返回回车前的数据内容,并不返回回车符
readLine方法原理:无论是读一行,还是读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终使用的还是read方法一次读一个
MyBufferedReader
明白了BufferedReader类中的特有方法readLine原理后,可以自定义一个类中包含一个功能和readLine一致的方法,来模拟一下BufferedReader
package days13;
import java.io.*;
public class Mybuf
{
public static void main(String[]args) throws IOException
{
FileReader fr=new FileReader("C:\\buf.txt");
Mybuf buf=new Mybuf(fr);
String line=null;
while((line=buf.myreadLine())!=null)
{
System.out.println(line);
}
fr.close();
}
private FileReader r;
Mybuf(FileReader r)
{
this.r=r;
}
public String myreadLine()throws IOException
{
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
}
31、装饰设计模式
装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的对象,并提供加强的功能,那么自定义的类成为装饰类。装饰类通常通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
package days13;
public class Zhuangshi
{
public static void main(String[]args)
{
Person p=new Person();
superPerson p1=new superPerson(p);
p1.superchifan();
}
}
class Person
{
public void chifan()
{
System.out.println("吃饭");
}
}
class superPerson
{
private Person p;
superPerson(Person p)
{
this.p=p;
}
public void superchifan()
{
p.chifan();
System.out.println("喝汤");
}
}
装饰和继承的区别
装饰模式比继承要灵活,避免了继承体系的臃肿,而且降低了类与类之间的关系,装饰类因为增强它已有的对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰类通常都属于一个体系中
32、IO流(下)
LineNumberReader
package days13;
import java.io.*;
public class Linenum
{
public static void main(String[]args)throws IOException
{
FileReader fr=new FileReader("C:\\paixu.java");
LineNumberReader lnr=new LineNumberReader(fr);
String line=null;
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+line);
}
}
}
MyLineNumberReader
package days13;
import java.io.*;
class MyBufferedReader extends Reader
{
private Reader r;
MyBufferedReader(Reader r)
{
this.r = r;
}
//可以一次读一行数据的方法。
public String myReadLine()throws IOException
{
//定义一个临时容器。原BufferReader封装的是字符数组。
//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
/*
覆盖Reader类中的抽象方法。
*/
public int read(char[] cbuf, int off, int len) throws IOException
{
return r.read(cbuf,off,len) ;
}
public void close()throws IOException
{
r.close();
}
public void myClose()throws IOException
{
r.close();
}
}
class MyLineNumberReader extends MyBufferedReader
{
private int lineNumber;
MyLineNumberReader(Reader r)
{
super(r);
}
public String myReadLine()throws IOException
{
lineNumber++;
return super.myReadLine();
}
public void setLineNumber(int lineNumber)
{
this.lineNumber = lineNumber;
}
public int getLineNumber()
{
return lineNumber;
}
}
class MyLineNumberReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("copyTextByBuf.java");
MyLineNumberReader mylnr = new MyLineNumberReader(fr);
String line = null;
mylnr.setLineNumber(100);
while((line=mylnr.myReadLine())!=null)
{
System.out.println(mylnr.getLineNumber()+"::"+line);
}
mylnr.myClose();
}
}
字节流File读写操作
需求:想要操作图片数据,这时要用到字节流
1、用字节流读取流对象和图片关联
2、用字节写入流对象,创建一个图片文件,用于存储获取到的图片数据
3、通过循环读写,完成数据存储
4、关闭资源
package days13;
import java.io.*;
public class Copypic
{
public static void main(String[]args) throws IOException
{
FileInputStream fis=null;
FileOutputStream fos=null;
try
{
fos=new FileOutputStream("C:\\2.jpg");
fis=new FileInputStream("C:\\1.jpg");
byte[] by=new byte[1024];
int len=0;
while((len=fis.read(by))!=-1)
{
fos.write(by,0,len);
}
}
catch(IOException e)
{
throw new RuntimeException("失败");
}
finally
{
fis.close();
fos.close();
}
}
}
字节流的缓冲区
package days14;
import java.io.*;
public class MP
{
public static void main(String[]args) throws IOException
{
long start=System.currentTimeMillis();
copy();
long end=System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
public static void copy() throws IOException
{
BufferedInputStream bufrs=new BufferedInputStream(new FileInputStream("C:\\1.doc"));
BufferedOutputStream bufro=new BufferedOutputStream(new FileOutputStream("C:\\2.doc"));
byte[]by=new byte[1024];
int ch=0;
while((ch=bufrs.read(by))!=-1)
{
bufro.write(by);
}
bufrs.close();
bufro.close();
}
}
自定义字节流缓冲区read和write的特点
import java.io.*;
class MyBufferedInputStream
{
private InputStream in;
private byte[] buf = new byte[1024*4];
private int pos = 0,count = 0;
MyBufferedInputStream(InputStream in)
{
this.in = in;
}
//一次读一个字节,从缓冲区(字节数组)获取。
public int myRead()throws IOException
{
//通过in对象读取硬盘上数据,并存储buf中。
if(count==0)
{
count = in.read(buf);
if(count<0)
return -1;
pos = 0;
byte b = buf[pos];
count--;
pos++;
return b&255;
}
else if(count>0)
{
byte b = buf[pos];
count--;
pos++;
return b&0xff;
}
return -1;
}
public void myClose()throws IOException
{
in.close();
}
}
/*
11111111-111111110000000000101001001010100101010010101001010
byte: -1 ---> int : -1;
00000000 00000000 00000000 11111111 255
11111111 11111111 11111111 11111111
11111111 -->提升了一个int类型 那不还是-1吗?是-1的原因是因为在8个1前面补的是1导致的。
那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。
怎么补0呢?
11111111 11111111 11111111 11111111
&00000000 00000000 00000000 11111111
------------------------------------
00000000 00000000 00000000 11111111
0000-0001
1111-1110
000000001
1111-1111 -1
结论:
字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。
因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.
那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。
所以,为了避免这种情况将读到的字节进行int类型的提升。
并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。
而在写入数据时,只写该int类型数据的最低8位。
*/
读取键盘录入
System.in:对应 标准输入设备:键盘
System.out:对应标准输出设备,控制台
通过键盘导入数据,当录入一行数据后,就将该行数据进行打印。如果录入的数据时over,那么停止录入
package days14;
import java.io.*;
public class ReadIn
{
public static void main(String[]args) throws IOException
{
//read1();
read2();
}
public static void read1()throws IOException
{
InputStream in=System.in;
int ch=0;
while((ch=in.read())!=-1)
{
System.out.println(ch);
}
}
public static void read2()throws IOException
{
InputStream in=System.in;
StringBuilder sb=new StringBuilder();
while(true)
{
int ch=in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String s=sb.toString();
System.out.println(s);
sb.delete(0, sb.length());
if(s.equals("over"))
{
break;
}
}
else
sb.append((char)ch);
}
}
}
读取转换流
通过刚才的键盘录入一行数据并打印,发现其实就是读一行数据原理,也就是readLine方法,
能不能直接使用readLine方法直接来完成键盘录入一行数据的读取呢
readLine方法是BufferedReader类中的方法,而键盘录入的read方法是InputStream的方法
那么能不能将字节流转成字符流再使用字符流缓冲区的readLine方法呢
package days14;
import java.io.*;
public class TranStr
{
public static void main(String[]args) throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line=null;
while((line=bufr.readLine())!=null)
{
if(line.equals("over"))
break;
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
}
流操作规律
需求:想把键盘录入的数据存储到一个文件中
源:键盘
目的:文件
变化的部分:
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(FileOutputStream(""1.txt))));
需求:想要将一个文件的数据打印在控制台上
源:文件
目的:控制台
变化的部分
BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("1.txt")));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
最痛苦的是流对象有很多,不知道该选用哪一个?
通过两个明确来完成
1、明确源和目的
源:输入流
目的:输出流
2、操作的数据是否是纯文本
输入流:InputStream Reader 是纯文本:字符流
输出流:OutputStream Writer 不是纯文本:字节流
当体系明确后,再明确要使用哪个具体的对象
通过对设备进行区分:
源设备:内存、硬盘、键盘
目的设备:内存、硬盘、控制台
将一个文本文件中的数据存储到另一个文件中——复制文件
源:InputStream,Reader(因为是源所以使用读取流)
是不是操作纯文本文件:是,这时候选择Reader
接下来明确对象:明确设备,硬盘,Reader体系中可以操作的文件对象是FileReader
FileReader fr=new FileReader("a.txt");
是否需要提高效率:是,加入Reader体系中的缓冲区BufferedReader
BufferedReader bufr=new BufferedReader(fr);
目的:OutputStream Writer
是否是纯文本:是,Writer
明确设备:硬盘,一个文件
Writer体系中可以操作的文件对象时FileWriter
FileWriter fw=new FileWriter("b.txt");
是否需要提高效率:是
加入Writer体系中的缓冲区:BufferedWriter
BufferedWriter bufw=new BufferedWriter(fw);
将键盘导入数据,保存到一个文件中
这个需求源和目的都存在,那么分别分析
源:InputStream、Reader
是不是纯文本:是!Reader
设备:键盘,对应的对象是System.in
不是选择Reader吗?System.in不是对应的字节流吗?
为了操作键盘的文本数据方便,转换成字符流,按照字符串操作时最方便的,所以既然明确了Reader,那么就将System.in转换成Reader,用了Reader体系中的转换流:InputStreamReader
InputStream Reader isr=new InputStreamReader(System.in)
需要提高效率吗?
是!BufferedReader
BufferedReader bufr=new BufferedReader(isr);
目的:OutputStream Writer
是否是纯文本:是!Writer
设备:键盘,一个文件使用,FileWriter
FileWriter fw=new FileWriter("c.txt");
需要提高工作效率吗?
需要,BufferedWriter
BufferedWriter bufw=new BufferedWriter(fw);
练习代码:
package days14;
import java.io.*;
public class Test1
{
public static void main(String[]args) throws IOException
{
//copy_1();
//copy_2();
copy_3();
}
public static void copy_1() throws IOException
{
BufferedWriter bufw=new BufferedWriter(new FileWriter("C:\\dy.txt"));
BufferedReader bufr=new BufferedReader(new FileReader("C:\\pai.java"));
String len=null;
while((len=bufr.readLine())!=null)
{
bufw.write(len);
bufw.newLine();
bufw.flush();
System.out.println(len);
}
bufr.close();
bufw.close();
}
public static void copy_2() throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new FileWriter("C:\\text.txt"));
String len=null;
while((len=bufr.readLine())!=null)
{
bufw.write(len);
bufw.flush();
bufw.newLine();
System.out.println(len);
}
bufw.close();
bufr.close();
}
public static void copy_3()throws IOException
{
FileInputStream fis=new FileInputStream("C:\\1.jpg");
FileOutputStream fos=new FileOutputStream("C:\\5.jpg");
int len=0;
while((len=fis.read())!=-1)
{
fos.write(len);
fos.flush();
System.out.print((char)len);
}
fos.close();
fis.close();
}
}
想要把录入的数据按照指定的编码表,将数据存到文件中
目的:OutStream、Writer
是否是纯文本?
是 Writer
设备:硬盘,一个文件,使用FileWriter
但是存储的时候需要加入指定的编码表,而指定的编码表示有转换流可以指定
所以要使用的是对象是OutputStreamWriter
所以转换流对象要接收一个字节输出流 FileoutputStream
本想用FileWriter,但是它使用的是默认编码表:GBK
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("d.txt","UTF-8"));
需要高效吗?需要
BufferedWriter bufw=new BufferedWriter(osw);
所以记住转换流什么时候使用,字符和字节之间的桥梁,通常涉及到:字符编码转换流
练习代码:
package days14;
import java.io.*;
public class Trans
{
public static void main(String[]args) throws IOException
{
//show_1();
show_2();
}
public static void show_1()throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter((new FileOutputStream("C:\\dy.txt")),"UTF-8"));
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
bufw.close();
bufr.close();
}
public static void show_2()throws IOException
{
BufferedReader bfr=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\1.jpg")));
BufferedWriter bfw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\demo.txt"),"UTF-8"));
String len=null;
while((len=bfr.readLine())!=null)
{
bfw.write(len);
bfw.newLine();
bfw.flush();
}
bfw.close();
bfr.close();
}
}
改变标准输入输出设备
System.setIn(new FileInputStream("PersonDemo.java"));
System.setOut(new PrintStream("zzz.txt"));
异常的日志信息
package days14;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExInfo
{
public static void main(String[]args) throws Exception
{
try
{
int[]arr=new int[2];
System.out.println(arr[3]);
}
catch(Exception e)
{
try
{
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s = sdf.format(d);
PrintStream ps = new PrintStream("C:\\123.log");
ps.println(s);
System.setOut(ps);
}
catch(IOException ex)
{
throw new RuntimeException("日志创建失败!!!");
}
e.printStackTrace(System.out);
}
}
}
系统信息
package days14;
import java.io.*;
import java.util.Properties;
public class Syst
{
public static void main(String[]args) throws FileNotFoundException
{
Properties prop=System.getProperties();
prop.list(new PrintStream("C:\\demo.txt"));
}
}
34、File类
用来将文件或文件夹封装成对象,方便对文件或文件夹进行修改。File对象可以作为参数传递给流的构造函数。
package days15;
import java.io.*;
public class File1
{
public static void main(String[]args)
{
File f1 = new File("a.txt");
//
File f2 = new File("c:\\abc","b.txt");
File d = new File("c:\\abc");
File f3 = new File(d,"c.txt");
sop("f1:"+f1);
sop("f2:"+f2);
sop("f3:"+f3);
File f4 = new File("c:"+File.separator+"abc"+File.separator+"zzz"+File.separator+"a.txt");
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。和输出流不一样,输出流对象一建立创建文件。而且文件已经存在,会覆盖。
boolean mkdir():创建文件夹。
boolean mkdirs():创建多级文件夹。
2,删除。
boolean delete():删除失败返回false。如果文件正在被使用,则删除不了返回falsel。
void deleteOnExit();在程序退出时删除指定文件。
3,判断。
boolean exists() :文件是否存在.
isFile():
isDirectory();
isHidden();
isAbsolute();
4,获取信息。
getName():
getPath():
getParent():
getAbsolutePath()
long lastModified()
long length()
package days15;
import java.io.*;
public class File2
{
public static void main(String[]args) throws IOException
{
File f=new File("C:\\demo.txt");
sop("creat:"+f.createNewFile());
sop("delete:"+f.delete());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
判断
package days15;
import java.io.*;
public class File3
{
public static void main(String[]args)
{
File f=new File("C:\\demo2.txt");
sop("exists:"+f.exists());
sop("execute:"+f.canExecute());
File dir=new File("C:\\abcf");
sop("mkdir:"+dir.mkdir());
File dir2=new File("C:\\abcf\\kkk");
sop("mkdirs:"+dir2.mkdirs());
sop("dir:"+f.isDirectory());
sop("file:"+f.isFile());
sop(f.isAbsolute());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
记住在判断文件对象是否是文件或者目的时,必须要判断该文件对象封装的内容是否存在,通过exists判断
获取信息
package days15;
import java.io.*;
public class File5
{
public static void main(String[]args)
{
File f=new File("C:\\demo2.txt");
sop("path:"+f.getPath());
sop("abspath:"+f.getAbsolutePath());
sop("parent:"+f.getParent());
File f1=new File("C:\\dy.txt");
File f2=new File("C:\\fos2.txt");
sop("rename:"+f.renameTo(f2));
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
File对象功能——文件列表
package days15;
import java.io.*;
public class File6
{
public static void main(String[]args)
{
File[]files=File.listRoots();
for(File f:files)
{
System.out.println(f);
}
list();
}
public static void list()
{
File f=new File("C:\\");
String[]names=f.list();
for (String name:names)
{
System.out.println(name);
}
}
}
调用list方法,list对象必须是封装了一个目录,该目录还必须存在
File对象功能——文件列表2
package days15;
import java.io.*;
public class File7
{
public static void main(String[]args)
{
File f=new File("C:\\");
String[]names=f.list();
String []st=new String[names.length];
int n=0;
for(int i = 0;i<names.length;i++)
{
if(!names[i].endsWith(".jpg"))
continue;
st[n]=names[i];
n++;
}
for(int i=0;i<n;i++)
{
System.out.println(st[i]);
}
}
}
列出目录下所有内容
package days15;
import java.io.*;
public class File8
{
public static void main(String[]args)
{
File dir=new File("D:\\");
show(dir);
}
public static void show(File dir)
{
File[]files=dir.listFiles();
for(int i=0;i<files.length;i++)
{
if(files[i].isDirectory())
{
show(files[i]);
}
else
{
System.out.println(files[i]);
}
}
}
}
因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可,在列出过程中出现的还是目录的话,,只要使用同一个列出目录功能的函数完成即可,在列出过程中出现的还是目录的话,可以再次调用本功能,也就是函数自身调用自身
这种表现形式或者编程手法,称作递归
递归应注意:
1、限定条件
2、要注意递归的次数,尽量避免内存溢出
文件相关知识综合
package days15;
import java.io.*;
import java.util.Scanner;
public class Remove
{
public static void main(String[]args) throws IOException
{
System.out.println("请输入要操作的路径:");
Scanner scr=new Scanner(System.in);
String str=scr.next();
File dir=new File(str);//指定文件路径
System.out.println(" 1、指定范围文件遍历 2、删除包含该关键字的文件 3、删除以该关键字结尾的文件 4、查找包含该关键字的文件 5、查找以该关键字结尾的文件");
int x=scr.nextInt();
String msg=null;
if(x!=1)
{
msg=imp();
}
long start=System.currentTimeMillis();
int y=basic(dir,x,msg);
if((y==4)||(y==5))
{
open(dir);
}
long end=System.currentTimeMillis();
long time=end-start;
if(time<=10000)
System.out.println("本次执行共花费"+time+"毫秒");
else
if(time>10000&&time<=100000)
System.out.println("本次执行共花费"+time/1000+"秒");
else
System.out.println("本次执行共花费"+time/60000+"分钟");
}
//1、文件遍历 2、删除包含该关键字 3、删除以该关键字结尾 4、查找包含该关键字 5、查找以该关键字结尾
public static int basic(File dir,int x,String msg) throws IOException
{
File[]files=dir.listFiles();
for(int i=0;i<files.length;i++)
{
if(files[i].isDirectory())
basic(files[i],x,msg);
else
switch(x)
{
case 1:System.out.println(files[i]);break;
case 2:delete_1(files[i],msg);break;
case 3:delete_2(files[i],msg);break;
case 4:find_1(files[i],msg);break;
case 5:find_2(files[i],msg);break;
}
}
return x;
}
public static void delete_1(File dir,String msg) throws IOException//2号功能
{
if(dir.toString().contains(msg))//获取文件名,包含关键字的删除
{
System.out.println(dir+"---------------删除成功");
dir.delete();
}
}
public static void delete_2(File dir,String msg) throws IOException //3号功能
{
if(dir.toString().endsWith(msg))//获取文件名,以该关键字结尾的删除
{
System.out.println(dir+"-----------------删除成功");
dir.delete();
}
}
public static String[] find_1(File dir,String msg) throws IOException//4号功能
{
String[]str=new String[5000];
int i=0;
if(dir.toString().contains(msg))//获取文件名,包含关键字的查找
{
System.out.println(dir+"------------查找成功");
str[i]=dir.toString();
i++;
}
return str;
}
public static String[] find_2(File dir,String msg) throws IOException//5号功能
{
String[]str=new String[5000];
int i=0;
String strs=imp();
if(dir.toString().endsWith(msg))//获取文件名,包含关键字的查找
{
System.out.println(dir+"---------------查找成功");
str[i]=dir.toString();
i++;
}
return str;
}
public static void open(File f) throws IOException //打开程序
{
Runtime r=Runtime.getRuntime();
r.exec("cmd /k start D:\\");//打开程序
}
public static String imp() throws IOException
{
System.out.println("请输入关键字信息:"); //关键字
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
return str;
}
}