package ringBuffer.reader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.LinkedHashMap;
public class MsgReader {
public static void main(String[] args) {
long start = System.currentTimeMillis();
MsgReader smh = new MsgReader();
Reader rd = smh.new Reader();
try {
new Thread(rd).start();
for (Integer j = 0; j < 5; j++) {
LinkedHashMap<Integer, String> msgs = rd.getMsg(j);
System.out.println(" msg : " + msgs.get(0));
}
rd.interrupt();
rd.join(); // 这里主线程会否比子线程先跑完? 加上join
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" last : " + (System.currentTimeMillis() - start));
System.exit(0);
}
class Reader extends Thread {
int bufferSize = 2 * 1024 * 1024;
private byte[] buffer = new byte[bufferSize];
private Integer filePos = 0; // 文件指针
private Integer bufPos = 0; // 缓冲区指针
String outputFile = "F:\\test\\ringBuf.txt";
private int fileLength = 0;
boolean isRead = true;
long stepNum = 0;
RandomAccessFile raf;
LinkedHashMap<Long, LinkedHashMap<Integer, String>> lastJobMsgs = new LinkedHashMap<Long, LinkedHashMap<Integer, String>>();
public Reader() {
try {
raf = new RandomAccessFile(outputFile, "rw");
fileLength = (int) raf.length(); // 中间文件一般不会超过int大小?
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
while (isRead) {
raf.seek(filePos);
int readLength= 0 ;
if ((fileLength - filePos + bufPos) > bufferSize) {
raf.read(buffer, bufPos, bufferSize - bufPos);
filePos = filePos + bufferSize - bufPos;
readLength = bufferSize ; //满读
} else {
readLength = fileLength - filePos;
raf.read(buffer, bufPos, readLength);//部分读
readLength = bufPos + readLength ;
filePos = (int) raf.length();
}
bufPos= 0; //每次新读取处理都从buf的0处开始
fromBufToMsg(buffer, bufPos, readLength);
isRead = false;
this.notifyAll();
}
}
}
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void fromBufToMsg(byte[] buffer, int pos, int len) throws IOException {
String str = new String(buffer,pos, len);
String[] map = str.split("R");
if (map.length > 1) { // 包含结果
} else {
String[] superSteps = str.split("S");
for (int i = 0; i < superSteps.length; i++) {
LinkedHashMap<Integer, String> keyValues = new LinkedHashMap<Integer, String>();
if (i == superSteps.length - 1) { // 最后一组可能取不全,要做处理
if (str.lastIndexOf("S") != (str.length() - 1)) {
System.arraycopy(buffer, bufPos, buffer, 0,
(bufferSize - bufPos)); // 把最后Step的信息放到开头
bufPos = bufferSize - bufPos;
break;
}
bufPos = 0; // 恰好取整
}
String[] vertexMsgs = superSteps[i].split("V");
for (String vertexMsg : vertexMsgs) {
String[] keyMsgs = vertexMsg.split("-");
Integer key = new Integer(keyMsgs[0]);
if (keyMsgs.length < 2)
continue;
keyValues.put(key, keyMsgs[1]);
}
bufPos = bufPos + superSteps[i].length() + 1;
lastJobMsgs.put(stepNum++, keyValues);
}
}
return;
}
public LinkedHashMap<Integer, String> getMsg(long i) {
synchronized (this) {
try {
while (lastJobMsgs.get(i) == null) {
isRead = true;
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return lastJobMsgs.get(i);
}
}
}
}
分享到:
相关推荐
通过移动读指针和写指针就可以实现缓冲区的数据读取和写入。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以...
VB 读取磁盘扇区 VB 读取磁盘扇区(512 Byte),直接代码读取,不用外部 DLL、OCX、API,这个代码仅仅演示读取,所以没有危险性 '由于代码针对 FAT 格式了写的,所以只能用于 FAT
VB读取磁盘扇区.rarVB读取磁盘扇区.rarVB读取磁盘扇区.rar
读取磁盘信息,包括磁盘空间,序列号等
VC 写windows下直接读取磁盘分区信息,为下一步的数据恢复打基础
可从指定编号的扇区开始读取指定个字节的数据,支持硬盘、U盘和SD卡的数据读取。
Windows读取Mac格式磁盘软件,Windows读取Mac格式磁盘软件,Windows读取Mac格式磁盘软件,Windows读取Mac格式磁盘软件,Windows读取Mac格式磁盘软件,Windows读取Mac格式磁盘软件,Windows读取Mac格式磁盘软件,...
用C语言读取磁盘文件位置链表的方法.通过这个可以了解C语言的磁盘定位方法
VB 读取磁盘扇区(512 Byte)[readfatdisk.rar]-精品源代码
用c语言读取磁盘文件代码 用c语言读取磁盘文件代码
在linux下,有时候为了获取磁盘厂商名称,以及相关信息,以利用这些信息对不同的磁盘做相应的处理。本代码实例调用了一个IOCTL命令读取磁盘厂商信息,以及磁盘序列号,并打印出来。在2.6版本上测试过!
WindowsDisk-读取磁盘扇区080616.rar
磁盘驱动读取系统的分析设计.pdf
磁盘结构损坏且无法读取如何修复https://jingyan.baidu.com/article/e75057f21e8cd2ebc91a8913.html
VB读取磁盘序列号,简单操作,适合新手加在一些小程序里面。相当好的哟,呵,
无法读取源文件或磁盘完美解决工具 无法读取源文件或磁盘完美解决工具
该代码读取了本地磁盘的磁盘总量和使用量等信息,并用饼图的形式表现出来。
读取磁盘总容量以及剩余容量
总共2个程序实例,可以在linux下,获取磁盘设备号,以及对应磁盘厂商名称,以及相关信息本代码实例调用了一个IOCTL命令读取磁盘厂商信息,以及磁盘序列号,并打印出来。