📄 fatfs.java
字号:
{
throw new FATException("Error writing disk");
}
}
else if(FATType == FS_TYPE_FAT32)
{
ArrayUtils.putInt(value & FAT32_MASK, sector2, 0);
if(!disk.write(sectorAddress, sector2, 0, 4))
{
throw new FATException("Error writing disk");
}
}
else
{
throw new FATException("Unrecognized FAT Type");
}
}
}
}
private int nextSector(int sector, boolean growFile, boolean clearNew) throws FATException
{
// Do some special handling for the root directory on non-FAT32 systems.
if(FATType != FS_TYPE_FAT32 && sector >= firstRootDirSector && sector < firstDataSector)
{
sector++;
if(sector == firstDataSector)
{
return 0;
}
return sector;
}
int cluster = sectorToCluster(sector);
// Go to the next sector.
sector++;
// Did we go past the end of a cluster?
if(cluster == sectorToCluster(sector))
{
// If not, just return the next sector of this cluster.
return sector;
}
// Get the next cluster in the chain.
int nextClus = nextCluster(cluster, growFile, clearNew);
if(nextClus == 0)
{
return 0;
}
return clusterToSector(nextClus);
}
private void parseFileName(String name)
{
filePartsLength = 0;
if(name == null || name.length() == 0)
{
return;
}
int slash = -1;
String part;
do
{
int nextslash = name.indexOf('/', slash + 1);
if(nextslash == -1)
{
part = name.substring(slash + 1);
}
else
{
part = name.substring(slash + 1, nextslash);
}
filePartsLength++;
if(fileParts.length < filePartsLength)
{
String[] newStrings = new String[filePartsLength + 10];
System.arraycopy(fileParts, 0, newStrings, 0, filePartsLength - 1);
fileParts = newStrings;
}
fileParts[filePartsLength - 1] = part;
slash = nextslash;
}
while(slash != -1);
}
//TODO - probably need to remove this once long file name handling is implemented.
private static boolean compareNames(String name, byte[] sector, int offset)
{
name = normalizeName(name);
for(int i = 0; i < 11; i++)
{
if(name.charAt(i) != sector[offset + i])
{
return false;
}
}
return true;
}
private static String normalizeName(String name)
{
byte[] nName = new byte[11];
int lastChar = name.length();
int dot = name.lastIndexOf('.');
if(dot == -1)
{
for(int i = 0; i < 8; i++)
{
if(i < lastChar)
{
nName[i] = (byte)name.charAt(i);
}
else
{
nName[i] = ' ';
}
}
for(int i = 8; i < 11; i++)
{
nName[i] = ' ';
}
}
else
{
for(int i = 0; i < 8; i++)
{
if(i < dot)
{
nName[i] = (byte)name.charAt(i);
}
else
{
nName[i] = ' ';
}
}
for(int i = 0; i < 3; i++)
{
if(i + dot + 1 < lastChar)
{
nName[8 + i] = (byte)name.charAt(i + dot + 1);
}
else
{
nName[8 + i] = ' ';
}
}
}
return new String(nName);
}
private boolean findFile(String name, int dirSector, boolean create, boolean isFile) throws FATException
{
//TODO handle long file names
do
{
synchronized (sector)
{
if(!disk.read(dirSector << shiftBytesPerSector, sector, 0, bytesPerSector))
{
throw new FATException("Error reading disk");
}
for(int i = 0; i < bytesPerSector; i += DIR_ENTRY_SIZE)
{
// Found the end of this directory.
if(sector[i + OFFSET_DIR_NAME] == DIR_LAST_ENTRY)
{
if(create)
{
if(isFile)
{
return makeFile(dirSector, normalizeName(name), 0x20, -1);
}
else
{
if(makeFile(dirSector, normalizeName(name), ATTR_DIRECTORY, -1))
{
int firstSector = getFirstSector();
com.dalsemi.system.ArrayUtils.arrayFill(sector, 0, bytesPerSector, (byte)DIR_LAST_ENTRY);
for(int iSector = 0; iSector < sectorsPerCluster; iSector++)
{
if(!disk.write((firstSector + iSector) << shiftBytesPerSector, sector, 0, bytesPerSector))
{
return false;
}
}
return makeFile(firstSector, ". ", ATTR_DIRECTORY, sectorToCluster(firstSector)) &&
makeFile(firstSector, ".. ", ATTR_DIRECTORY, sectorToCluster(dirSector));
}
}
}
return false;
}
// If this is a valid file entry...
if((ArrayUtils.getByte(sector, i + OFFSET_DIR_NAME) != DIR_SLOT_DELETED) &&
(ArrayUtils.getByte(sector, i + OFFSET_DIR_ATTRIBUTES) != ATTR_LONG_NAME))
{
if(compareNames(name, sector, i + OFFSET_DIR_NAME))
{
currentFileSector = dirSector;
currentFileOffset = i;
return true;
}
}
}
}
dirSector = nextSector(dirSector, create, true);
} while(dirSector != 0);
return false;
}
private boolean isDirectory()
{
if(currentFileSector == 0 && currentFileOffset == 0)
{
// This is the root directory.
return true;
}
synchronized(sector)
{
disk.read((currentFileSector << shiftBytesPerSector) + currentFileOffset, sector, 0, DIR_ENTRY_SIZE);
return (ArrayUtils.getByte(sector, OFFSET_DIR_ATTRIBUTES) & ATTR_DIRECTORY) == ATTR_DIRECTORY;
}
}
private boolean isWritable()
{
if(currentFileSector == 0 && currentFileOffset == 0)
{
// This is the root directory.
return true;
}
synchronized(sector)
{
disk.read((currentFileSector << shiftBytesPerSector) + currentFileOffset, sector, 0, DIR_ENTRY_SIZE);
return (ArrayUtils.getByte(sector, OFFSET_DIR_ATTRIBUTES) & ATTR_READ_ONLY) != ATTR_READ_ONLY;
}
}
private int getFirstSector()
{
int hi;
int lo;
if(currentFileSector == 0 && currentFileOffset == 0)
{
// This is the root directory.
return firstRootDirSector;
}
synchronized(sector)
{
disk.read((currentFileSector << shiftBytesPerSector) + currentFileOffset, sector, 0, DIR_ENTRY_SIZE);
hi = ArrayUtils.getShort(sector, OFFSET_DIR_FIRST_CLUSTER_HIGH);
lo = ArrayUtils.getShort(sector, OFFSET_DIR_FIRST_CLUSTER_LOW);
}
return clusterToSector((hi << 16) | lo);
}
private boolean makeFile(int dirSector, String name, int attributes, int cluster)
{
do
{
synchronized (sector)
{
if(!disk.read(dirSector << shiftBytesPerSector, sector, 0, bytesPerSector))
{
return false;
}
for(int i = 0; i < bytesPerSector; i += DIR_ENTRY_SIZE)
{
// Found the end of this directory.
if(sector[i + OFFSET_DIR_NAME] == DIR_LAST_ENTRY || sector[i + OFFSET_DIR_NAME] == DIR_SLOT_DELETED)
{
//TODO handle long file names
name.getBytes(0, name.length(), sector, i + OFFSET_DIR_NAME);
ArrayUtils.putByte(attributes, sector, i + OFFSET_DIR_ATTRIBUTES);
if((attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
{
ArrayUtils.putByte(0x08, sector, i + OFFSET_DIR_NT_RESERVED);
}
else
{
ArrayUtils.putByte(0x18, sector, i + OFFSET_DIR_NT_RESERVED);
}
long millis = System.currentTimeMillis();
if(calendar == null)
{
calendar = Calendar.getInstance();
}
calendar.setTime(new Date(millis));
int time = ((calendar.get(Calendar.SECOND) / 2) & 0x01F) |
((calendar.get(Calendar.MINUTE) & 0x03F) << 5) |
((calendar.get(Calendar.HOUR_OF_DAY) & 0x1F) << 11);
int date = (calendar.get(Calendar.DATE) & 0x1F) |
(((calendar.get(Calendar.MONTH) + 1) & 0x0F) << 5) |
(((calendar.get(Calendar.YEAR) - 1980) & 0x7F) << 9);
//TODO - should this be tenths or hundredths
ArrayUtils.putByte(((int)millis % 2000) / 10, sector, i + OFFSET_DIR_CREATE_TIME_TENTH);
ArrayUtils.putShort(time, sector, i + OFFSET_DIR_CREATE_TIME);
ArrayUtils.putShort(date, sector, i + OFFSET_DIR_CREATE_DATE);
ArrayUtils.putShort(date, sector, i + OFFSET_DIR_LAST_ACCESS_DATE);
ArrayUtils.putShort(time, sector, i + OFFSET_DIR_WRITE_TIME);
ArrayUtils.putShort(date, sector, i + OFFSET_DIR_WRITE_DATE);
ArrayUtils.putInt(0, sector, i + OFFSET_DIR_FILE_SIZE);
if(cluster == -1)
{
boolean emptyClusterFound = false;
// Look for an unused cluster.
for(cluster = 2; cluster < maxCluster; cluster++)
{
try
{
int temp = readFATEntry(cluster);
if(temp == 0)
{
// Found an unused cluster, add it to the end of the chain.
writeFATEntry(cluster, CLUST_EOFE);
emptyClusterFound = true;
break;
}
}
catch(FATException x)
{
return false;
}
}
if(!emptyClusterFound)
{
return false;
}
}
// The way windows treats cluster 0 vs. cluster 2 is strange.
if(FATType == FS_TYPE_FAT32)
{
if(cluster == 2)
{
cluster = 0;
}
}
ArrayUtils.putShort(cluster >> 16, sector, i + OFFSET_DIR_FIRST_CLUSTER_HIGH);
ArrayUtils.putShort(cluster, sector, i + OFFSET_DIR_FIRST_CLUSTER_LOW);
currentFileSector = dirSector;
currentFileOffset = i;
return disk.write((dirSector << shiftBytesPerSector) + i, sector, i, DIR_ENTRY_SIZE);
}
}
}
try
{
dirSector = nextSector(dirSector, true, true);
}
catch(FATException ex)
{
return false;
}
} while(dirSector != 0);
return false;
}
FATFSDescriptor fileOpened(Vector list, int fileSector, int fileOffset, FATFSDescriptor start)
{
synchronized (lock)
{
int i;
if(start == null)
{
i = 0;
}
else
{
i = list.indexOf(start) + 1;
}
for(;i < list.size(); i++)
{
FATFSDescriptor fd = (FATFSDescriptor)list.elementAt(i);
if(fd.fileSector == fileSector && fd.fileOffset == fileOffset)
{
return fd;
}
}
return null;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -