您的位置:首页 > 其它

外部归并排序(1)——通道映射方法的文件读写

2013-12-27 23:17 691 查看

1、核心类

映射方式读取文件涉及的核心类:java.nio.channels.FileChannel。该类通过 FileInputStream 实例的 getChannel 方法所获得的通道将允许进行读取操作;通过 FileOutputStream 实例的 getChannel 方法所获得的通道将允许进行写入操作。
对于该类的其他详细解释,可参见JDK_API_1_6_zh_CN.CHM的FileChannel类。

2、输入流InputChannelImpl

该类构造函数有两个参数:输入文件,读取输入文件的byte模板的大小(即一次读取多长的字符)。

该类提供三个方法:打开一个文件来读取(open())、读取下一节数据(read_next())和判断文件是否读完(end_of_stream())。

源代码如下:

package com.emms.raw.channel.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;

import org.apache.log4j.Logger;

/**
* 通过映射方式读取文件。
* @author Administrator
*
*/
public class InputChannelImpl
{
/**
* 打印日志对象。
*/
Logger logger = Logger.getLogger(InputChannelImpl.class);

/**
* 文件输入流。
*/
private FileInputStream fileInputStream;

/**
* 输入流对于的文件通道。
*/
private FileChannel fileChannel;

/**
* 作为映射模板的字节缓冲区。
*/
private ByteBuffer byteBuffer;

/**
*
*/
private int byteBufferSize;

/**
* 用户输入的文件。
*/
private File file;

/**
* 从文件中读取的映射模板大小的字节数组。
*/
private byte[] bytelist;

/**
* 是否读取完毕。
*/
private boolean isEnd = true;

/**
* 对应文件的输入流。
* @param file 输入文件。
* @param size 读取输入文件的byte模板的大小,即一次读取多长的字符。
*/
public InputChannelImpl(File file,int size)
{
this.file = file;
this.byteBufferSize = size;
}

/**
* 打开一个文件来读取.
*/
public void open()
{
try
{
fileInputStream = new FileInputStream(this.file);
}
catch (FileNotFoundException e)
{
logger.error("Open File : " + file.getPath() + " failed",e);
}

fileChannel = fileInputStream.getChannel();
logger.info("Open File : " + file.getPath() + " success");
}

/**
* 读取下一个.
*/
public byte[] read_next()
{
if(fileChannel.isOpen())
{
byteBuffer = ByteBuffer.allocate(byteBufferSize);

try
{
fileChannel.read(byteBuffer);
}
catch (IOException e)
{
logger.error("Read data failed, because : IOException",e);
}
bytelist = byteBuffer.array();
}

logger.info("Return bytelist length: " + bytelist.length
+ ". Read from " + file.getPath());
return bytelist;
}

/**
* 当一个判断return true时,说明到达流的末尾.
* @return
*/
public boolean end_of_stream()
{

try
{
if(fileChannel.position() < fileChannel.size())
{
isEnd = false;
}
else
{
isEnd = true;
close();
}

}
catch (ClosedChannelException e)
{
logger.info("The fileChannel is Closed");
}
catch (IOException e)
{
logger.error("Get fileChannel position failed, because : IOException",e);
}

logger.info("Return isEnd : " + isEnd + ". Read from " + file.getPath());
return isEnd;
}

/**
* 关闭输入流和读取数据的通道。
*/
private void close()
{
if(fileChannel != null)
{
try
{
fileChannel.close();
}
catch (IOException e)
{
logger.error("Close fileChannel failed, because : IOException",e);
}
}

if(fileInputStream != null)
{
try
{
fileInputStream.close();
}
catch (IOException e)
{
logger.error("Close fileInputStream failed, because : IOException",e);
}
}
}

}

3、输出流OutputChannelImpl

该类构造函数有一个参数:需要创建的文件路径字符串,文件路径字符串的合法性需要调用者校验。
该类提供三个方法:创建一个新文件(create())、在流中写入一个元素(write())和关闭一个流(close())。
源代码如下:
package com.emms.raw.channel.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.log4j.Logger;

/**
* 通过映射方式输出文件。
* @author Administrator
*
*/
public class OutputChannelImpl
{
/**
* 打印日志对象。
*/
Logger logger = Logger.getLogger(OutputChannelImpl.class);

/**
* 需要创建的文件路径。
*/
private String filePath;

/**
* 通过文件路径,创建的文件。
*/
private File file;

/**
* 输出流。
*/
private FileOutputStream fileOutputStream;

/**
* 输出流对于的文件通道。
*/
private FileChannel fileChannel;

/**
* 作为映射模板的字节缓冲区。
*/
private ByteBuffer byteBuffer;

/**
* 构造方法,必须设置所需创建的文件路径。
* @param filePath
*/
public OutputChannelImpl(String filePath)
{
this.filePath = filePath;
}

/**
* 创建一个新文件.
*/
public void create()
{
file = new File(this.filePath);
try
{
fileOutputStream = new FileOutputStream(file);
}
catch (FileNotFoundException e)
{
logger.error("Create File : " + this.filePath + " failed",e);
}

fileChannel = fileOutputStream.getChannel();
logger.info("Create File : " + this.filePath + " success");
}

/**
* 在流中写入一个元素.
* @param byteList
*/
public void write(byte[] byteList)
{
if(fileChannel.isOpen())
{
byteBuffer = ByteBuffer.wrap(byteList);
try
{
fileChannel.write(byteBuffer);
}
catch (IOException e)
{
logger.error("Write byteList length : " + byteList.length + ". to "
+ this.filePath + " failed, because : IOException",e);
}
logger.info("Write byteList length : " + byteList.length + ". to "
+ this.filePath + " success");
}
else
{
logger.info("FileChannel is not opened");
}
}

/**
* 关闭一个流.
*/
public void close()
{
if(fileChannel != null)
{
try
{
fileChannel.close();
}
catch (IOException e)
{
logger.error("Close fileChannel failed, because : IOException",e);
}
}

if(fileOutputStream != null)
{
try
{
fileOutputStream.close();
}
catch (IOException e)
{
logger.error("Close fileOutputStream failed, because : IOException",e);
}
}

}

}


[/code]

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: