欢迎光临
我们一直在努力

Java实现分类文件拷贝-JSP教程,Java技巧及代码

建站超值云服务器,限时71元/月

在java中对文件进行分类

如果你是个java程序员,也许你对java的文件组织已经非常清楚,例如你知道你们项目组是如何把众多的java文件进行分类,组成整个项目工程.通常你们可能会根据业务来分组.有时候,我们作为项目成员,就会把自己的java文件根据分组来进行分类的.下面,给出个例子:

某项目projectx要给某家名叫comx的商业公司做的信息系统,根据业务需要分为,a,b,c,d四组,采用典型的三层结构,其中,工程中的文件分为前台部分和后台部分.经过分析,该项目最后把文件组织成这样的结构:

a组写的前台文件所在的包为com.comx.foreg.a,相对应的后台文件放在com.comx.backg.a中

b组写的前台文件所在的包为com.comx.foreg.b,相对应的后台文件放在com.comx.backg.b中

c组写的前台文件所在的包为com.comx.foreg.c,相对应的后台文件放在com.comx.backg.c中

d组写的前台文件所在的包为com.comx.foreg.d,相对应的后台文件放在com.comx.backg.d中

当然,这只是我的一种简化的模型,实际上的项目由于业务交叉,综合复杂度等等因素应该比这样的结构复杂的多.象上面这样的工程,最后所有的代码放在文件夹"d:\projectx\src\"下面,而下面的文件组织和java包路径可能又不一样.

现在,我描述一下,我要阐述的问题,当这个工程已经基本完成之后,各个小组都出现了修改,集成发布人员,给项目组开了一个ftp,ftp文件结构正好和原来的结构一样,a组的程序员修改了某个文件后,按照他所在的位置,重新上传.这样,通常会有人把代码传错了位置,最后编译的时候出现错误,对于及其复杂,各组有所交叉的组织来说,编译的时候查错,都很困难.

现在要做的是,让修改后的文件全部都传到一个文件夹中,通过程序把这些文件分发到他们应该在的位置.

好,如何来作?

思路很简单:每个文件都有他们的包路径,既然我们已经有了完整的文件结构,我们就能知道每一个包路径所对应的文件组织中的路径,如有一个文件classx.java,我们通过读取他的包路径为com.comx.foreg.a.a1,a1为a组的一个用例,但是它实际所在的位置为:

d:\projectx\src\business_1\com\comx\foreg\a\a1\classx.java,我们另外一个文件calssy.java,他的包为com.comx.foreg.a.a2,它是a组的第二个用例,但他的实际存放路径为:d:\projectx\src\business_2\com\comx\foreg\a\a2\classy.java,

我们就可以根据事先指定的src目录找到他的合适位置.

我所作的是为本项目组的程序员上传文件提供方便,他们把要上传的文件上传到一个文件夹,然后通过这个程序拷贝到正确的位置即可.下面是我实现的一些模块,你可以根据自己的特殊情况来做修改或扩展.

0.处理这个问题需要设置一些类变量:

private string filepath="d:\\work\\upload"; //文件上传路径,直接指向你的ftp目录吧

private string configefile="packageconfig.cxh"; //路径配置文件,后面会专门讲到

private string objpath="d:\\work\\gdlt\\src"; //目标文件路径,你可以指定任意,但要和配置文件一致

private printstream ps=null; //输出消息重定向,用于处理过程中的信息输出定向

private arraylist lines=null; //保存配置文件

string[] heads=null; //保存每条配置的头

string globalline; //记录一条配置信息

1.传入一个java文件,返回该java文件的包路径,如上面的classx.java,返回com.comx.foreg.a

/**

* 读取一个java文件,返回他的package信息取出来

* @param file 文件句柄

* @return 返回包路径

*/

private string readpac(file file){

string pac=null;

try{

bufferedreader fr=new bufferedreader(new filereader(file)); //读取器

string line=fr.readline();

while(line!=null){ //逐行处理

//处理当前行

line.trim();

if(line.startswith("package")){ //找到包信息了

pac=line.substring(7,line.length()-1).trim();

break;

}

line=fr.readline();

}

} catch(ioexception ie){

pac=null;

ie.printstacktrace();

}

return pac;

}

