第三章 文件操作——file
java.io.File
OperationSystem操作系统
File是OS系统的子系统(文件夹)
File的每一个实例用于表示文件系统中的一个文件或目录
使用File可以:
1,访问文件或目录的属性信息(名字,大小,权限,修改时间等)
2,操作文件或目录(创建、删除)
3,访问一个目录的子项
但是不能访问文件数据的内容
在当前目录中创建flie文件
File file = new File("./test.txt"); if(!file.exits){ file.createNewFile(); System.out.println("文件已创建"); }else{ System.out.println("文件已存在"); }
file.getName();获取文件名
file.length();文件的长度(long)
file.canRead();boolean型,判断文件是否可读
file.canWrite();boolean型,判断文件是否可写
file.isHidden();boolean型,判断文件是否隐藏
file.exits boolean型,判断文件是否存在
file.createNewFile();创建新文件
file.delete(); 删除文件//删除文件夹时要求被删文件夹为空
dir.mkdir();创建目录(要求目录所在的父目录必须存在)
dir.mkdirs();创建多级目录(无此要求,将所有不存在的父目录一起创建出来)
dir.delete();删除目录(要求被删除目录为空)
dir.listFiles();返回数组类型,获取一个目录中的所有子目录
dir.isDirectory();boolean 型,判断是否是目录
dir.isFile(); boolean型,判断是否是文件
递归调用
//在方法中调用方法自己,第归调用,开发时能不用就不用,必须要在一个if分支中进行控制
【案例】
*删除一个含有多层子目录的目录文件
public class FileExercise { public static void main(String[] args) { File file = new File("文件夹a"); delete(file); } /**创建一个delete(File f)方法 */ public static void delete(File f) { //f不是文件则: if(f.isDirectory()) { File[]subs=f.listFiles(); for(int i=0;i<subs.length;i++) { File sub =subs[i]; delete(sub);//第归调用 } } //f是文件,则: f.delete(); } } 【练习】 * 1: 编写一段程序,完成1+2+3+……100并输出结果。 * 在这段代码中不得出现for while关键字 private static int index=0; private static int sums=0; public static void main(String[] args) { int[]num= {1,2,3,10,20}; int sums= sums(num); System.out.println(sums); } public static int sums(int[] num) { if(index<num.length) { sums+=num[index]; index++; sums(num); } return sums; }
dir.listFile(FileFilter)文件过滤器 import java.io.File; import java.io.FileFilter; /** * file提供类一个重载的listFiles方法 * File[] listFiles(FileFilter filter); * 该方法要求传入一个文件过滤器,然后将这个目录中满足过滤要求的子项返回 */ /**文件过滤器练习 */ public class FileFilterExercise { public static void main(String[] args) throws IOException { /* * 获取当前目录中所有名字以"."开头的子项 */ File fe = new File(".test"); if(!fe.exists()) { fe.createNewFile(); } File file = new File("."); if(file.isDirectory()) { FileFilter filter = new FileFilter() { public boolean accept(File file) { return file.getName().startsWith("."); } }; File[] f = file.listFiles(filter); for(int i=0;i<f.length;i++) { File fi = f[i]; System.out.println(fi.getName()); } }else { if(file.getName().startsWith(".")) { System.out.println(file.getName()); } } } }
----------------------------------------------------------------------------------------------------------
第四章 RandomAccessFile
java.io.RandomAccessFile
用来读写文件数据的类,RAF是基于指针对文件进行读写操作的
创建RAF时常用的两种模式:
"r" :只读模式
"rw":读写模式
常用构造方法:
RandomAccessFile(String path,String mode);
RandomAccessFile(File file,String mode);
RandomAccessFile raf=new RandomAccessFile("./raf.dat","rw");
//读写模式下:没有文件会自动创建raf.dat
RandomAccessFile raf1=new RandomAccessFile(file,"r");
//只读模式下,不会自动创建文件,会抛出异常,filenotfoundException
byte[] data=new byte[1024*10];//10kb长度字节量的字节数组
1)raf.read();//一次读一个字节
2)raf.read(byte[] data);//一次读给定字节数组data长度的字节量
3)raf.read(byte[] data,int offset,int len)//读写一个字节
4)byte[]buf = str.getBytes();//将字符串按照默认编码转换为字节,并存到buf 数组中
5)raf.write(int d)//向文件中写入1个字节,写入的是给定int值对应的2进制低8位
6)raf.writeInt();//一次性将给定int值对应的4个字节写入文件
7)raf.readInt();//读取int值
其他如:writeLong();writeDouble();等类同
8)long pos = raf.getFilePointer();//获取指针位置
9)raf.write(buf);//按块写出
10)void seek(long pos);//移动指针到指定位置
11)raf.close();
read()方法在读取到文件末尾时以-1返回(因为一个字节内容表示不了-1)
readInt()方法返回的是int值,可以读取到-1,所以读到末尾不能用-1表示,直接抛出EOFException:End Of File Exception
12)
通过读写达成copy:
1 RandomAccessFile src =new RandomAccessFile("飞机","r"); 2 RandomAccessFile desc=new RandomAccessFile("飞机_copy","rw"); 3 int d=-1; 4 while((d=src.read())!=-1) { 5 desc.write(d); 6 } 7 System.out.println("复制完毕!"); 8 src.close(); 9 desc.close();
【随机读写】:单字节读写,频繁读写硬盘,效率差
【块读写】:一组字节读写,效率快
【案例】:
main:
* RAF提供类块读写的方法:
* int read(byte[]data);
* 一次性从文件中读取给定的字节数组长度的字节量
* 并将读取到的字节存入到该数组中,返回值为本次实际读到的字节量
* 若返回值为-1,表示读到类末尾,没有读到任何字节
*
*void write(byte[]data)
*一次性将给定的字节数组中的所有字节写入文件
*
*void write(byte[]data,int offset,int len)
*一次性将给定字节数组中从指定下标offset处到指定位置len处的字节写入文件
【案例】
修改指定用户密码:
main:
1 Scanner sc=new Scanner(System.in); 2 System.out.println("请输入要修改的名字:"); 3 String userName=sc.nextLine(); 4 System.out.println("请输入新密码"); 5 String password = sc.nextLine(); 6 RandomAccessFile raf =new RandomAccessFile("reg.doc","rw"); 7 for(int i=0;i<raf.length()/100;i++) { 8 raf.seek(i*100); 9 byte[]data=new byte[32]; 10 raf.read(data); 11 String name= new String(data,"UTF-8"); 12 if(name.equals(userName)) { 13 raf.seek(i*100+32); 14 data=password.getBytes("UTF-8"); 15 data=Arrays.copyOf(data, 32); 16 raf.write(data); 17 System.out.println("修改成功"); 18 } 19 } 20 raf.close();
* 字符串转成字节,需要指定一个字符集:
* UTF-8(万国码,Unicode的一个子集),英文占1字节,中文一个字占3字节
* GBK:国标编码,英文占1字节,中文占2字节
* ISO8859-1:欧洲编码集,不支持中文
* 字符集包含着字符对应的编码以及字节量
【作业】
*注册信息程序:
*注册信息包含:userName,useId,password,age
*注册信息保存在文件Register.txt中
*注册时检查useId是否存在,若已存在,则提示“该Id已注册,请更换Id!”
*注册完毕后,根据userName可更改该用户的password
【代码实现】
1 package weekend0602; 2 3 import java.io.IOException; 4 import java.io.RandomAccessFile; 5 import java.util.Arrays; 6 import java.util.Scanner; 7 8 /**注册信息 要求输入Id不能重复 */ 9 public class RegistByRAF { 10 private static String userName; 11 private static String userId; 12 private static String password; 13 private static int age; 14 15 public static void main(String[] args) throws IOException { 16 RandomAccessFile raf = new RandomAccessFile("Register.txt","rw"); 17 RandomAccessFile rr = new RandomAccessFile("Register.txt","r"); 18 Scanner sc = new Scanner(System.in); 19 System.out.println("请输入姓名:"); 20 userName = sc.nextLine(); 21 do { 22 System.out.println("请输入Id:"); 23 userId = sc.nextLine(); 24 if(checkEquals("Register.txt",userId,32)) { 25 System.out.println("该Id已注册,请更换Id!"); 26 }else { 27 break; 28 } 29 }while(true); 30 System.out.println("请输入密码:"); 31 password = sc.nextLine(); 32 System.out.println("请输入年龄:"); 33 age = Integer.parseInt(sc.nextLine()); 34 35 raf.seek(raf.length()); 36 byte[] data = userName.getBytes("utf-8"); 37 data = Arrays.copyOf(data, 32); 38 raf.write(data); 39 data = userId.getBytes("utf-8"); 40 data = Arrays.copyOf(data, 32); 41 raf.write(data); 42 data = password.getBytes("utf-8"); 43 data = Arrays.copyOf(data, 32); 44 raf.write(data); 45 raf.writeInt(age); 46 System.out.println("注册完毕!"); 47 sc.close(); 48 raf.close(); 49 rr.close(); 50 51 } 52 53 /**检查指定文件名fileName中指定位置index的内容和str的内容是否相同,若相同则返回true,否则返回false */ 54 public static boolean checkEquals(String fileName,String inputstr,int index) throws IOException { 55 RandomAccessFile raf = new RandomAccessFile(fileName,"r"); 56 boolean flag = false; 57 for(int i=0;i<raf.length()/100;i++) { 58 raf.seek(i*100+index); 59 byte[] data = new byte[32]; 60 raf.read(data); 61 String s = new String(data,"utf-8").trim(); 62 63 if(s.equals(inputstr)) { 64 flag=true; 65 break; 66 } 67 } 68 raf.close(); 69 return flag; 70 71 } 72 /**检查指定文件名fileName中指定位置index的内容和inputstr的内容是否相同,若相同则修改beginIndex处的内容,否则提示inputstr不存在 73 * @throws IOException */ 74 public static void changeInfo (String fileName,String inputstr,int index,int beginIndex,String changeInfo) throws IOException { 75 RandomAccessFile raf = new RandomAccessFile(fileName,"r"); 76 RandomAccessFile raw = new RandomAccessFile(fileName,"rw"); 77 for(int i=0;i<raf.length()/100;i++) { 78 raf.seek(i*100+index); 79 byte[] data = new byte[32]; 80 raf.read(data); 81 String s = new String(data,"utf-8").trim(); 82 if(s.equals(inputstr)) { 83 raf.seek(i*100+index+beginIndex); 84 data=changeInfo.getBytes("utf-8"); 85 data=Arrays.copyOf(data, 32); 86 raw.write(data); 87 System.out.println("修改完毕!"); 88 break; 89 } 90 if(i==raf.length()/100-1) { 91 System.out.println("用户名不存在"); 92 } 93 } 94 raf.close(); 95 raw.close(); 96 } 97 }
********************
package weekend0602; import java.io.IOException; import java.util.Scanner; /**练习用RandomAccessFile修改指定用户的密码 */ public class RAF_ChangePasswordExercise { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String userName = sc.nextLine(); System.out.println("请输入新密码:"); String password = sc.nextLine(); RegistByRAF.changeInfo("Register.txt", userName, 0, 0, password); sc.close(); } }