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

📄 fatfs.java

📁 java 编写的一个FAT16读写源代码 支持长文件名和子目录
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*---------------------------------------------------------------------------
 *  Copyright (C) 2008 Maxim Integrated Products, Inc., All Rights Reserved.
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included
 *  in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *  IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS INC. BE LIABLE FOR ANY CLAIM,
 *  DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 *  USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *  Except as contained in this notice, the name of Maxim Integrated Products,
 *  Inc. shall not be used except as stated in the Maxim Integrated Products,
 *  Inc. Branding Policy.
 * ---------------------------------------------------------------------------
 */

//TODO - keep track of all open files.  Don't allow opening a file for writing that is already open for reading or writing.  (Maybe I can allow those that are open for reading if I update the pointers of the reading file descriptors)
// Should I allow opening a file for reading that is open for writing?  I think it is OK as long as the read and write routines are protected by the 'lock'.

package com.dalsemi.fs.fat;

import com.dalsemi.fs.*;
import java.io.*;
import java.util.*;

public class FATFS implements FileSystemDriver
{

    public static void sendMessage(String str)
    {
        ((com.dalsemi.slush.Slush)com.dalsemi.system.TINIOS.getShell()).broadcast("  ****DEBUG MESSAGE**** " + str);
    }
    

    public void init(String[] args) throws Exception
    {
//        // Create the interface object.
//        Class diskClass = Class.forName(args[0]);
//        disk = (DiskInterface)diskClass.newInstance();
          disk = (DiskInterface)(new SDCard());

        // Initialize the disk.
//        String[] dArgs = new String[args.length - 1];
//        System.arraycopy(args, 1, dArgs, 0, dArgs.length);
//        disk.init(dArgs);

        // Get all the necessary file system info.
        sector = new byte[512];
        if(!disk.read(0, sector, 0, 512))
        {
            throw new FATException("Error reading disk");

        }

        if(sector[0] != (byte)0xEB && sector[0] != (byte)0xE9)
        {
            int lba = ArrayUtils.getInt(sector, 454) * 512;
            disk.setOffset(lba);
            if(!disk.read(0, sector, 0, 512))
            {
                throw new FATException("Error reading disk");
            }
        }

        parseBootSector(sector);

        // Recreate the buffer if necessary.
        if(bytesPerSector != 512)
        {
          sector = new byte[bytesPerSector];
        }
        sector2 = new byte[bytesPerSector];
    }

    public boolean exists(String fileName)
    {
        return exists(fileName, false);
    }

    private boolean exists(String fileName, boolean create)
    {
        try
        {
            synchronized(lock)
            {
                // Split the file name up into its various pieces.
                // The name will be stored in the fileParts array.
                // The length is stored in filePartsLength.
                parseFileName(fileName);

                // This is a request for the root directory.
                if(filePartsLength == 0)
                {
                    currentFileSector = 0;
                    currentFileOffset = 0;
                    return true;
                }

                int currentDirSector = firstRootDirSector;
                boolean writable = true;

                // Go through all of the directories to get to the file.
                for(int i = 0; i < filePartsLength - 1; i++)
                {
                    // Look for a directory with the given name.
                    if(!findFile(fileParts[i], currentDirSector, create & writable, false))
                    {
                        return false;
                    }

                    // Verify this file is a directory and not a file.
                    if(!isDirectory())
                    {
                        return false;
                    }

                    writable = isWritable();

                    // Point to the contents of this directory.
                    currentDirSector = getFirstSector();
                }

                // Look for file with the given name.
                return findFile(fileParts[filePartsLength - 1], currentDirSector, create & writable, true);
            }
        }
        catch(FATException x)
        {
            return false;
        }
    }

    public boolean canWrite(String fileName, byte uid)
    {
        synchronized(lock)
        {
            exists(fileName, false);

            if(currentFileSector == 0 && currentFileOffset == 0)
            {
                return true;
            }
            else
            {
                synchronized(sector)
                {
                    disk.read((currentFileSector << shiftBytesPerSector) + currentFileOffset + OFFSET_DIR_ATTRIBUTES, sector, 0, 1);
                    return (sector[0] & ATTR_READ_ONLY) != ATTR_READ_ONLY;
                }
            }
        }
    }

    public boolean canRead(String fileName, byte uid)
    {
        // FAT file system doesn't support permissions, so if the file exists assume it is readable.
        return exists(fileName);
    }

    public boolean canExec(String fileName, byte uid)
    {
        // FAT file system doesn't support permissions, so if the file exists assume it is accessible.
        return exists(fileName);
    }

    public boolean isFile(String fileName)
    {
        synchronized(lock)
        {
            return exists(fileName) && !isDirectory();
        }
    }

    public boolean isDirectory(String fileName)
    {
        synchronized(lock)
        {
            return exists(fileName) && isDirectory();
        }
    }

