码迷,mamicode.com
首页 > 数据库 > 详细

J2SE知识点归纳笔记(七)---Java IO Part 1:File类与RandomAccessFile类

时间:2015-04-26 12:25:28      阅读:247      评论:0      收藏:0      [点我收藏+]

标签: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的习惯哦~


技术分享





本节正文:


1.File(文件类):

1)File类的定义:

描述文件的相关特性,比如:是否可读,可写,文件大小等特性的一个类


2)创建File类对象时要注意的地方:

答:首先我们要区分两个名词:"绝对路径"和"相对路径"

绝对路径——即完整的路径,比如: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下来哦~



3)File的常见方法:

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) 



4)File的使用示例:

①创建一个文件:

	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);
            }
        }
}


5)学以致用的两个小例子:

①遍历某个文件夹下特定的文件

比如某个目录下的所有.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文件而不是直接打印到屏幕上等....




2.RandomAccessFile类

1)这个类是干嘛的?

随机访问文件类,其实和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

  1. package com.jay.test;  
  2.   
  3. import java.io.InputStream;  
  4. import java.io.RandomAccessFile;  
  5. import java.net.HttpURLConnection;  
  6. import java.net.URL;  
  7. import org.junit.Test;  
  8.   
  9.   
  10. public class Downloader {  
  11.     //添加@Test标记是表示该方法是Junit测试的方法,就可以直接运行该方法了  
  12.         @Test  
  13.         public void download() throws Exception  
  14.         {  
  15.             //设置URL的地址和下载后的文件名  
  16.             String filename = "meitu.exe";  
  17.             String path = "http://10.13.20.32:8080/Test/XiuXiu_Green.exe";  
  18.               
  19.             URL url = new URL(path);  
  20.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  21.             conn.setConnectTimeout(5000);  
  22.             conn.setRequestMethod("GET");  
  23.               
  24.             //获得需要下载的文件的长度(大小)  
  25.             int filelength = conn.getContentLength();  
  26.             System.out.println("要下载的文件长度"+filelength);  
  27.             //生成一个大小相同的本地文件  
  28.             RandomAccessFile file = new RandomAccessFile(filename, "rwd");  
  29.             file.setLength(filelength);  
  30.             file.close();  
  31.             conn.disconnect();  
  32.             //设置有多少条线程下载  
  33.             int threadsize = 3;  
  34.             //计算每个线程下载的量  
  35.             int threadlength = filelength % 3 == 0 ? filelength/3:filelength+1;  
  36.             for(int i = 0;i < threadsize;i++)  
  37.             {  
  38.                 //设置每条线程从哪个位置开始下载  
  39.                 int startposition = i * threadlength;  
  40.                 //从文件的什么位置开始写入数据  
  41.                 RandomAccessFile threadfile = new RandomAccessFile(filename, "rwd");  
  42.                 threadfile.seek(startposition);  
  43.                 //启动三条线程分别从startposition位置开始下载文件  
  44.                 new DownLoadThread(i,startposition,threadfile,threadlength,path).start();  
  45.             }  
  46.             int quit = System.in.read();  
  47.             while(‘q‘ != quit)  
  48.             {  
  49.                 Thread.sleep(2000);  
  50.             }  
  51.         }  
  52.       
  53.       
  54.     private class DownLoadThread extends Thread {  
  55.           
  56.           
  57.         private int threadid;  
  58.         private int startposition;  
  59.         private RandomAccessFile threadfile;  
  60.         private int threadlength;  
  61.         private String path;  
  62.         public DownLoadThread(int threadid, int startposition,  
  63.                 RandomAccessFile threadfile, int threadlength, String path) {  
  64.             this.threadid = threadid;  
  65.             this.startposition = startposition;  
  66.             this.threadfile = threadfile;  
  67.             this.threadlength = threadlength;  
  68.             this.path = path;  
  69.         }  
  70.           
  71.         public DownLoadThread() {}  
  72.           
  73.         @Override  
  74.         public void run() {  
  75.             try  
  76.             {  
  77.                 URL url = new URL(path);  
  78.                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  79.                 conn.setConnectTimeout(5000);  
  80.                 conn.setRequestMethod("GET");  
  81.                 //指定从什么位置开始下载  
  82.                 conn.setRequestProperty("Range""bytes="+startposition+"-");  
  83.                 //System.out.println(conn.getResponseCode());  
  84.                 if(conn.getResponseCode() == 206)  
  85.                 {  
  86.                     InputStream is = conn.getInputStream();  
  87.                     byte[] buffer = new byte[1024];  
  88.                     int len = -1;  
  89.                     int length = 0;  
  90.                     while(length < threadlength && (len = is.read(buffer)) != -1)  
  91.                     {  
  92.                         threadfile.write(buffer,0,len);  
  93.                         //计算累计下载的长度  
  94.                         length += len;  
  95.                     }  
  96.                     threadfile.close();  
  97.                     is.close();  
  98.                     System.out.println("线程"+(threadid+1) + "已下载完成");  
  99.                 }  
  100.                   
  101.                   
  102.             }catch(Exception ex){System.out.println("线程"+(threadid+1) + "下载出错"+ ex);}  
  103.         }  
  104.           
  105.     }  
  106. }  


运行截图:

技术分享

技术分享

如图,使用多线程完成了对文件的下载!双击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‘的话就退出


代码下载:J2SEMulDownLoader.zip





最后说两句:

关于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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!