2.根据上面返回的包路径,返回该文件应该在的实际位置,例如上面的classx.java,返回d:\projectx\src\business_2\com\comx\foreg\a\

/**

*

* 通过package信息把该文件应该在的位置取出来

* @param pack 包路径

* @return 返回该文件应该在的路径 返回null表示识别失败,需要读入 比如sbzs

* 并智能的更新配置文件

*/

private string parsepac(string pack,file cfgfile){

string path=null;

string line=null;

try{

for(int i=0;i<heads.length;i++){

line=(string)lines.get(i);

if(line.indexof(pack)>0){ //找到了

return heads[i];

}

}

//没有找到,进行询问

ps.print("请输入包 "+pack+" 所在的路径:(例如:sbzs)");

datainputstream dis=new datainputstream(system.in);

path=dis.readline().trim().tolowercase();

dis.close();

if(path==null||path.length()==0){

ps.println("没有输入有效的包所在位置");

} else{ //得到名字,写入

int i;

for(i=0;i<heads.length;i++){

if(path.equals(heads[i])){ //找到了目标,把该包加入

string tmp=(string)lines.get(i)+"|"+pack;

lines.set(i,tmp); //更新

break;

}

}

if(i==heads.length){ //目前还没有这个位置,加入并更新

lines.add(path+":"+pack);

string[] tmp=new string[heads.length+1];

system.arraycopy(heads,0,tmp,0,heads.length);

tmp[heads.length]=path;

heads=tmp;

}

}

} catch(ioexception ie){

path=null;

ie.printstacktrace();

}

return path;

}

3.根据上面返回的实际位置,就可以把该文件拷贝到适合的位置.成功返回true

/**

* 把该文件拷贝到完整的路径中去

* @param file 文件句柄

* @param path 文件目标的绝对路径

* @return

*/

private boolean copy(file file,string fullpath){

ps.println("开始拷贝文件….");

ps.println("源文件:"+file.getname());

ps.println("目标文件在:"+fullpath);

string filename=file.getname();

int pos=filename.lastindexof(file.separator);

if(pos>0){

filename=filename.substring(pos+1,filename.length());

}

string lastpath=fullpath+file.separator+filename;

file objfile=new file(lastpath);

if(objfile.exists()&&!objfile.delete()){ //如果存在则删除

ps.println("删除目标文件失败");

return false;

}

//开始拷贝

try{

objfile.createnewfile();

fileinputstream fis=new fileinputstream(file);

fileoutputstream fos=new fileoutputstream(objfile);

byte[] buf=new byte[1024];

int i=0;

while((i=fis.read(buf))!=-1){

fos.write(buf,0,i);

}

fis.close();

fos.close();

} catch(ioexception ie){

ie.printstacktrace();

return false;

}

return true;

}

到目前为止你可能都已经注意到了,这一切都非常简单,模块的思路也非常清楚.当然你肯定也注意到了,其中最重要的一个角色就是配置文件,如果没有这个,你可以看到在parsepac方法中,会要求你控制台输入某个文件对应的目标路径,这是对于新文件(即原来目标目录中没有的文件,新添的),对于对老文件的修改,我们都可以在配置文件中得到目标路径.下面我们看看配置文件如何得到.在这各之前,我们提到几个工具方法:

1.取文件名的扩展名,传入文件名,返回扩展名.

/**

*

* @param filename

* @return

*/

private string getext(string filename){

int pos=filename.lastindexof(".");

if(pos>0){

return filename.substring(pos+1,filename.length());

}

return null;

}

2.判断一个目录是否有子目录,传入一个目录,判断有没有子目录,没则有返回true,有子目录返回false

/**

* 判断一个目录是否有子目录,没有返回true

* @param dir

* @return

*/