    public long lastModified(String fileName)
    {
        synchronized (lock)
        {
            if(exists(fileName))
            {
                if(calendar == null)
                {
                    calendar = Calendar.getInstance();
                }

                int date;
                int time;

                if(currentFileSector == 0 && currentFileOffset == 0)
                {
                    //TODO - this is the root directory, how do I get last modified time.
                    return 0L;
                }

                synchronized (sector)
                {
                    if(!disk.read(currentFileSector << shiftBytesPerSector, sector, 0, DIR_ENTRY_SIZE))
                    {
                        return 0L;
                    }

                    date = ArrayUtils.getShort(sector, OFFSET_DIR_WRITE_DATE);
                    time = ArrayUtils.getShort(sector, OFFSET_DIR_WRITE_TIME);
                }

                int year = 1980 + ((date >> 9) & 0x7F);
                int month = ((date >> 5) & 0x0F) - 1;
                int day = (date & 0x1F);

                int hour = (time >> 11) & 0x1F;
                int minute = (time >> 5) & 0x3F;
                int second = (time & 0x1F) * 2;

                calendar.set(year, month, day, hour, minute, second);
                return calendar.getTime().getTime();
            }
            else
            {
                return 0L;
            }
        }
    }

    public long length(String fileName)
    {
        synchronized (lock)
        {
            if(exists(fileName))
            {
                if(isDirectory())
                {
                    // Start at the beginning of the directory's contents.
                    int dirSector = getFirstSector();
                    int fileCount = 0;
                    do
                    {
                        synchronized (sector)
                        {
                            // Read the complete sector.
                            if(!disk.read(dirSector << shiftBytesPerSector, sector, 0, bytesPerSector))
                            {
                                return 0L;
                            }

                            // Check each entry in the sector.
                            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)
                                {
                                    return fileCount;
                                }

                                // 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(!com.dalsemi.system.ArrayUtils.arrayComp(sector, i + OFFSET_DIR_NAME, dotBytes, 0, 11) &&
                                       !com.dalsemi.system.ArrayUtils.arrayComp(sector, i + OFFSET_DIR_NAME, dotdotBytes, 0, 11))
                                    {
                                        // ...increment the count of files.
                                        fileCount++;
                                    }
                                }
                            }
                        }

                        try
                        {
                            // Keep going until we reach the end of the cluster chain.
                            dirSector = nextSector(dirSector, false, false);
                        }
                        catch(FATException ex)
                        {
                            return 0L;
                        }
                    } while(dirSector != 0);

                    return fileCount;
                }
                else
                {
                    synchronized (sector)
                    {
                        if(!disk.read((currentFileSector << shiftBytesPerSector) + currentFileOffset, sector, 0, DIR_ENTRY_SIZE))
                        {
                            return 0L;
                        }
                        return (long)ArrayUtils.getInt(sector, OFFSET_DIR_FILE_SIZE);
                    }
                }
            }
            else
            {
                return 0L;
            }
        }
    }

    public boolean mkdir(String fileName, byte uid)
    {
        try
        {
            synchronized(lock)
            {
                // Split the file name up into its various pieces.
                // The name will be stored in the fileParts array.
                // The length is stored in filePartsLength.
                parseFileName(fileName);

                // This is a request for the root directory which must already exist.
                if(filePartsLength == 0)
                {
                    return false;
                }

                int currentDirSector = firstRootDirSector;

                // Go through all of the directories to get to the file.
                for(int i = 0; i < filePartsLength - 1; i++)
                {
                    // Look for a directory with the given name.
                    if(!findFile(fileParts[i], currentDirSector, false, false))
                    {
                        return false;
                    }

                    // Verify this file is a directory and not a file.
                    if(!isDirectory())
                    {
                        return false;
                    }

                    // Point to the contents of this directory.
                    currentDirSector = getFirstSector();
                }

                // Look for file with the given name.
                if(findFile(fileParts[filePartsLength - 1], currentDirSector, false, false))
                {
                    return false;
                }

                String nName = normalizeName(fileParts[filePartsLength - 1]);
                if(makeFile(currentDirSector, nName, ATTR_DIRECTORY, -1))
                {
                    int firstSector = getFirstSector();
                    synchronized (sector)
                    {
                        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(currentDirSector));
                }

                return false;
            }
        }
        catch(FATException x)
        {
            return false;
        }

    }

    public boolean rename(String srcname, String destname, byte uid)
    {
        return false;
        /*TODO*/
    }

    public String[] list(String fileName, byte uid)
    {
        synchronized (lock)
        {
            if(listVector == null)
            {
                listVector = new Vector();
            }
            listVector.removeAllElements();

            if(isDirectory(fileName))
            {
                //TODO - handle long file names.

                // Start at the beginning of the directory's contents.
                int dirSector = getFirstSector();
                do
                {
                    synchronized (sector)
                    {
                        // Read the complete sector.
                        if(!disk.read(dirSector << shiftBytesPerSector, sector, 0, bytesPerSector))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -