fatlfndirectory.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 286 行
JAVA
286 行
/*
* $Id: FatLfnDirectory.java,v 1.3 2003/11/29 17:20:25 gbin Exp $
*/
package org.jnode.fs.fat;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import org.jnode.fs.FSEntry;
/**
* @author gbin
*/
public class FatLfnDirectory extends FatDirectory {
private HashMap shortNameIndex = new HashMap();
private HashMap longFileNameIndex = new HashMap();
/**
* @param fs
* @param file
* @throws IOException
*/
public FatLfnDirectory(FatFileSystem fs, FatFile file) throws IOException {
super(fs, file);
}
// for root
public FatLfnDirectory(FatFileSystem fs, int nrEntries) {
super(fs, nrEntries);
}
public FSEntry addFile(String name) throws IOException {
name = name.trim();
String shortName = generateShortNameFor(name);
FatDirEntry realEntry = new FatDirEntry(this, splitName(shortName), splitExt(shortName));
LfnEntry entry = new LfnEntry(this, realEntry, name);
shortNameIndex.put(shortName, entry);
longFileNameIndex.put(name, entry);
setDirty();
flush();
return entry;
}
public FSEntry addDirectory(String name) throws IOException {
name = name.trim();
String shortName = generateShortNameFor(name);
FatDirEntry realEntry = new FatDirEntry(this, splitName(shortName), splitExt(shortName));
final long parentCluster;
if (file == null) {
parentCluster = 0;
} else {
parentCluster = file.getStartCluster();
}
final int clusterSize = getFatFileSystem().getClusterSize();
realEntry.setFlags(FatConstants.F_DIRECTORY);
final FatFile file = realEntry.getFatFile();
file.setLength(clusterSize);
final byte[] buf = new byte[clusterSize];
// Clean the contents of this cluster to avoid reading strange data
// in the directory.
file.write(0, buf, 0, buf.length);
file.getDirectory().initialize(file.getStartCluster(), parentCluster);
LfnEntry entry = new LfnEntry(this, realEntry, name);
shortNameIndex.put(shortName, entry);
longFileNameIndex.put(name, entry);
setDirty();
flush();
return entry;
}
public FSEntry getEntry(String name) {
//System.out.println("Search : " + name);
name = name.trim();
FSEntry entry;
// try first as a long file name
entry = (LfnEntry)longFileNameIndex.get(name);
if (entry == null)
return (LfnEntry)shortNameIndex.get(name.toUpperCase());
else
return entry;
}
protected synchronized void read(byte[] src) {
super.read(src);
readLFN();
}
private void readLFN() {
//System.out.println("Read LFN");
int i = 0;
int size = entries.size();
while (i < size) {
// jump over empty entries
while (i < size && entries.get(i) == null) {
i++;
}
if (i >= size) {
break;
}
int offset = i; // beginning of the entry
// check when we reach a real entry
while (entries.get(i) instanceof FatLfnDirEntry) {
//System.out.println(" Jumped over : " + entries.get(i));
i++;
if (i >= size) {
// This is a cutted entry, forgive it
break;
}
}
i++;
if (i >= size) {
// This is a cutted entry, forgive it
break;
}
LfnEntry current = new LfnEntry(this, entries, offset, i - offset);
if (!current.isDeleted() && current.isValid())
{
shortNameIndex.put(current.getRealEntry().getName(), current);
longFileNameIndex.put(current.getName(), current);
//System.out.println(" Found a real entry : |" + current + "|");
}
}
}
private void updateLFN() {
//System.out.println("Update LFN");
Iterator allEntries = shortNameIndex.values().iterator();
Vector destination = new Vector();
while (allEntries.hasNext()) {
LfnEntry currentEntry = (LfnEntry)allEntries.next();
FatBasicDirEntry[] encoded = currentEntry.compactForm();
for (int i = 0; i < encoded.length; i++) {
destination.add(encoded[i]);
}
}
int size = destination.size();
for (int i = 0; i < size; i++) {
entries.set(i, destination.get(i));
}
int entireSize = entries.size();
for (int i = size; i < entireSize; i++) {
entries.set(i, null); // remove stale entries
}
}
protected void flush() throws IOException {
//System.out.println("LfnDirectory: Flush");
updateLFN();
super.flush();
}
public Iterator iterator() {
return shortNameIndex.values().iterator();
}
/*
* Its in the DOS manual!(DOS 5: page 72) Valid: A..Z 0..9 _ ^ $ ~ ! # % & - {} () @ ' `
*
* Unvalid: spaces/periods,
*/
public String generateShortNameFor(String longFullName) {
int dotIndex = longFullName.lastIndexOf('.');
String longName;
String longExt;
if (dotIndex == -1) // No dot in the name
{
longName = longFullName;
longExt = ""; // so no extension
} else {
// split it at the dot
longName = longFullName.substring(0, dotIndex);
longExt = longFullName.substring(dotIndex + 1);
}
String shortName = longName;
String shortExt = longExt;
// make the extension short
if (shortExt.length() > 3) {
shortExt = shortExt.substring(0, 3);
}
// make the ~n name short
if (shortName.length() > 8) {
// trim it
char[] shortNameChar = shortName.substring(0, 7).toUpperCase().toCharArray();
// epurate it from alien characters
loop : for (int i = 0; i < shortNameChar.length; i++) {
char toTest = shortNameChar[i];
valid : {
if (toTest > 255)
break valid;
if (toTest == ' ')
break valid;
if (toTest >= 'A' && toTest <= 'Z')
continue loop;
if (toTest >= '0' && toTest <= '9')
continue loop;
if (toTest == '_'
|| toTest == '^'
|| toTest == '$'
|| toTest == '~'
|| toTest == '!'
|| toTest == '#'
|| toTest == '%'
|| toTest == '&'
|| toTest == '-'
|| toTest == '{'
|| toTest == '}'
|| toTest == '('
|| toTest == ')'
|| toTest == '@'
|| toTest == '\''
|| toTest == '`')
continue loop;
}
shortNameChar[i] = '_';
}
// name range from "nnnnnn~1" to "~9999999"
for (int i = 1; i <= 99999999; i++) {
String tildeStuff = "~" + i;
int tildeStuffLength = tildeStuff.length();
//System.out.println("tildeStuff="+tildeStuff);
System.arraycopy(tildeStuff.toCharArray(), 0, shortNameChar, 7 - tildeStuffLength, tildeStuffLength);
shortName = new String(shortNameChar);
if (!shortNameIndex.containsKey(shortName + "." + shortExt))
break;
}
}
String shortFullName = shortName + "." + shortExt;
return shortFullName.toUpperCase();
}
/**
* Remove the entry with the given name from this directory.
*
* @param name
* @throws IOException
*/
public void remove(String name) throws IOException {
name = name.trim();
LfnEntry byLongName = (LfnEntry)longFileNameIndex.get(name);
if (byLongName != null) {
longFileNameIndex.remove(name);
shortNameIndex.remove(byLongName.getRealEntry().getName());
return;
}
String uppedName = name.toUpperCase();
LfnEntry byShortName = (LfnEntry)shortNameIndex.get(uppedName);
if (byShortName != null) {
longFileNameIndex.remove(byShortName.getName());
shortNameIndex.remove(uppedName);
}
throw new FileNotFoundException(name);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?