private boolean hasnosub(string directory){

file dir=new file(directory);

if(!dir.isdirectory()){ //当前不是目录,肯定没有子目录

return true;

}

string[] subs=dir.list();

for(int i=0;i<subs.length;i++){ //对每个子元素进行判断,有目录就直接返回false

file tmp=new file(dir+file.separator+subs[i]);

if(tmp.isdirectory()){

return false;

}

}

return true;

}

那么我们的配置文件记录什么,什么样的格式?假设我们指定我们的目标路径,类变量objpath=d:\projectx\src

那么我们的配置生成象这样:

business_1:com.comx.foreg.a.a1

business_2:com.comx.foreg.a.a2

如果a组的另外一个用例a3在business_1文件夹下,则配置文件的第一条配置信息为:

business_1:com.comx.foreg.a.a1|com.comx.foreg.a.a3

依次类推,通过文件的包信息与每条配置信息进行匹配,得知它所在的文件夹,当然如果objpath设置为d:\projectx\的话,那么配置信息的:前面部分为src/business_1.就这样,我们得到了可以使用的配置文件.下面我们看看配置文件相关的模块.

1.给定配置文件,把配置信息读入到类变量lines,它的每一个元素就是一条配置信息(配置文件的一行),同时把配置信息中:号前面的部分,我们称之为配置信息头(如business_1或src/business_1),取到我们的类变量heads中,它的作用就是为了提高处理效率,使得我们不用每次都配置信息中取头信息.

/**

* 读取配置文件,到arraylist和heads

* @return

*/

private boolean readcfg(file cfgfile){

try{

bufferedreader fr=new bufferedreader(new filereader(cfgfile));

string line=fr.readline();

while(line!=null){

//处理当前行

line.trim();

lines.add(line);

line=fr.readline();

}

int size=lines.size();

heads=new string[size];

for(int i=0;i<size;i++){

line=(string)lines.get(i);

heads[i]=gethead(line);

}

fr.close();

} catch(ioexception ie){

ie.printstacktrace();

return false;

}

return true;

}

2.把一条配置信息的头解析出来,就是上面方法出现的gethead

/**

* 取得一条配置文件的头 例如business_1:

* @param line 一条配置文件

* @return

*/

private string gethead(string line){

int pos=line.indexof(":");

if(pos==-1){

ps.println("配置文件有错");

return "";

}

return line.substring(0,pos);

}

3.该方法的作用就是,把我们的类变量lines的信息写入到配置文件中,因为可能有新添加的文件,用户输入了新的配置信息,或者在交互时,某些配置信息发生了变化.

/**

* 写入配置文件

* @return

*/

private boolean savecfg(file cfgfile){

if(lines==null||lines.size()==0){

return false;

}

try{

cfgfile.delete();

cfgfile.createnewfile();

bufferedwriter bw=new bufferedwriter(new filewriter(cfgfile));

int size=lines.size();

for(int i=0;i<size;i++){

bw.write((string)lines.get(i));

bw.newline();

}

bw.flush();

bw.close();

} catch(ioexception ie){

ie.printstacktrace();

return false;

}

return true;

}

上面的方法都是我们和配置文件的交互的一个过程,我们下一个问题时,如何初始化生成这个配置文件,基本上有下面几个模块:

1.这就是我们生成配置文件的根本,实际上就是到目标路径中收集结构信息的过程,其中可能调用一些工具方法.

/**

* 生成配置文件

* @param pac 包路径

* @param path 文件路径

* @return 返回保存是否正确

*/

public boolean createcfg(){

file dir=new file(objpath); //到目标路径中去收集信息

string[] dirs=dir.list();

string curdir;

char sep=file.separatorchar;

string line;

for(int i=0;i<dirs.length;i++){ //到每一个子元素(文件或目录)下工作

if(!new file(objpath+sep+dirs[i]).isdirectory()){ //当前元素不是目录,做下一个

continue;

}

globalline=null;

curdir=objpath+sep+dirs[i]+sep+"src";

getpath(curdir,null); //到当前目录下继续搜寻信息,getpath.

line=dirs[i]+":"+globalline;

lines.add(line);

}

file cfgfile=new file(filepath+sep+configefile);

savecfg(cfgfile); //保存配置信息

return true;

}

