⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatfs.java

📁 java 编写的一个FAT16读写源代码 支持长文件名和子目录
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
                    {
                        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 + -