ext2filesystem.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 205 行
JAVA
205 行
/*
* $Id: Ext2FileSystem.java,v 1.6 2004/01/09 21:54:08 blindidiot Exp $
*/
package org.jnode.fs.ext2;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.jnode.driver.ApiNotFoundException;
import org.jnode.driver.Device;
import org.jnode.driver.block.FSBlockDeviceAPI;
import org.jnode.fs.FSEntry;
import org.jnode.fs.FileSystem;
import org.jnode.fs.FileSystemException;
import org.jnode.fs.ext2.cache.Block;
import org.jnode.fs.ext2.cache.BlockCache;
/**
* @author Andras Nagy
*
*/
public class Ext2FileSystem implements FileSystem {
/*
* remarks about the code: -wherever the number (count) of some structure is known (e.g. number of block groups), I use an array to store them
*/
private final Device device;
private final FSBlockDeviceAPI api;
private boolean closed;
private Superblock superblock;
private GroupDescriptor groupDescriptors[];
private int groupCount;
private BlockCache cache;
private final Logger log = Logger.getLogger(getClass());
/**
* Constructor for Ext2FileSystem.
*/
public Ext2FileSystem(Device device) throws FileSystemException {
if (device == null) {
throw new FileSystemException("null device!");
}
this.device = device;
try {
this.api = (FSBlockDeviceAPI) device.getAPI(FSBlockDeviceAPI.class);
} catch (ApiNotFoundException ex) {
throw new FileSystemException("Device is not a partition", ex);
}
closed = false;
byte data[];
//points to the byte where the fs metadata parsing has reached
long byteIndex;
cache = new BlockCache(50, (float) 0.75);
try {
data = new byte[Superblock.SUPERBLOCK_LENGTH];
//skip the first 1024 bytes (bootsector) and read the superblock
byteIndex = 1024;
api.read(byteIndex, data, 0, Superblock.SUPERBLOCK_LENGTH);
byteIndex += Superblock.SUPERBLOCK_LENGTH;
superblock = new Superblock(data);
//read the group descriptors
groupCount = (int) Math.ceil((double) superblock.getBlocksCount() / (double) superblock.getBlocksPerGroup());
groupDescriptors = new GroupDescriptor[groupCount];
for (int i = 0; i < groupCount; i++) {
data = new byte[GroupDescriptor.GROUPDESCRIPTOR_LENGTH];
api.read(byteIndex + i * GroupDescriptor.GROUPDESCRIPTOR_LENGTH, data, 0, GroupDescriptor.GROUPDESCRIPTOR_LENGTH);
groupDescriptors[i] = new GroupDescriptor(data);
}
byteIndex += superblock.getBlockSize();
/*
* //go through each block group //XXX byteIndex = ... //read the block bitmap //XXX what if it doesn't fit? data = new byte[(int)superblock.getBlockSize()]; api.read( byteIndex, data, 0,
* (int)superblock.getBlockSize()); FSBitmap blockBitmap = new FSBitmap(data); byteIndex += superblock.getBlockSize();
*
* //read the inode bitmap //XXX what if it doesn't fit? data = new byte[(int)superblock.getBlockSize()]; api.read( byteIndex, data, 0, (int)superblock.getBlockSize()); FSBitmap
* inodeBitmap = new FSBitmap(data); byteIndex += superblock.getBlockSize();
*
* //read the inode table //XXX what if it doesn't fit? Inode inodeTable[] = new Inode[ (int)superblock.getInodesCount() ];
*/
} catch (FileSystemException e) {
throw e;
} catch (Exception e) {
throw new FileSystemException(e);
}
log.debug("Ext2fs filesystem constructed sucessfully");
log.debug(
" superblock: #blocks: "
+ superblock.getBlocksCount()
+ "\n"
+ " #blocks/group: "
+ superblock.getBlocksPerGroup()
+ "\n"
+ " #block groups: "
+ groupCount
+ "\n"
+ " block size: "
+ superblock.getBlockSize()
+ "\n"
+ " #inodes: "
+ superblock.getINodesCount()
+ "\n"
+ " #inodes/group: "
+ superblock.getINodesPerGroup());
}
/**
* @see org.jnode.fs.FileSystem#close()
*/
public void close() throws IOException {
flush();
closed = true;
//XXX
throw new IOException("Yet unimplemented");
}
/**
* Flush all changed structures to the device.
*
* @throws IOException
*/
public void flush() throws IOException {
//XXX
throw new IOException("Yet unimplemented");
}
/**
* @see org.jnode.fs.FileSystem#getDevice()
*/
public Device getDevice() {
return device;
}
/**
* @see org.jnode.fs.FileSystem#getRootEntry()
*/
public FSEntry getRootEntry() throws IOException {
log.debug("Ext2FileSystem.getRootEntry()");
try {
if (!closed) {
return new Ext2Entry(getINode(Ext2Constants.EXT2_ROOT_INO), "/", Ext2Constants.EXT2_FT_DIR);
}
} catch (FileSystemException e) {
throw new IOException(e);
}
return null;
}
/**
* Return the block size of the file system
*/
public long getBlockSize() {
return superblock.getBlockSize();
}
/**
* Return a data block
*/
public byte[] getBlock(long nr) throws IOException {
int blockSize = superblock.getBlockSize();
Block result;
Integer key = new Integer((int) nr);
//check if the block has already been retrieved
if (cache.containsKey(key))
result = (Block) cache.get(key);
else {
byte[] data = new byte[blockSize];
api.read(nr * blockSize, data, 0, blockSize);
result = new Block(data);
cache.put(key, result);
}
return result.getData();
}
public Superblock getSuperblock() {
return superblock;
}
/**
* Return the inode numbered inodeNr (the first inode is #1)
*/
public INode getINode(int iNodeNr) throws IOException, FileSystemException {
if (iNodeNr < 1)
throw new IOException("INode number must be greater than 0");
int group = (int) ((iNodeNr - 1) / superblock.getINodesPerGroup());
int index = (int) ((iNodeNr - 1) % superblock.getINodesPerGroup());
//get the part of the inode table that contains the inode
long iNodeTableBlock = groupDescriptors[group].getInodeTable(); //the first block of the inode table
INodeTable iNodeTable = new INodeTable(this, (int) iNodeTableBlock);
return new INode(this, iNodeTable.getInodeData(index));
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?