在lab5中要求利用多种I/O实现文件读写,并根据Strategy设计模式在多种I/O策略之间切换。
输入策略
一、Reader
利用Filereader 和BufferedReader,根据BuffredReader的readLine方法逐行直接读取。
package circularorbit:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class InReader implements InStrategy {
FileReader fr;
BufferedReader br;
/**.
* 构造函数
* @param file != null
*/
public InReader(File file) {
try {
fr = new FileReader(file.getAbsoluteFile());
br = new BufferedReader(fr);
} catch (IOException e) {
e.printStackTrace();
System.out.println("file not find");
}
}
@Override
public String readLine() {
try {
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void close() {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、Scanner
利用scanner的hasNextLine方法判断文件是否读完,根据scanner的nextLine方法逐行读取文件。
package circularorbit;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class InScanner implements InStrategy {
Scanner sc;
/**.
* 构造函数
* @param file != null
*/
public InScanner(File file) {
try {
sc = new Scanner(file.getAbsoluteFile());
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("file not find");
}
}
@Override
public String readLine() {
if (sc.hasNextLine()) {
return sc.nextLine();
}
return null;
}
@Override
public void close() {
sc.close();
}
}
三、Stream
利用FileInputStream和DataInputStream,根据DataInputStream的readLine方法逐行读取文件。
package circularorbit;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
public class InStream implements InStrategy {
FileInputStream fileInputStream;
DataInputStream dis;
/**.
* 构造函数
* @param file != null
*/
public InStream(File file) {
try {
fileInputStream = new FileInputStream(file.getAbsoluteFile());
dis = new DataInputStream(fileInputStream);
} catch (IOException e) {
e.printStackTrace();
System.out.println("file not find");
}
}
@Override
public String readLine() {
try {
return dis.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void close() {
try {
fileInputStream.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、Channel
利用ByteBuffer缓存字节。利用FileChannel的read方法读取整个文件,利用ByteBuffer的hasRemainning方法判断是否读完,get方法获取文件每一个字节。
FileInputStream fin = new FileInputStream(file);
FileChannel fc = fin.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
fc.read(buffer);
buffer.flip();
while (buffer.hasRemaining()) {
byte b = buffer.get();
}
fin.close();
关于Strategy模式
为Input设计一个InStrategy的接口,接口中设计:1.返回字符串的readLine方法;2.close方法。
package circularorbit;
public interface InStrategy {
public String readLine();
public void close();
}
建立InReader,InScanner,InStream三个类实现InStrategy接口。将InStrategy接口封装在InContext类中。
package circularorbit;
public class InContext {
InStrategy inStrategy;
public InContext(InStrategy inStr) {
this.inStrategy = inStr;
}
public String readLine() {
return this.inStrategy.readLine();
}
public void close() {
this.inStrategy.close();
}
}
调用方法如下:
InContext fileReader = null;
System.out.println("choose a output strategy:");
System.out.println("1.Reader");
System.out.println("2.Scanner");
System.out.println("3.Stream");
Scanner in = new Scanner(System.in);
String input = in.nextLine();
if (input.equals("1")) {
fileReader = new InContext(new InReader(file));
} else if (input.equals("2")) {
fileReader = new InContext(new InScanner(file));
} else {
fileReader = new InContext(new InStream(file));
}
输出策略
一、Writer
利用FileWriter和BufferedWriter。BufferedWriter的write方法直接写入文件。
package circularorbit;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class OutWriter implements OutStrategy {
FileWriter fw;
BufferedWriter bw;
/**.
* 构造函数
* @param file != null
*/
public OutWriter(File file) {
try {
fw = new FileWriter(file.getAbsoluteFile());
bw = new BufferedWriter(fw);
} catch (IOException e) {
e.printStackTrace();
System.out.println("file not find");
}
}
@Override
public void write(String string) {
try {
bw.write(string);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void close() {
try {
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、Stream
利用FileOutputStream。每次将需要写入的字符串转换为字节数组,FileOutputStream的write方法中传入这个字符数组即可。
package circularorbit;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutStream implements OutStrategy {
FileOutputStream fileOutStream;
/**.
* 构造函数
* @param file != null
*/
public OutStream(File file) {
try {
fileOutStream = new FileOutputStream(file.getAbsoluteFile());
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("file not find");
}
}
@Override
public void write(String string) {
byte[] b = string.getBytes();
try {
fileOutStream.write(b);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void close() {
try {
fileOutStream.flush();
fileOutStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、Channel
Channel的write方法中传入ByteBuffer,这个ByteBuffer中是需要写入的字符串的字节形式。
package circularorbit;
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;
public class OutNio implements OutStrategy {
FileChannel channel;
ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
/**.
* 构造函数
* @param file != null
*/
public OutNio(File file) {
try {
FileOutputStream fos = new FileOutputStream(file.getAbsoluteFile());
channel = fos.getChannel();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("file not found");
}
}
@Override
public void write(String string) {
byteBuffer.put(string.getBytes());
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
try {
channel.write(byteBuffer);
} catch (IOException e) {
e.printStackTrace();
}
}
byteBuffer.clear();
}
@Override
public void close() {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
关于output的strategy模式
与前文input的strategy模式类似,有一个封装在OutContext类中的OutStrategy接口,建立OutWriter,OutStream,OutNio类实现接口。
package circularorbit;
public interface OutStrategy {
public void write(String string);
public void close();
}
调用方法如下,以AtomStructure为例:
OutContext fileWriter = null;
System.out.println("choose a output strategy:");
System.out.println("1.Writer");
System.out.println("2.Stream");
System.out.println("3.Nio");
Scanner in = new Scanner(System.in);
String input = in.nextLine();
if (input.equals("1")) {
fileWriter = new OutContext(new OutWriter(file));
} else if (input.equals("2")) {
fileWriter = new OutContext(new OutStream(file));
} else {
fileWriter = new OutContext(new OutNio(file));
}
Atom atom = (Atom) c.getCentralObject();
fileWriter.write("ElementName ::= " + atom.getName() + "\r\n");
int trackNum = c.getTrackObjects().size();
fileWriter.write("NumberOfTracks ::= " + trackNum + "\r\n");
fileWriter.write("NumberOfElectron ::= ");
for (int i = 0; i < trackNum - 1; i++) {
int electronNum = c.getTrackObjects().get(i).getObjs().size();
fileWriter.write(i + 1 + "/" + electronNum + ";");
}
fileWriter
.write(trackNum + "/" + c.getTrackObjects().get(trackNum - 1).getObjs().size() + "\r\n");
fileWriter.close();