基于Java回顾之I/O的使用详解
工作后,使用的技术随着项目的变化而变化,时而c#,时而java,当然还有其他一些零碎的技术。总体而言,c#的使用时间要更长一些,其次是java。我本身对语言没有什么倾向性,能干活的语言,就是好语言。而且从面向对象的角度来看,我觉得c#和java对我来说,没什么区别。
这篇文章主要回顾java中和i/o操作相关的内容,i/o也是编程语言的一个基础特性,java中的i/o分为两种类型,一种是顺序读取,一种是随机读取。
我们先来看顺序读取,有两种方式可以进行顺序读取,一种是inputstream/outputstream,它是针对字节进行操作的输入输出流;另外一种是reader/writer,它是针对字符进行操作的输入输出流。
下面我们画出inputstream的结构
fileinputstream:操作文件,经常和bufferedinputstream一起使用
pipedinputstream:可用于线程间通信
objectinputstream:可用于对象序列化
bytearrayinputstream:用于处理字节数组的输入
linenumberinputstream:可输出当前行数,并且可以在程序中进行修改
下面是outputstream的结构
printstream:提供了类似print和println的接口去输出数据
下面我们来看如何使用stream的方式来操作输入输出
使用inputstream读取文件
使用fileinputstream读取文件信息
public static byte[] readfilebyfileinputstream(file file) throws ioexception
{
bytearrayoutputstream output = new bytearrayoutputstream();
fileinputstream fis = null;
try
{
fis = new fileinputstream(file);
byte[] buffer = new byte[1024];
int bytesread = 0;
while((bytesread = fis.read(buffer, 0, buffer.length)) != -1)
{
output.write(buffer, 0, bytesread);
}
}
catch(exception ex)
{
system.out.println("error occurs during reading " + file.getabsolutefile());
}
finally
{
if (fis !=null) fis.close();
if (output !=null) output.close();
}
return output.tobytearray();
}
使用bufferedinputstream读取文件
public static byte[] readfilebybufferedinputstream(file file) throws exception
{
fileinputstream fis = null;
bufferedinputstream bis = null;
bytearrayoutputstream output = new bytearrayoutputstream();
try
{
fis = new fileinputstream(file);
bis = new bufferedinputstream(fis);
byte[] buffer = new byte[1024];
int bytesread = 0;
while((bytesread = bis.read(buffer, 0, buffer.length)) != -1)
{
output.write(buffer, 0, bytesread);
}
}
catch(exception ex)
{
system.out.println("error occurs during reading " + file.getabsolutefile());
}
finally
{
if (fis != null) fis.close();
if (bis != null) bis.close();
if (output != null) output.close();
}
return output.tobytearray();
}
使用outputstream复制文件
使用fileoutputstream复制文件
public static void copyfilebyfileoutputstream(file file) throws ioexception
{
fileinputstream fis = null;
fileoutputstream fos = null;
try
{
fis = new fileinputstream(file);
fos = new fileoutputstream(file.getname() + ".bak");
byte[] buffer = new byte[1024];
int bytesread = 0;
while((bytesread = fis.read(buffer,0,buffer.length)) != -1)
{
fos.write(buffer, 0, bytesread);
}
fos.flush();
}
catch(exception ex)
{
system.out.println("error occurs during copying " + file.getabsolutefile());
}
finally
{
if (fis != null) fis.close();
if (fos != null) fos.close();
}
}
使用bufferedoutputstream复制文件
public static void copyfilebybufferedoutputstream(file file)throws ioexception
{
fileinputstream fis = null;
bufferedinputstream bis = null;
fileoutputstream fos = null;
bufferedoutputstream bos = null;
try
{
fis = new fileinputstream(file);
bis = new bufferedinputstream(fis);
fos = new fileoutputstream(file.getname() + ".bak");
bos = new bufferedoutputstream(fos);
byte[] buffer = new byte[1024];
int bytesread = 0;
while((bytesread = bis.read(buffer, 0, buffer.length)) != -1)
{
bos.write(buffer, 0, bytesread);
}
bos.flush();
}
catch(exception ex)
{
system.out.println("error occurs during copying " + file.getabsolutefile());
}
finally
{
if (fis != null) fis.close();
if (bis != null) bis.close();
if (fos != null) fos.close();
if (bos != null) bos.close();
}
}
这里的代码对异常的处理非常不完整,稍后我们会给出完整严谨的代码。
下面我们来看reader的结构
这里的reader基本上和inputstream能够对应上。
writer的结构如下
下面我们来看一些使用reader或者writer的例子
使用reader读取文件内容
使用bufferedreader读取文件内容
public static string readfile(string file)throws ioexception
{
bufferedreader br = null;
stringbuffer sb = new stringbuffer();
try
{
br = new bufferedreader(new filereader(file));
string line = null;
while((line = br.readline()) != null)
{
sb.append(line);
}
}
catch(exception ex)
{
system.out.println("error occurs during reading " + file);
}
finally
{
if (br != null) br.close();
}
return sb.tostring();
}
使用writer复制文件
使用bufferedwriter复制文件
public static void copyfile(string file) throws ioexception
{
bufferedreader br = null;
bufferedwriter bw = null;
try
{
br = new bufferedreader(new filereader(file));
bw = new bufferedwriter(new filewriter(file + ".bak"));
string line = null;
while((line = br.readline())!= null)
{
bw.write(line);
}
}
catch(exception ex)
{
system.out.println("error occurs during copying " + file);
}
finally
{
if (br != null) br.close();
if (bw != null) bw.close();
}
}
下面我们来看如何对文件进行随机访问,java中主要使用randomaccessfile来对文件进行随机操作。
创建一个大小固定的文件
创建大小固定的文件
public static void createfile(string file, int size) throws ioexception
{
file temp = new file(file);
randomaccessfile raf = new randomaccessfile(temp, "rw");
raf.setlength(size);
raf.close();
}
向文件中随机写入数据
向文件中随机插入数据
public static void writefile(string file, byte[] content, int startpos, int contentlength) throws ioexception
{
randomaccessfile raf = new randomaccessfile(new file(file), "rw");
raf.seek(startpos);
raf.write(content, 0, contentlength);
raf.close();
}
接下里,我们来看一些其他的常用操作
移动文件
移动文件
public static boolean movefile(string sourcefile, string destfile)
{
file source = new file(sourcefile);
if (!source.exists()) throw new runtimeexception("source file does not exist.");
file dest = new file(destfile);
if (!(new file(dest.getpath()).exists())) new file(dest.getparent()).mkdirs();
return source.renameto(dest);
}
复制文件
复制文件
public static void copyfile(string sourcefile, string destfile) throws ioexception
{
file source = new file(sourcefile);
if (!source.exists()) throw new runtimeexception("file does not exist.");
if (!source.isfile()) throw new runtimeexception("it is not file.");
if (!source.canread()) throw new runtimeexception("file cound not be read.");
file dest = new file(destfile);
if (dest.exists())
{
if (dest.isdirectory()) throw new runtimeexception("destination is a folder.");
else
{
dest.delete();
}
}
else
{
file parentfolder = new file(dest.getparent());
if (!parentfolder.exists()) parentfolder.mkdirs();
if (!parentfolder.canwrite()) throw new runtimeexception("destination can not be written.");
}
fileinputstream fis = null;
fileoutputstream fos = null;
try
{
fis = new fileinputstream(source);
fos = new fileoutputstream(dest);
byte[] buffer = new byte[1024];
int bytesread = 0;
while((bytesread = fis.read(buffer, 0, buffer.length)) != -1)
{
fos.write(buffer, 0, bytesread);
}
fos.flush();
}
catch(ioexception ex)
{
system.out.println("error occurs during copying " + sourcefile);
}
finally
{
if (fis != null) fis.close();
if (fos != null) fos.close();
}
}
复制文件夹
复制文件夹
public static void copydir(string sourcedir, string destdir) throws ioexception
{
file source = new file(sourcedir);
if (!source.exists()) throw new runtimeexception("source does not exist.");
if (!source.canread()) throw new runtimeexception("source could not be read.");
file dest = new file(destdir);
if (!dest.exists()) dest.mkdirs();
file[] arrfiles = source.listfiles();
for(int i = 0; i < arrfiles.length; i++)
{
if (arrfiles[i].isfile())
{
bufferedreader reader = new bufferedreader(new filereader(arrfiles[i]));
bufferedwriter writer = new bufferedwriter(new filewriter(destdir + "/" + arrfiles[i].getname()));
string line = null;
while((line = reader.readline()) != null) writer.write(line);
writer.flush();
reader.close();
writer.close();
}
else
{
copydir(sourcedir + "/" + arrfiles[i].getname(), destdir + "/" + arrfiles[i].getname());
}
}
}
删除文件夹
删除文件夹
public static void del(string filepath)
{
file file = new file(filepath);
if (file == null || !file.exists()) return;
if (file.isfile())
{
file.delete();
}
else
{
file[] arrfiles = file.listfiles();
if (arrfiles.length > 0)
{
for(int i = 0; i < arrfiles.length; i++)
{
del(arrfiles[i].getabsolutepath());
}
}
file.delete();
}
}
获取文件夹大小
获取文件夹大小
public static long getfoldersize(string dir)
{
long size = 0;
file file = new file(dir);
if (!file.exists()) throw new runtimeexception("dir does not exist.");
if (file.isfile()) return file.length();
else
{
string[] arrfilename = file.list();
for (int i = 0; i < arrfilename.length; i++)
{
size += getfoldersize(dir + "/" + arrfilename[i]);
}
}
return size;
}
将大文件切分为多个小文件
将大文件切分成多个小文件
public static void splitfile(string filepath, long unit) throws ioexception
{
file file = new file(filepath);
if (!file.exists()) throw new runtimeexception("file does not exist.");
long size = file.length();
if (unit >= size) return;
int count = size % unit == 0 ? (int)(size/unit) : (int)(size/unit) + 1;
string newfile = null;
fileoutputstream fos = null;
fileinputstream fis =null;
byte[] buffer = new byte[(int)unit];
fis = new fileinputstream(file);
long startpos = 0;
string countfile = filepath + "_count";
printwriter writer = new printwriter(new filewriter( new file(countfile)));
writer.println(filepath + "\t" + size);
for (int i = 1; i <= count; i++)
{
newfile = filepath + "_" + i;
startpos = (i - 1) * unit;
system.out.println("creating " + newfile);
fos = new fileoutputstream(new file(newfile));
int bytesread = fis.read(buffer, 0, buffer.length);
if (bytesread != -1)
{
fos.write(buffer, 0, bytesread);
writer.println(newfile + "\t" + startpos + "\t" + bytesread);
}
fos.flush();
fos.close();
system.out.println("startpos:" + i*unit + "; endpos:" + (i*unit + bytesread));
}
writer.flush();
writer.close();
fis.close();
}
将多个小文件合并为一个大文件
将多个小文件合并成一个大文件
public static void linkfiles(string countfile) throws ioexception
{
file file = new file(countfile);
if (!file.exists()) throw new runtimeexception("count file does not exist.");
bufferedreader reader = new bufferedreader(new filereader(file));
string line = reader.readline();
string newfile = line.split("\t")[0];
long size = long.parselong(line.split("\t")[1]);
randomaccessfile raf = new randomaccessfile(newfile, "rw");
raf.setlength(size);
fileinputstream fis = null;
byte[] buffer = null;
while((line = reader.readline()) != null)
{
string[] arrinfo = line.split("\t");
fis = new fileinputstream(new file(arrinfo[0]));
buffer = new byte[integer.parseint(arrinfo[2])];
long startpos = long.parselong(arrinfo[1]);
fis.read(buffer, 0, integer.parseint(arrinfo[2]));
raf.seek(startpos);
raf.write(buffer, 0, integer.parseint(arrinfo[2]));
fis.close();
}
raf.close();
}
执行外部命令
执行外部命令
public static void execexternalcommand(string command, string argument)
{
process process = null;
try
{
process = runtime.getruntime().exec(command + " " + argument);
inputstream is = process.getinputstream();
bufferedreader br = new bufferedreader(new inputstreamreader(is));
string line = null;
while((line = br.readline()) != null)
{
system.out.println(line);
}
}
catch(exception ex)
{
system.err.println(ex.getmessage());
}
finally
{
if (process != null) process.destroy();
}
}