其中curdir =…那一行是当前路径,其中的"src"因为我所在项目的子文件下还有一个src目录,但他不是包信息包含的,就像是我们的business_1下面为src/com/comx/…等等,所以就直接加上了.

明眼人一眼就能看出,关键方法是getpath,他是递归的,就像这样:

2.当前子目录下递归收集信息,对于每一条路径,我们只保存最长的,因为短的是可以在长的路径匹配得到的.

/**

* 递归收集

* @param root 上一级目录

* @param pack 当前已经收集到的信息

*/

private void getpath(string root,string pack){

if(hasnosub(root)){ //如果没有了子目录

if(globalline==null){

globalline=pack;

} else{

globalline+="|"+pack;

}

return;

}

file dir=new file(root);

char sep=file.separatorchar;

string[] subs=dir.list();

for(int i=0;i<subs.length;i++){

string curpath=root+sep+subs[i];

file tmp=new file(curpath);

if(tmp.isdirectory()){

if(pack==null){ //如果是目录,则递归

getpath(curpath,subs[i]);

} else{

getpath(curpath,pack+"."+subs[i]);

}

}

}

}

其中用到了类变量globalline,它最终在调用完成的时候,会返回一条完整的配置信息.

好了,我就讲这么多了,不知道有没有讲明白,希望对你有所帮助,谢谢,最后一个方法是excute方法,就是执行这个完整的分类拷贝文件的工作.我把完整的类放在下面,就不另外写了.(这个类带有我本身项目的痕迹,不过不多,稍改即可)

import java.io.bufferedreader;

import java.io.bufferedwriter;

import java.io.datainputstream;

import java.io.file;

import java.io.fileinputstream;

import java.io.fileoutputstream;

import java.io.filereader;

import java.io.filewriter;

import java.io.ioexception;

import java.io.printstream;

import java.util.arraylist;

/**

* <p>title: </p>

* <p>description: </p>

* <p>copyright: copyright (c) 2004</p>

* <p>company: </p>

* @author caoxh

* @version 1.0

*/

