标签:j2se 笔记 file randromaccessfile 文件io
J2SE知识点归纳笔记(七)---Java IO Part 1:File类与RandomAccessFile类
——转载请注明出处:coder-pig
本节引言:
兜兜转转,又回来写Java了,上一篇J2SE知识点归纳笔记(六)---Java常用类是上2014.4.14写的,时隔一年
又来重拾之前还没写完的系列了,前些天群里一个妹子反映她Java基础薄弱,然后抱怨在csdn上找不到J2SE的
系列教程,J2SE简单嘛,个个都懒得写...真的简单么?或许吧...今天刚写完论文初稿,也算稍微轻松了那么一点,
白天上班,晚上赶论文,痛苦的一个星期也算到头了...趁着临近周末,小猪也来动下笔墨吧,(*^__^*) 嘻嘻……
哪怕有一个读者,小猪也会坚持写下去的。好了,唠叨的废话就说到这。本节要学习的东西:
Java IO,一说到IO,估计大家第一时间想起的就是:流,输入输出流,字符流,字节流等等,是吧,但是本节先不讲
流,先来点开胃菜,介绍两个文件IO的类: File(文件类)与RandomAccessFile(随机访问文件类),开始本节内容~
ps:另外说下Java IO相关的类和接口都放在java.io包下,大家要养成查API的习惯哦~
本节正文:
描述文件的相关特性,比如:是否可读,可写,文件大小等特性的一个类
答:首先我们要区分两个名词:"绝对路径"和"相对路径"
绝对路径——即完整的路径,比如:D:\MyCode\Java\FileDemo
相对路径——会在代码所在的地方生成,比如:res/jay.txt 就会在你代码的目录下成jay.txt文件
另外,还有注意一点,文件的路径与Windows下不同,"\"要写成‘/‘或者"\\"不然会报错的喔~
如果,你想保险点,让程序跨平台的话,比如在linux下就和Windows不一样的,Linux下是"/"
解决方法就是使用File给我们提供的两个常量,他们分别是:
File.separator: "\" File.pathSeparator:";"
如果我们是直接自己拼的话,在window下,在D盘下我们要创建一个Jay.txt文件要这样写:
File f=new File("D:\\Jay.txt"); 如果在Linux下呢?要写成 //
如果我们用使用上面的两个常量的话,我们无需理在什么系统下,直接:
String fileName="D:"+File.separator+"Jay.txt";
File f=new File(fileName);
打印下fileName:
好了,记得把这两个变量Mark下来哦~
1)判断文件或者目录是否存在: exists()
2)判断是否为目录: isDirectory()
3)判断是否为文件: isFile()
4)判断文件是否可读: canRead()
5)判断文件是否可写: canWrite()
6)判断文件是否隐藏: isHidden()
7)判断文件路径是否为绝对路径: isAbsolute()
8)判断文件路径是否相同: equals():返回true,false
compareTo():是否相等,相等返回0,小于返回负数,大于返回正数
9)获取文件的绝对路径: getAbsolutePath()
10)获取文件名称: getName()
11)获取文件大小: length()
12)获取文件最后被修改的时间 : lastModified()
13)获取文件的路径: getPath()
14)获取文件的上层文件的目录: getParent()
15)创建一个新文件: createNewFile()
16)创建一个新目录: mkdir()
17)删除文件或目录: delete()
18)修改文件的名称: renameTo(str)
19)修改文件为只读: setReadOnly()
20)修改最后的修改时间:
setLastModified(long time)
public void newFile(String fileName)throws Exception { File f=new File(fileName); f.createNewFile(); }
public void deleteFile(String fileName) { File f=new File(fileName); if(f.exists())f.delete(); else System.out.println("文件不存在"); }
public void newDir(String fileName) { //fileName写文件夹名哦,比如:D:\Test File f=new File(fileName); f.mkdir(); }
删除文件夹的方法和删除文件是一样的,都是调用delete( )方法,空文件夹可以直接删除,
但是有一点要注意的是,非空文件夹是不能直接删除的哦!!!我们需要先把里面的文件都
删除了,才能删除文件夹哦,那么现在我们要做的是,就是删除文件夹里的文件咯,如果
有几层怎么破?我们需要考虑这个问题,这里的话,如果我们使用递归的话,就很容易解决
这个问题了,代码如下:
import java.io.File; public class RemoveDir { public static void main(String[] args) { File file = new File("D:\\Test"); removeDir(file); } public static void removeDir(File file) { File[] files = file.listFiles(); for (File f : files) { if (f.isDirectory())// 递归调用 { removeDir(f); } else { f.delete(); } } // 一层目录下的内容都删除以后,删除掉这个文件夹 file.delete(); } }
好吧,递归就是这么奇妙~
public boolean isDir(String fileName) { File f=new File(fileName); if(f.isDirectory()){ <span style="white-space:pre"> </span>return true; <span style="white-space:pre"> </span>} return false; }
public void getAllFile1(String fileName) { File f = new File(fileName); String[] str = f.list(); for (int i = 0; i < str.length; i++) { System.out.println(str[i]); } }
public void getAllFile2(String fileName) { File f = new File(fileName); File[] str = f.listFiles(); for (int i = 0; i < str.length; i++) { System.out.println(str[i]); } }
还是用到我们的递归:
/* * 获取某目录下的全部文件(包含子目录,完整路径,隐藏文件) * */ public void getAllFile3(File file) { if(file != null){ if(file.isDirectory()){ File[] fileArray=file.listFiles(); if(fileArray!=null){ for (int i = 0; i < fileArray.length; i++) { //递归调用 getAllFile3(fileArray[i]); } } } else{ System.out.println(file); } } }
比如某个目录下的所有.zip文件,笔者的电脑下载了很多编程视频,
我们想遍历查看所有.zip的文件的名称:
核心是:判断是否为目录,文件名的筛选
好吧,下面我们就来实现吧:
/* * 遍历某目录下特定文件的文件名与路径 */ public static void getSpecificFile(File file, String suffix) { if (file != null) { if (file.isDirectory()) { File[] fileArray = file.listFiles(); String name1 = file.getName(); System.out.println("——————" + name1); if (fileArray != null) { for (int i = 0; i < fileArray.length; i++) { // 递归调用 getSpecificFile(fileArray[i], suffix); } } } else { if (file.getName().toString().endsWith(suffix)) { System.out.print(" "); System.out.println(file .getName() .toString() .substring( 0, file.getName().toString().length() - suffix.length())); } } } }
部分运行截图:
比如我们写App的时候,下载了一大堆了素材图片:
而下载的时候:他们的文件名是这样的:
我们是想把他们作为头像的,我们想把他们改成head1.png,head2.png...这种文件名格式的,
难道我们一个个手动的去改么=-=,如果这些图标有上百个,改到什么时候呢?
学以致用,这里我们就来实现简单的批量文件名修改:
比如我们这里需要批量修改下述的图标:
代码实现:
/** * 批量修改文件名: * @param filename 要是目录哦! */ public static boolean changeFileNames(String fileName,String suffix) { File f = new File(fileName); if(!f.isDirectory()) { return false; } int j = 0; File[] fs = f.listFiles(); for(int i = 0;i < fs.length;i++) { String str = fs[i].getName(); if(str.endsWith(suffix)) { fs[i].renameTo(new File(fileName + File.separator +"head" + j +suffix)); // System.out.println(fileName + File.separator +"head" + j +suffix); j++; } } return true; }
运行后:
好了,就是那么简单,是不是又有趣呢?这里并没有都是一些简单的东西,笔者可以根据自己的需要,
进行拓展,比如遍历文件后,生成另外的txt文件而不是直接打印到屏幕上等....
随机访问文件类,其实和File的功能类似,都是用于操作文件,但是RandomAccessFile类
有seek( )方法来访问文件,可以从文件的任意位置读写文件,这个seek可以看做文件指针吧,
而这个类,我们用的最多的无疑是:Java多线程文件下载~
ps:其实这个小猪已经在Android入门之路的day 8写过了,这里就再贴一遍哈,别怪小猪偷懒哈,
另外这个多线程下载的话,文件小的话效果不大哦~比如下个1,2mb的东西....另外示例给的是
Tomact搭建的web空项目,要下载的东西丢到Webroot目录下即可,另外你可以可以直接改成
网上的一个下载链接~
我们都知道使用多线程下载文件可以更快地完成文件的下载,但是为什么呢?
答:因为抢占的服务器资源多,假设服务器最多服务100个用户,服务器中的一个线程对应一个用户
100条线程在计算机中并发执行,由CPU划分时间片轮流执行,加入a有99条线程下载文件,那么
相当于占用了99个用户资源,自然就有用较快的下载速度
ps:当然不是线程越多就越好,开启过多线程的话,app需要维护和同步每条线程的开销,这些开销
反而会导致下载速度的降低,另外还和你的网速有关!
多线程下载的流程
获取网络连接——本地磁盘创建相同大小的空文件——计算每条线程需从文件哪个部分开始下载,结束
——依次创建,启动多条线程来下载网络资源的指定部分
ps:这里直接用J2SE来完成多线程操作,直接建立一个工程,使用Junit运行指定方法即可
如果再Android下用单元测试有点麻烦,照顾一部分朋友,你直接new一个Java Project即可!
代码如下:
DownLoader.java
运行截图:
如图,使用多线程完成了对文件的下载!双击exe文件可运行,说明文件并没有损坏!
注意事项:
①int filelength = conn.getContentLength(); //获得下载文件的长度(大小)
②RandomAccessFile file = new RandomAccessFile(filename, "rwd");
//该类运行对文件进行读写,是多线程下载的核心
③int threadlength = filelength % 3 == 0 ? filelength/3:filelength+1;
//计算每个线程要下载的量
④conn.setRequestProperty("Range", "bytes="+startposition+"-");
//指定从哪个位置开始读写,这个是URLConnection提供的方法
⑤//System.out.println(conn.getResponseCode());
//这个注释了的代码是用来查看conn的返回码的,我们前面用的都是200,
而针对多线程的话,通常是206,必要时我们可以通过调用该方法查看返回码!
⑥int quit = System.in.read();
while(‘q‘ != quit){Thread.sleep(2000);}
//这段代码是做延时操作的,因为我们用的是本地下载,可能该方法运行完了,而我们的
线程还没有开启,这样会引发异常,这里的话,让用户输入一个字符,如果是‘q‘的话就退出
最后说两句:
关于JavaIO中的File和RandowAccessFile就介绍这里了,
大家可以发挥自己的创造力,使用这两个类,实现自己想要的功能~
最后把File的东东都贴到一个工具类中,有需要的可以复制粘贴:
import java.io.File; public class FileUtil { /* * 创建一个新文件 * */ public static void newFile(String fileName) throws Exception { File f = new File(fileName); f.createNewFile(); } /* * 删除文件 * */ public static void deleteFile(String fileName) { File f = new File(fileName); if (f.exists()) f.delete(); else System.out.println("文件不存在"); } /* * 创建一个文件夹(目录) * */ public static void newDir(String fileName) { // fileName写文件夹名哦,比如:D:\Test File f = new File(fileName); f.mkdir(); } /* * 删除一个文件夹(目录) * */ public static void deleteDir(File file) { File[] files = file.listFiles(); for (File f : files) { if (f.isDirectory())// 递归调用 { deleteDir(f); } else { f.delete(); } } // 一层目录下的内容都删除以后,删除掉这个文件夹 file.delete(); } /* * 判断是否为一个文件夹(目录) * */ public static boolean isDir(String fileName) { File f = new File(fileName); if (f.isDirectory()) { return true; } return false; } /* * 获取目录下的全部文件名,包含隐藏文件 */ public static void getAllFile1(String fileName) { File f = new File(fileName); String[] str = f.list(); for (int i = 0; i < str.length; i++) { System.out.println(str[i]); } } /* * 获取目录下的全部文件名包含完整路径,包含隐藏文件 */ public static void getAllFile2(String fileName) { File f = new File(fileName); File[] str = f.listFiles(); for (int i = 0; i < str.length; i++) { System.out.println(str[i]); } } /* * 获取某目录下的全部文件(包含子目录,完整路径,隐藏文件) */ public static void getAllFile3(File file) { if (file != null) { if (file.isDirectory()) { File[] fileArray = file.listFiles(); if (fileArray != null) { for (int i = 0; i < fileArray.length; i++) { // 递归调用 getAllFile3(fileArray[i]); } } } else { System.out.println(file); } } } /* * 遍历某目录下特定文件的文件名与路径 */ public static void getSpecificFile(File file, String suffix) { if (file != null) { if (file.isDirectory()) { File[] fileArray = file.listFiles(); String name1 = file.getName(); System.out.println("——————" + name1); if (fileArray != null) { for (int i = 0; i < fileArray.length; i++) { // 递归调用 getSpecificFile(fileArray[i], suffix); } } } else { if (file.getName().toString().endsWith(suffix)) { System.out.print(" "); System.out.println(file .getName() .toString() .substring( 0, file.getName().toString().length() - suffix.length())); } } } } /** * 批量修改文件名: * @param filename 要是目录哦! */ public static boolean changeFileNames(String fileName,String suffix) { File f = new File(fileName); if(!f.isDirectory()) { return false; } int j = 0; File[] fs = f.listFiles(); for(int i = 0;i < fs.length;i++) { String str = fs[i].getName(); if(str.endsWith(suffix)) { fs[i].renameTo(new File(fileName + File.separator +"head" + j +suffix)); // System.out.println(fileName + File.separator +"head" + j +suffix); j++; } } return true; } }
J2SE知识点归纳笔记(七)---Java IO Part 1:File类与RandomAccessFile类
标签:j2se 笔记 file randromaccessfile 文件io
原文地址:http://blog.csdn.net/coder_pig/article/details/45248445