/* * (C) 2007-2012 Alibaba Group Holding Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * Authors: * wuhua <wq163@163.com> , boyan <killme2008@gmail.com> */ package com.taobao.metamorphosis.server.transaction.store; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.concurrent.atomic.AtomicInteger; /** * ������һ�������ļ� * * @author dogun (yuexuqiang at gmail.com) */ class DataFile { private final int number; private final File file; private final AtomicInteger referenceCount = new AtomicInteger(0); protected FileChannel fc; protected RandomAccessFile raf; /** * ���캯�������ָ�����ļ������ҽ�ָ��ָ���ļ���β * * @param file * @throws IOException */ DataFile(final File file) throws IOException { this(file, 0, false); } DataFile(final File file, final int number) throws IOException { this(file, number, false); } int getNumber() { return this.number; } /** * ���캯�������ָ�����ļ������ҽ�ָ��ָ���ļ���β * * @param file * @throws IOException */ DataFile(final File file, final int number, final boolean force) throws IOException { this.file = file; this.number = number; this.raf = new RandomAccessFile(file, force ? "rws" : "rw"); this.fc = this.raf.getChannel(); // ָ���Ƶ���� this.fc.position(this.fc.size()); } /** * ����ļ��Ĵ�С * * @return �ļ��Ĵ�С * @throws IOException */ long getLength() throws IOException { return this.fc.size(); } void truncate(final long size) throws IOException { this.fc.truncate(size); } /** * ��ȡ�ļ�����޸�ʱ�� * * @return * @throws IOException */ long lastModified() throws IOException { return this.file.lastModified(); } /** * ɾ���ļ� * * @return �Ƿ�ɾ���ɹ� * @throws IOException */ boolean delete() throws IOException { this.close(); return this.file.delete(); } /** * ǿ�ƽ�����д��Ӳ�� * * @throws IOException */ void force() throws IOException { if (this.fc.isOpen()) { this.fc.force(false); } } /** * �ر��ļ� * * @throws IOException */ void close() throws IOException { try { if (this.fc != null) { this.fc.close(); } } finally { if (this.raf != null) { this.raf.close(); } } } /** * ���ļ���ȡ���ݵ�bf��ֱ���������߶����ļ���β�� <br /> * �ļ���ָ�������ƶ�bf�Ĵ�С * * @param bf * @throws IOException */ void read(final ByteBuffer bf) throws IOException { while (bf.hasRemaining()) { final int l = this.fc.read(bf); if (l < 0) { break; } } } /** * ���ļ����ƶ�λ�ö�ȡ���ݵ�bf��ֱ���������߶����ļ���β�� <br /> * �ļ�ָ�벻���ƶ� * * @param bf * @param offset * @throws IOException */ void read(final ByteBuffer bf, final long offset) throws IOException { int size = 0; while (bf.hasRemaining()) { final int l = this.fc.read(bf, offset + size); size += l; if (l < 0) { break; } } } /** * д��bf���ȵ����ݵ��ļ����ļ�ָ�������ƶ� * * @param bf * @return д�����ļ�position * @throws IOException */ long write(final ByteBuffer bf) throws IOException { while (bf.hasRemaining()) { final int l = this.fc.write(bf); if (l < 0) { break; } } return this.fc.position(); } /** * ��ָ��λ��д��bf���ȵ����ݵ��ļ����ļ�ָ��<b>����</b>����ƶ� * * @param offset * @param bf * @throws IOException */ void write(final long offset, final ByteBuffer bf) throws IOException { int size = 0; while (bf.hasRemaining()) { final int l = this.fc.write(bf, offset + size); size += l; if (l < 0) { break; } } } /** * ���ļ�����һ�����ü��� * * @return ���Ӻ�����ü��� */ int increment() { return this.referenceCount.incrementAndGet(); } /** * �����ļ����� * * @param i */ void setReferenceCount(final int i) { this.referenceCount.set(i); } /** * ���ļ�����һ�����ü��� * * @return ���ٺ�����ü��� */ int decrement() { return this.referenceCount.decrementAndGet(); } /** * �ļ��Ƿ���ʹ�ã����ü����Ƿ���0�ˣ� * * @return �ļ��Ƿ���ʹ�� */ boolean isUnUsed() { return this.getReferenceCount() <= 0; } long position() throws IOException { return this.fc.position(); } /** * ������ü�����ֵ * * @return ���ü�����ֵ */ int getReferenceCount() { return this.referenceCount.get(); } @Override public String toString() { String result = null; try { result = this.file.getName() + " , length = " + this.getLength() + " refCount = " + this.referenceCount + " position:" + this.fc.position(); } catch (final IOException e) { result = e.getMessage(); } return result; } }