public class savefile{

private string filepath="d:\\work\\upload"; //文件上传路径

private string configefile="packageconfig.cxh"; //路径配置文件

private string objpath="d:\\work\\gdlt\\src"; //目标文件路径

private printstream ps=null; //输出消息重定向

private arraylist lines=null; //保存配置文件

string[] heads=null; //保存每条配置的头

string globalline; //记录一条配置信息

/**

* 读取一个java文件,返回他的package信息取出来

* @param file 文件句柄

* @return 返回包路径

*/

private string readpac(file file){

string pac=null;

try{

bufferedreader fr=new bufferedreader(new filereader(file));

string line=fr.readline();

while(line!=null){

//处理当前行

line.trim();

if(line.startswith("package")){ //找到包了

pac=line.substring(7,line.length()-1).trim();

break;

}

line=fr.readline();

}

} catch(ioexception ie){

pac=null;

ie.printstacktrace();

}

return pac;

}

/**

* 取得一条配置文件的头 例如sbzs:

* @param line 一条配置文件

* @return

*/

private string gethead(string line){

int pos=line.indexof(":");

if(pos==-1){

ps.println("配置文件有错");

return "";

}

return line.substring(0,pos);

}

/**

* 读取配置文件,到arraylist和heads

* @return

*/

private boolean readcfg(file cfgfile){

try{

bufferedreader fr=new bufferedreader(new filereader(cfgfile));

string line=fr.readline();

while(line!=null){

//处理当前行

line.trim();

lines.add(line);

line=fr.readline();

}

int size=lines.size();

heads=new string[size];

for(int i=0;i<size;i++){

line=(string)lines.get(i);

heads[i]=gethead(line);

}

fr.close();

} catch(ioexception ie){

ie.printstacktrace();

return false;

}

return true;

}

/**

* 写入配置文件

* @return

*/

private boolean savecfg(file cfgfile){

if(lines==null||lines.size()==0){

return false;

}

try{

cfgfile.delete();

cfgfile.createnewfile();

bufferedwriter bw=new bufferedwriter(new filewriter(cfgfile));

int size=lines.size();

for(int i=0;i<size;i++){

bw.write((string)lines.get(i));

bw.newline();

}

bw.flush();

bw.close();

} catch(ioexception ie){

ie.printstacktrace();

return false;

}

return true;

}

/**

*

* 通过package信息把该文件应该在的位置取出来

* @param pack 包路径

* @return 返回该文件应该在的路径 返回null表示识别失败,需要读入 比如sbzs

* 并智能的更新配置文件

*/

private string parsepac(string pack,file cfgfile){

string path=null;

string line=null;

try{

for(int i=0;i<heads.length;i++){

line=(string)lines.get(i);

if(line.indexof(pack)>0){ //找到了

return heads[i];

}

}

//没有找到,进行询问

ps.print("请输入包 "+pack+" 所在的路径:(例如:sbzs)");

datainputstream dis=new datainputstream(system.in);

path=dis.readline().trim().tolowercase();

dis.close();

if(path==null||path.length()==0){

ps.println("没有输入有效的包所在位置");

} else{ //得到名字,写入

int i;

for(i=0;i<heads.length;i++){

if(path.equals(heads[i])){ //找到了目标,把该包加入

string tmp=(string)lines.get(i)+"|"+pack;

lines.set(i,tmp); //更新

break;

}

}

if(i==heads.length){ //目前还没有这个位置,加入并更新

lines.add(path+":"+pack);

string[] tmp=new string[heads.length+1];

system.arraycopy(heads,0,tmp,0,heads.length);

tmp[heads.length]=path;

heads=tmp;

}

}

} catch(ioexception ie){

path=null;

ie.printstacktrace();

}

return path;

}

/**

* 把该文件拷贝到完整的路径中去

* @param file 文件句柄

* @param path 文件目标的绝对路径

* @return

*/

private boolean copy(file file,string fullpath){

ps.println("开始拷贝文件….");

ps.println("源文件:"+file.getname());

ps.println("目标文件在:"+fullpath);

string filename=file.getname();

int pos=filename.lastindexof(file.separator);

if(pos>0){

filename=filename.substring(pos+1,filename.length());

}

string lastpath=fullpath+file.separator+filename;

file objfile=new file(lastpath);

if(objfile.exists()&&!objfile.delete()){ //如果存在则删除

ps.println("删除目标文件失败");

return false;

}

//开始拷贝

try{

objfile.createnewfile();

fileinputstream fis=new fileinputstream(file);

fileoutputstream fos=new fileoutputstream(objfile);

byte[] buf=new byte[1024];

int i=0;

while((i=fis.read(buf))!=-1){

fos.write(buf,0,i);

}

fis.close();

fos.close();

} catch(ioexception ie){

ie.printstacktrace();

return false;

}

return true;

}

/**

* 生成配置文件

* @param pac 包路径

* @param path 文件路径

* @return 返回保存是否正确

*/

public boolean createcfg(){

file dir=new file(objpath);

string[] dirs=dir.list();

string curdir;

char sep=file.separatorchar;

string line;

for(int i=0;i<dirs.length;i++){

if(!new file(objpath+sep+dirs[i]).isdirectory()){

continue;

}

globalline=null;

curdir=objpath+sep+dirs[i]+sep+"src";

getpath(curdir,null);

line=dirs[i]+":"+globalline;

lines.add(line);

}

file cfgfile=new file(filepath+sep+configefile);

savecfg(cfgfile);

return true;

}

/**

* 递归收集

* @param root

* @param pack

*/

private void getpath(string root,string pack){

if(hasnosub(root)){ //如果没有了子目录

if(globalline==null){

globalline=pack;

} else{

globalline+="|"+pack;

}

return;

}

file dir=new file(root);

char sep=file.separatorchar;

string[] subs=dir.list();

for(int i=0;i<subs.length;i++){

string curpath=root+sep+subs[i];

file tmp=new file(curpath);

if(tmp.isdirectory()){

if(pack==null){ //如果是目录,则递归

getpath(curpath,subs[i]);

} else{

getpath(curpath,pack+"."+subs[i]);

}

}

}

}

/**

* 判断一个目录是否有子目录,没有返回true

* @param dir

* @return

*/

private boolean hasnosub(string directory){

file dir=new file(directory);

if(!dir.isdirectory()){

return true;

}

string[] subs=dir.list();

for(int i=0;i<subs.length;i++){

file tmp=new file(dir+file.separator+subs[i]);

if(tmp.isdirectory()){

return false;

}

}

return true;

}

/**

*

* @param filename

* @return

*/

private string getext(string filename){

int pos=filename.lastindexof(".");

if(pos>0){

return filename.substring(pos+1,filename.length());

}

return null;

}

/**

* 循环处理一个文件夹

*/

public void excute(){

char sep=file.separatorchar;

file list=new file(filepath+sep+"list.txt");

file dir=new file(filepath);

if(!dir.exists()||!dir.isdirectory()){ //指定的不是目录

ps.println("指定上传文件的目录不正确");

return;

}

file cfgfile=new file(filepath+sep+configefile);

try{

printstream pslist=new printstream(new fileoutputstream(list));

if(!cfgfile.exists()&&!cfgfile.createnewfile()){ //配置文件不存在

ps.println("指定的配置文件不存在");

return;

}

if(!readcfg(cfgfile)){ //读入配置文件失败

ps.println("读入配置文件失败");

return;

}

file[] files=dir.listfiles();

if(files.length<2){ //没有要上传的文件

ps.println("指定的目录中没有文件");

return;

}

//逐个文件处理

for(int i=0;i<files.length;i++){

file curfile=files[i];

if(!curfile.isfile()||!getext(curfile.getname()).equals("java")){

continue;

}

pslist.println(curfile.getname());

//当前文件是java文件

string pac=readpac(curfile); //取该文件的包路径

ps.println("读包完成….");

if(pac==null){

// ps.println("文件读出包路径出错");

return;

}

string path=parsepac(pac,cfgfile); //通过package取路径

ps.println("解析完成….");

if(path==null){

ps.println("取文件的保存路径出错");

continue; //跳过这个文件

}

//组装成一个完整的路径

string fullpath=objpath+sep+path+sep+"src"+sep+pac.replace(.,sep);

ps.println("建立拷贝路径:"+fullpath);

if(!copy(curfile,fullpath)){

ps.println("拷贝文件失败"+curfile.getname());

continue;

}

curfile.delete();

ps.println("成功保存一个文件");

}

ps.println("成功保存所有文件");

if(!savecfg(cfgfile)){

ps.println("保存配置文件失败");

return;

}

} catch(ioexception ie){

ie.printstacktrace();

}

}

/**

* 构造函数

*/

public savefile(){

try{

file log=new file(filepath+file.separator+"cf.log");

if(log.exists()){

log.delete();

}

log.createnewfile();

fileoutputstream fos=new fileoutputstream(log);

ps=new printstream(fos);

} catch(ioexception ie){

ie.printstacktrace();

system.out.print("创建日志失败!");

ps=system.out;

}

lines=new arraylist();

}

public static void main(string[] args){

savefile sf=new savefile();

if(args.length==1){

if(args[0].equals("mc")){ //生成配置文件

sf.createcfg();

}

if(args[0].equals("cf")){ //完成分类拷贝工作

sf.excute();

}

} else{

sf.ps.println("请指定参数:\n mc 生成配置文件\n cf 拷贝文件");

return;

}

}

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » Java实现分类文件拷贝-JSP教程,Java技巧及代码
分享到: 更多 (0)

相关推荐

  • 暂无文章