1.File类
File类被定义为“文件和目录路径名的抽象表示形式”,这是因为File类既可以表示“文件”也可以表示“目录”,他们都通过对应的路径来描述。通过构造函数创建一个File类对象,则该对象就是指定文件的引用,可以通过该对象对文件操作。通过File对象,可以获取文件的属性值(文件大小,能否读写,最后修改时间等)。File对象不能对文件进行读取和写入的操作,如果想要对文件进行读写,那么要使用IO流。
以下函数是File类使用示例。它的功能是,将一个文件的路径传入函数,函数判断此路径是否有文件,如果此路径没有指向任何文件或目录,那么判断这个路径里是否有".",如果有,那么创建这个路径的文件,如果没有,创建这个目录。如果有文件,则判断此路径是文件还是目录,如果是文件,则显示它的一系列属性,如果是目录,那么后续用递归的方式显示它及其子目录下的文件。文件路径有两种表示方法,一种是绝对路径,一种是相对路径。绝对路径是带盘符的,相对路径是相对于当前目录的路径。
1 public void testFile(String path){ 2 File file = new File(path); 3 if(file.exists()){ 4 //如果文件存在,再获取属性值 5 //TODO:获取文件大小 6 if(file.isFile()){ 7 System.out.println("文件大小"+file.length()); 8 9 //TODO:文件是否可读,可写 10 System.out.println("是否能写:"+file.canWrite()); 11 System.out.println("是否可读:"+file.canRead()); 12 //TODO:获取最后修改时间 13 //Date date = new Date(); 14 SimpleDateFormat sfm = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 15 String str = sfm.format(file.lastModified()); 16 System.out.println("文件最后修改时间:"+str); 17 18 } 19 else if(file.isDirectory()){ 20 System.out.println("sdfsf"); 21 this.listFiles(file); 22 //这个函数递归列出所有子目录及文件,在后续会有提及 23 } 24 }else{ 25 System.out.println("文件不存在"+path); 26 if(path.contains(".")){ 27 try { 28 //创建文件 29 file.createNewFile(); 30 } catch (IOException e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 } 34 }else{ 35 36 //创建目录:file.mkdir(); 创建单目录 37 //file.mkdirs();循环创建目录,没有的话可以创建上层目录 38 file.mkdirs(); 39 } 40 } 41 }
以下是递归调用listFiles(file)重载递归的函数实现。思想是先用listFiles获取当前目录下的所有列表,显示所有列表的名字,如果当前列表还是个目录,那么调用自身,进行子目录的遍历输出。
1 public void listFiles(File file){ 2 File [] files = file.listFiles();//获取当前目录下所有列表 3 for(File one :files){ 4 System.out.println("名字:" + one.getName()); 5 //TODO:如果是目录,继续遍历列出 6 if(one.isDirectory()){ 7 listFiles(one); 8 } 9 } 10 }
2.字节流
字节流抽象类是InputStream和OutputStream,它们的实现的子类是FileInputStream和FileOutputStream。此处我们使用FileInputStream和FileOutPutStream解决文件读写问题。读入的思想是当需要把文件的内容读入程序时,要申明一个Byte字节数组,将FileInputStream对象读入数组。当没读完的时候,返回读取的长度。当读完的时候,返回-1。当使用完流的时候,要记得关闭流。FileOutputStream写的时候也是需要将写的东西转换为Byte数组写入文件,写完关闭流。
1 public static void Input(String path) throws IOException { 2 //构建一个InputStream对象 1、打开流 3 FileInputStream fin = new FileInputStream(path); 4 byte[] buf = new byte[1024]; 5 int iread = 0;//读取的实际长度 6 //TODO:2、读取文件内容 7 while((iread = fin.read(buf)) != -1){ 8 System.out.println(new String(buf)); 9 System.out.println("*****************我已读"+iread+"**************"); 10 } 11 //TODO:3、关闭流 12 fin.close(); 13 } 14 public static void Output(String path) throws IOException { 15 //1.打开 16 FileOutputStream oup = new FileOutputStream(path); 17 String string = "道可道非常道"; 18 //2.写 19 oup.write(string.getBytes()); 20 //3.关闭 21 oup.close(); 22 }
当读完文件之后立刻要写的时候,我们要注意一个问题,就是最后一次存入的时候,可能已经数组里的内容比最后一次读入的多,那么就会最后一次多输出一些上一次读入数组时存的数据。为了解决这个问题,我们采用三个参数的write方式,避免出现乱码。
public static void ReadAndWrite() throws IOException{ //1、打开 FileInputStream fin = new FileInputStream("d:\\uft.txt"); FileOutputStream fout = new FileOutputStream("d:\\www.txt"); //一个读一个写,一块一块操作 int iread = 0; byte [] buf = new byte[200]; while((iread = fin.read(buf))!=-1){ fout.write(buf,0,iread); System.out.println(new String(buf)); }//关闭 fin.close(); fout.close(); }
3.字符流
字符流:操作的数据单元是16位字符,Reader、Writer 文本文件。思想跟字节流类似,不同的是我们使用的字符流FileReader类继承于Reader接口,字符流FileWriter类继承于Writer接口。具体的操作步骤也是打开流,操作流,关闭流的步骤。
1 public static void Fileread(String path) throws IOException{ 2 //1、打开流 3 FileReader fin = new FileReader(path); 4 //2、 5 char[] buf = new char[100];//读取的数据 6 int iread = 0; 7 while((iread = fin.read(buf)) !=-1){ 8 String str = new String(buf); 9 System.out.println("[读了"+iread+"]"+str.substring(0, iread)); 10 } 11 //3、 12 fin.close(); 13 } 14 public static void testOut(String path,String str) throws IOException{ 15 FileWriter fr = new FileWriter(path,true); 16 fr.write(str); 17 fr.close(); 18 System.out.println("*******************输出完毕!!!*********************"); 19 }
当需要读完了立马就输入文件的时候也是需要注意之前字节流的那个问题,写的时候要用那个三个参数的write函数,不然会将数组里的所有东西存入文件,会存入多余数据。
public static void testIO(String inPath,String outPath) throws Exception{ //d:\红鲤鱼.txt ->d:\红鲤鱼.out2.txt //1 FileReader fin = new FileReader(inPath); FileWriter fout = new FileWriter(outPath); //2 char[] buf = new char[100];//读取的数据 int iread = 0; while((iread = fin.read(buf))!=-1 ){ String str = new String(buf); fout.write(buf,0,iread); System.out.println("["+iread+"]"+str.substring(0, iread)); } //3 fin.close(); }
4.带缓冲的字符流
BufferedReader和BufferedWriter建立的时候需要传入一个Writer或者Reader,构造函数也可以指定缓冲区大小。也就是,BufferedReader是高层流,FileReader是底层流。最后要关闭的时候,要先关闭高层流再关闭底层流。
public static void testOut2() throws IOException{ StringWriter out = new StringWriter(); BufferedWriter fout = new BufferedWriter(out,3); String string = "ABCDEFG哈哈哈"; for(char c:string.toCharArray()){ fout.write(c); System.out.println(out.getBuffer().toString()); } } public static void testIoBuffer(String path1,String path2) throws Exception{ FileReader in = new FileReader(path1); BufferedReader fin = new BufferedReader(in); FileWriter out = new FileWriter(path2,true); BufferedWriter fout = new BufferedWriter(out); String s; while((s =fin.readLine())!=null){ fout.write(s); fout.newLine(); System.out.println(s); } //关闭 fout.close(); fin.close(); out.close(); in.close(); }