fatfile.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 211 行
JAVA
211 行
/**
* $Id: FatFile.java,v 1.2 2003/11/29 03:33:28 gbin Exp $
*/
package org.jnode.fs.fat;
import java.io.IOException;
import org.jnode.driver.block.BlockDeviceAPI;
import org.jnode.fs.FSFile;
/**
* A File instance is the in-memory representation of a single file (chain of
* clusters).
*
* @author epr
*/
public class FatFile extends FatObject implements FSFile {
private long startCluster;
private long length;
private FatDirectory dir;
private int clusterSize;
private boolean isDir;
private final FatDirEntry myEntry;
public FatFile(FatFileSystem fs, FatDirEntry myEntry, long startCluster, long length, boolean isDir) {
super(fs);
this.myEntry = myEntry;
this.startCluster = startCluster;
this.length = length;
this.clusterSize = fs.getClusterSize();
this.isDir = isDir;
}
public synchronized void read(long fileOffset, byte[] dest, int destOfs, int len) throws IOException {
final long max = (isDir) ? getLengthOnDisk() : getLength();
if (fileOffset + len > max) {
throw new IOException("Cannot read beyond the EOF");
}
final FatFileSystem fs = getFatFileSystem();
final long[] chain = fs.getFat().getChain(startCluster);
final BlockDeviceAPI api = fs.getBlockDeviceAPI();
int chainIdx = (int)(fileOffset / clusterSize);
if (fileOffset % clusterSize != 0) {
int clusOfs = (int)(fileOffset % clusterSize);
int size = Math.min(len, (int)(clusterSize - (fileOffset % clusterSize) - 1));
api.read(getDevOffset(chain[chainIdx], clusOfs), dest, destOfs, size);
fileOffset += size;
len -= size;
destOfs += size;
chainIdx++;
}
while (len > 0) {
int size = Math.min(clusterSize, len);
api.read(getDevOffset(chain[chainIdx], 0), dest, destOfs, size);
len -= size;
destOfs += size;
chainIdx++;
}
}
public synchronized void write(long fileOffset, byte[] src, int srcOfs, int len) throws IOException {
final long max = (isDir) ? getLengthOnDisk() : getLength();
if (fileOffset > max) {
throw new IOException("Cannot write beyond the EOF");
}
if (fileOffset + len > max) { // this is too short increase the size of the file
setLength(fileOffset + len);
}
final FatFileSystem fs = getFatFileSystem();
final long[] chain = fs.getFat().getChain(getStartCluster());
final BlockDeviceAPI api = fs.getBlockDeviceAPI();
int chainIdx = (int)(fileOffset / clusterSize);
if (fileOffset % clusterSize != 0) {
int clusOfs = (int)(fileOffset % clusterSize);
int size = Math.min(len, (int)(clusterSize - (fileOffset % clusterSize) - 1));
api.write(getDevOffset(chain[chainIdx], clusOfs), src, srcOfs, size);
fileOffset += size;
len -= size;
srcOfs += size;
chainIdx++;
}
while (len > 0) {
int size = Math.min(clusterSize, len);
api.write(getDevOffset(chain[chainIdx], 0), src, srcOfs, size);
len -= size;
srcOfs += size;
chainIdx++;
}
}
/**
* Sets the length.
* @param length The length to set
*/
public synchronized void setLength(long length)
throws IOException {
if (this.length == length) {
// Do nothing
return;
}
final FatFileSystem fs = getFatFileSystem();
final Fat fat = fs.getFat();
final int nrClusters = (int)((length + clusterSize-1) / clusterSize);
if (this.length == 0) {
final long[] chain = fat.allocNew(nrClusters);
this.startCluster = chain[0];
this.myEntry.setStartCluster((int)startCluster);
} else {
final long[] chain = fs.getFat().getChain(startCluster);
if (nrClusters != chain.length) {
if (nrClusters > chain.length) {
// Grow
int count = nrClusters - chain.length;
while (count > 0) {
fat.allocAppend(getStartCluster());
count--;
}
} else {
// Shrink
fat.setEof(chain[nrClusters-1]);
for (int i = nrClusters; i < chain.length; i++) {
fat.setFree(chain[i]);
}
}
}
}
this.length = length;
this.myEntry.updateLength(length);
}
/**
* Returns the length.
* @return long
*/
public long getLength() {
return length;
}
/**
* Gets the size this file occupies on disk
* @return long
*/
public long getLengthOnDisk() {
if (this.length == 0) {
return 0;
} else {
final FatFileSystem fs = getFatFileSystem();
final long[] chain = fs.getFat().getChain(getStartCluster());
return ((long)chain.length) * fs.getClusterSize();
}
}
/**
* Returns the startCluster.
* @return long
*/
public long getStartCluster() {
return startCluster;
}
/**
* Gets the directory contained in this file.
* @return Directory
*/
public synchronized FatDirectory getDirectory()
throws IOException {
if (dir == null) {
final FatFileSystem fs = getFatFileSystem();
dir = new FatLfnDirectory(fs, this);
}
return dir;
}
/**
* Calculates the device offset (0-based) for the given cluster and offset
* within the cluster.
* @param cluster
* @param clusterOffset
* @return long
*/
protected long getDevOffset(long cluster, int clusterOffset) {
final FatFileSystem fs = getFatFileSystem();
final long filesOffset = FatUtils.getFilesOffset(fs.getBootSector());
return filesOffset + clusterOffset + ((cluster - FatUtils.FIRST_CLUSTER) * clusterSize);
}
/**
* Flush any changes in this file to persistent storage
* @throws IOException
*/
protected void flush()
throws IOException {
if (dir != null) {
dir.flush();
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?