package com.alibaba.doris.dataserver.store.log.db; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import org.apache.commons.lang.StringUtils; import com.alibaba.doris.dataserver.store.log.LogStorageException; /** * @author ajun Email:jack.yuj@alibaba-inc.com */ public class LogFile { public enum AccessMode { R("r"), RW("rw"), RWS("rws"), RWD("rwd"); private AccessMode(String accessMode) { this.accessMode = accessMode; } public String value() { return accessMode; } private String accessMode; } public LogFile(String fileName) { this.fileName = fileName; } public void open(AccessMode accessMode) throws IOException { if (StringUtils.isBlank(fileName)) { throw new RuntimeException("Invalid file name."); } checkFile(accessMode); file = new RandomAccessFile(fileName, accessMode.value()); len = file.length(); this.accessMode = accessMode; } public void close() { if (file != null) { try { file.close(); } catch (IOException e) { throw new LogStorageException(e); } } } public boolean read(ByteBuffer buffer) throws IOException { int pos = buffer.position(); int size = buffer.limit() - pos; if (offset != file.getFilePointer()) { file.seek(offset); } int bytesRead = file.read(buffer.array(), pos + buffer.arrayOffset(), size); if (bytesRead >= 0) { buffer.position(pos + bytesRead); offset += bytesRead; return true; } else { isEof = true; return false; } } public void seek(long newOffset) { this.offset = newOffset; } public long length() { if (AccessMode.R == accessMode) { return len; } else { try { return file.length(); } catch (IOException e) { throw new LogStorageException(e); } } } public void write(ByteBuffer data) throws IOException { int pos = data.position(); int size = data.limit() - pos; if (offset != file.getFilePointer()) { file.seek(offset); } file.write(data.array(), pos + data.arrayOffset(), size); if (needCheckFile) { tempBuffer = ByteBuffer.allocate(size); file.seek(offset); file.read(tempBuffer.array(), 0, size); checkData(data, tempBuffer); } data.position(pos + size); offset += size; } public boolean isEOF() { return offset == length() || isEof == true; } /** * 数据写成功后,检查写入的数据是否正确 * * @param src 待写入的数据。 * @param target 成功写入文件中的数据。 */ private void checkData(ByteBuffer src, ByteBuffer target) { } private void checkFile(AccessMode accessMode) throws IOException { if (AccessMode.R == accessMode) { File f = new File(fileName); if (!f.exists()) { throw new FileNotFoundException(fileName); } } else if (AccessMode.RW == accessMode) { File f = new File(fileName); if (!f.exists() && createIfNotExists) { if (!f.createNewFile()) { throw new LogStorageException("Create file failed! File name:" + this.fileName); } } } } private String fileName; private RandomAccessFile file; private boolean needCheckFile = false; private boolean createIfNotExists = true; private ByteBuffer tempBuffer; private long offset; private long len; private boolean isEof = false; private AccessMode accessMode; }