Java实现文件操作方式有很多,这里写了几个小工具,需要的话可以直接拷贝使用,或者优化后使用。
基本概念
-
FileChannel是一个用读写,映射和操作一个文件的通道,也是Java NIO对应于磁盘等存储设备文件操作的通道。除了读写操作之外,还有裁剪特定大小文件truncate(),强制在内存中的数据刷新到硬盘中去force(),对通道上锁lock()等功能。
-
RandomAccessFile类的主要功能是完成随机读取功能,可以读取指定位置的内容。
之前的File类只是针对文件本身进行操作的,而如果要想对文件内容进行操作,则可以使用RandomAccessFile类,此类属于随机读取类,可以随机读取一个文件中指定位置的数据。 -
在使用FileChannel之前,必须先打开它。但是,我们无法直接打开一个FileChannel,需要通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例。
写文件操作
/**
* 写文件
* @param fileName
* @throws IOException
*/
public void doWrite(String fileName) throws IOException {
outFile = new RandomAccessFile(fileName, "rw");
outChannel = outFile.getChannel();
String newData = "New String to write to file... \n";
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while (buf.hasRemaining()){
outChannel.write(buf);
}
outChannel.close();
System.out.println("Write Over!\n");
}
读文件操作
/**
* 读文件
* @param fileName
* @throws IOException
*/
public void doRead(String fileName) throws IOException {
inFile = new RandomAccessFile(fileName, "rw");
inChannel = inFile.getChannel();
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
System.out.println("Read " + bytesRead);
buf.flip();
while (buf.hasRemaining()){
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
inFile.close();
}
文件拷贝操作
/**
* 拷贝文件
* @param sourceFile
* @param targetFile
* @throws IOException
*/
public void doCopy(String sourceFile, String targetFile) throws IOException {
inFile = new RandomAccessFile(sourceFile, "rw");
inChannel = inFile.getChannel();
RandomAccessFile bFile = new RandomAccessFile(targetFile, "rw");
FileChannel outChannel = bFile.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
System.out.println("Copy over");
inChannel.close();
}
/**
* 按照行读文件
* @param fileName
* @throws IOException
*/
public void doReadLine(String fileName) throws IOException {
inFile = new RandomAccessFile(fileName, "rw");
int lineNum = 0;
inFile.seek(lineNum);
String line = "";
while((line = inFile.readLine())!=null){
line = new String(line.getBytes("UTF-8"), "UTF-8");
System.out.println(line);
}
inFile.close();
}
特殊情况下倒序拷贝文件操作
/**
* 倒序拷贝文件
* @param sourceFile
* @param targetFile
* @throws IOException
*/
public void reverseCopy(String sourceFile, String targetFile) throws IOException {
inFile = new RandomAccessFile(sourceFile, "r");
inChannel = inFile.getChannel();
outFile = new RandomAccessFile(targetFile, "rw");
outChannel = outFile.getChannel();
// 文件长度
long len = inFile.length();
System.out.println("文件开始指针为"+0);
//指针是从0到length-1
long nextEnd = len - 1;
String line;
//seek到最后一个字符
inFile.seek(nextEnd);
int c = -1;
while (nextEnd >= 0) {
c = inFile.read();
//只有行与行之间才有\r\n,这表示读到每一行上一行的末尾的\n,而执行完read后,指针指到了这一行的开头字符
if (c == '\n')
{
line = new String(inFile.readLine().getBytes("UTF-8"), "UTF-8");
System.out.println(line);
writeLine(line, outChannel);
}
// 当文件指针退至文件开始处,输出第一行
if (nextEnd == 0) {
//不需要为下次做准备了,但是因为read()方法指针从0到了1,需重置为0
inFile.seek(0);
line = new String(inFile.readLine().getBytes("UTF-8"), "UTF-8");
System.out.println(line);
writeLine(line, outChannel);
} else {
//为下一次循环做准备
inFile.seek(nextEnd-1);
}
nextEnd--;
}
System.out.println("Reverse Copy over");
outChannel.close();
inChannel.close();
}
private void writeLine(String line, FileChannel outChannel)throws IOException{
// 写入文件
line += "\n";
buf.clear();
buf.put(line.getBytes());
buf.flip();
while (buf.hasRemaining()){
outChannel.write(buf);
}
}
完整代码
小技巧
文件按照行倒序输出可以使用这个命名
perl -e 'print reverse <>' filename
网友评论