1 文件的基本操作: 咱们在java中谈到的文件都是磁盘上的文件,如果抛开java站在操作系统的角度来看,操作系统在管理许多软件资源和硬件设备的时候,都是把这些东西抽象成了一个个的文件,显示器,打印机,网卡,抽象成文件
c****
//File(parent)传入一个绝对路径,来创建一个File的类
File file1=new File("d:/张中军/111111");
System.out.println(file1.exists());//判断文件是否存在
System.out.println(file1.isFile());//判断是否是普通文件
System.out.println(file1.isDirectory());//判断是否是目录
File file2=new File("d:/张中军/哈哈哈哈哈");
file2.createNewFile();//给定一个文件路径(随便写)(创建出一个普通文件)
File file3=new File("d:/张中军/比特");
file3.mkdir();//给定一个路径,创建出一个文件
File file4=new File("d:/张中军/java/javaweb/javaee");
file4.mkdirs();//创建出多个目录,给定任意一个路径
File file1=new File("d:/张中军/zzzzzzz.OBJ");
File file2=new File("d:/张中军/文件1");
File file3=new File("d:");
System.out.println(file3.exists());
System.out.println(file2.exists());
file1.renameTo(file2);//将文件1改名,名字是文件2的名字
file2.renameTo(file3);//将文件2的路径传到文件3的路径
所有的文件复制(剪切粘贴),其实都是一个高效的操作 ,每个文件都有一个属性,这个属性就是文件的路径;路径的移动操作,其实就是修改文件的属性罢了;这不是文件复制,要是文件复制,就是把文件的内容读出来,然后拷贝一份,写入到磁盘中,这个过程就需要比较大的开销了
面试题给一个list或者listFile方法,遍历出所有的文件
public static void ShowFile(File file)
{
File[] arr1=file.listFiles();
for(File file1:arr1)
{
if(file1.isDirectory())
{
ShowFile(file1);
}
else //if(file1.isFile())
{
System.out.println(file1);
}
}
public static void ShowFile(String str) {
File file = new File(str);
String[] arr1 = file.list();
if (file.isFile()) {
list.add(file);
return;
}else{
for (String string : arr1) {
System.out.println(string);
ShowFile(str+"/"+string);
}
}
2 下面我们对文件的读和写进行操作
InputStream inputStream=new FileInputStream("d:/张中军/哈哈哈哈哈"); int b=-1; int count=0; while(true) { b=inputStream.read();//一次读一个字节 count++;//通过count的值可以判断读了几次,文件中有123456,就读了六次 if(b==-1) break;//b代表读取的返回值 System.out.printf("%c",b); }
也可以不用一个字节一个字节的读
byte arr1[]=new byte[1024];
InputStream inputStream=new FileInputStream("d:/张中军/哈哈哈哈哈");
int b=0,count=0;
while(true)
{
b=inputStream.read(arr1);//像数组里面读,一次读取1024个字节,但是文件中只有6个数字,所以一次读6个
count++;
if(b==-1)
break;
}
inputStream.close();
//read方法 无参数的构造方法就是一次读取一个字节,假设这个文件中的长度是2049,
第一次循环,读取的长度是1024个字节,放到一个arr1数组中,返回一个1024;
第二次循环,读取的长度是1024个字节,放到arr1数组中,返回一个1024
第三次循环,读取一个字节,放到arr1数组中,返回1
第四次循环,已经读取到文件末尾了,read返回到了一个-1
输出汉字:
byte arr1[]=new byte[1024];
InputStream inputStream=new FileInputStream("d:/张中军/哈哈哈哈哈");
int b=0;
while(true)
{ b=inputStream.read(arr1);
if(b==-1)
break;
}
for(int i=0;i<arr1.length;i+=3){//把三个字节合并到一起,作为一个整体来输出
String str=new String(arr1,i,3,"UTF-8");// //i取决于从数组的哪一个下标开始,但是是如果是中英混合呢??
System.out.printf(str);
}
还可用scan的方式
try (InputStream inputStream = new FileInputStream("d:/张中军/哈哈哈哈哈")) {
try (Scanner scan = new Scanner(inputStream, "UTF-8")) {
while (scan.hasNext())// //scnner不光可以从标准台读取数据输入,而且还可以从文件中读取数据
{//这种try catch可以自动关闭资源
String s=scan.next();
System.out.println(s);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
1 为什么读汉字和读字符不一样呢? 中文的编码方式和英文是不太一样的,如果是Ascli码的话,就会比较简单。如果是中文的话,就需要使用UTF-8,因为一个汉字在UTF-8中,是由三个字节构成的。SE阶段也用到了Scanner为什么没有关闭资源呢?因为Scanner内部持有的inputStream是System是标准输入,标准输入这个文件,一般是不关闭的,这个文件是每个进程创建出来后,操作系统默认打开的文件;
2 flush 是刷新缓冲区,计算机读取内存的速度是比读写磁盘要快很多的,所以有时候为了提高效率,就可以直接减少访问磁盘的次数,使用缓冲区就可以很好地解决这个问题,当我们用write来写文件的时候,并不是真的直接写到磁盘中了,而是先放到缓冲区中;
byte[] arr1=new byte[]{'a','b','c','d'};
try(OutputStream outputStream=new FileOutputStream("d:/张中军/哈哈哈哈哈")){
outputStream.write(78);//以一个字节来写
outputStream.write(arr1);//写一个字节数组
String s="我是蔡徐坤";
outputStream.write(s.getBytes(StandardCharsets.UTF_8));//写一个字符串,先要把这个字符串转化成字节数组
}catch(IOException e)
{
e.printStackTrace();
}
}
那为什么要关闭文件呢? 这就涉及到文件描述符的问题了,每当创建一个进程的时候进程的PCB就会创建出一个文件描述符表,类似于一个数组(数组中的每一个元素就是structFile类型),那么每当进程打开一个文件,就会产生一个具体的文件描述符,然后就把他放到文件描述表中。每次打开文件,就会在文件描述表中申请一项,每当关闭文件时,就会把这个表项放掉;如果一直持续不断的打开文件,又不关闭,很快就会把文件描述符给耗尽,此时如果再打开文件,就会失败;
//一旦按照OUtputStream的方式来写文件,就会把原来的文件中的数据删除掉
try (OutputStream outputStream = new FileOutputStream("d:/张中军/哈哈哈哈哈")) {
try (PrintStream printStream = new PrintStream(outputStream)) {
printStream.println("大傻子");
}
} catch (IOException e) {
e.printStackTrace();
}
下面来做几个任务:
1 指定一个目录,扫描这个目录,找到文件名是否包含了指定字符的文件,并提示这个用户是否要删除这个文件,根据用户的输入来决定是否删除
public static void research(String str,File file,List list)
{ File[] arr1=file.listFiles();
if(arr1==null||arr1.length==0)
{
return;
}
for (File filex: arr1) {
if(filex.isDirectory())
{
research(str,filex,list);
}
else{
if(filex.getName().contains(str))
{
list.add(filex);
}
}
}
}
public static void main(String[] args) throws IOException {
System.out.println("请输入你要查询的目录,指定绝对路径");
Scanner scan=new Scanner(System.in);
String mulu=scan.next();
File file=new File(mulu);
if(file.isFile())
{
System.out.println("你输入的绝对路径有误,程序即将退出");
return;
}
System.out.println("请输入你要查询的字符");
String str= scan.next();
List<File> list=new ArrayList<>();
research(str,file,list);
for(File f:list)
{
System.out.println(f.getAbsoluteFile()+"是否要删除,删除是Yes,不删除是No");
String str2=scan.next();
if(str2.equals("Yes"))
{ f.delete();
System.out.println("此文件已经删除");
}
}
}
2 复制一个文件
描述:启动一个文件之后,让用户自己输入一个文件的绝对路径,要求这个文件是一个普通文件不是一个目录,然后再输入一个指定要复制过去的文件路径。通过程序把这个文件给复制了,如果这个原来的文件存在,就不复制了,会把文件删除掉
public static void main(String[] args)throws IOException {
Scanner scan=new Scanner(System.in);
System.out.println("请输入你想复制哪个文件,请输入绝对路径");
String str1=scan.next();
File file1=new File(str1);
if(file1.isDirectory())
{
System.out.println("这是一个目录,文件输入有误,程序即将退出");
return;
}
System.out.println("请输入目标路径");
String str2= scan.next();
File file2=new File(str2);
if(!file2.exists())
{
System.out.println("目标文件的目录不存在,程序直接退出");
return;
}
if(!file2.getParentFile().exists())
{
System.out.println("目标文件的父亲目录不存在");
return;
}
byte[] arr1=new byte[1024];
try(InputStream inputStream=new FileInputStream(str1))
{
try(OutputStream outputStream=new FileOutputStream(str2)) {
while(true)
{
int len=inputStream.read(arr1);
if(len==-1)
{
break;
}
}
outputStream.flush();
outputStream.write(arr1);
}
}catch(IOException e)
{
e.printStackTrace();
}
3 给定一个目录,查找文件名字和文件内容中出现特定字符的文件;
public static void research(List list,String str1,File file)throws IOException
{
File[] arr1=file.listFiles();;
for(File file2:arr1)
{
System.out.println(file2);
}
for (File file1:arr1) {
if(file1.isFile())
{ if(file1.getName().contains(str1)||scanlll(list,str1,file1))
list.add(file1);
}
else{
research(list,str1,file1);
}
}
}
public static boolean scanlll(List list,String str1,File file)throws IOException
{ StringBuffer stringBuffer=new StringBuffer();
try(InputStream inputStream=new FileInputStream(file))
{
Scanner scanner=new Scanner(inputStream,"UTF-8");
while(scanner.hasNextLine())
{
String line=scanner.nextLine();
stringBuffer.append(line+"\n");
}
}catch(IOException e)
{
e.printStackTrace();
}
return stringBuffer.indexOf(str1)!=-1;
}
public static void main(String[] args) throws IOException{
Scanner scan=new Scanner(System.in);
System.out.println("请输入你想查询的工作目录,绝对路径");
String str=scan.next();
File file=new File(str);
System.out.println("请输入你要查询的字符串");
String str1=scan.next();
if(file.isFile())
{
System.out.println("你输入的文件路径错误,是普通文件,请重新输入");
return;
}
List list=new ArrayList<>();
research(list,str1,file);
System.out.println(list);
}
i****ndexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回-1。
**nextline 是一次读取一行数据,每次读取的时候都是遇到了换行符,才读取完毕; **
版权归原作者 小比特大梦想 所有, 如有侵权,请联系我们删除。