一种将普通文件名转换为DOS 8.3格式的算法

An algorithm to convert normal filename to DOS 8.3 format

如标题所示,我正在寻找一种将“普通”文件名转换为短 8.3 格式的方法。但是我需要在不使用任何外部工具的情况下完全做到这一点,我必须知道算法。

也许我应该解释一下原因:我在 Arduino 上使用一个 SD 卡模块,我发现这个模块出于某种原因使用 8.3 格式保存文件,即使插入普通计算机的同一张卡也可以有得到具有正常文件名的文件。

问题是,当我想用​​这个模块保存文件时,我必须选择一个符合8.3格式的文件名,否则我将无法保存文件。读取文件时存在一些类似的问题:如果我给模块一个普通的文件名,那么模块不会自动将它转换为 8.3,我将无法读取它。

因为我正在为 Arduino 编写代码,所以我不能使用任何外部工具,例如 WinAPI 的 GetShortPathName 函数。我必须知道正确的算法。

Microsoft 可扩展固件倡议 FAT32 文件系统规范 中描述了该算法。 Download fatgen103.doc

The technique chosen to auto-generate short names from long names is modeled after Windows NT. Auto-generated short names are composed of the basis-name and an optional numeric-tail.

The Basis-Name Generation Algorithm

The basis-name generation algorithm is outlined below. This is a sample algorithm and serves to illustrate how short names can be auto-generated from long names. An implementation should follow this basic sequence of steps.

  1. The UNICODE name passed to the file system is converted to upper case.
  2. The upper cased UNICODE name is converted to OEM.
    If (the uppercased UNICODE glyph does not exist as an OEM glyph in the OEM code page) or (the OEM glyph is invalid in an 8.3 name)
    {
    Replace the glyph to an OEM '_' (underscore) character.
    Set a "lossy conversion" flag.
    }
  3. Strip all leading and embedded spaces from the long name.
  4. Strip all leading periods from the long name.
  5. While (not at end of the long name) and (char is not a period) and (total chars copied < 8)
    {
    Copy characters into primary portion of the basis name
    }
  6. Insert a dot at the end of the primary components of the basis-name iff the basis name has an extension after the last period in the name.
  7. Scan for the last embedded period in the long name.
    If (the last embedded period was found)
    {
    While (not at end of the long name) and (total chars copied < 3)
    {
    Copy characters into extension portion of the basis name
    }
    }
  8. Proceed to numeric-tail generation.

The Numeric-Tail Generation Algorithm

If (a "lossy conversion" was not flagged) and (the long name fits within the 8.3 naming conventions) and (the basis-name does not collide with any existing short name)
{
The short name is only the basis-name without the numeric tail.
}
else
{
Insert a numeric-tail "~n" to the end of the primary name such that the value of the "~n" is chosen so that the name thus formed does not collide with any existing short name and that the primary name does not exceed eight characters in length.
}

The "~n" string can range from "~1" to "~999999". The number "n" is chosen so that it is the next number in a sequence of files with similar basis-names. For example, assume the following short names existed: LETTER~1.DOC and LETTER~2.DOC. As expected, the next auto-generated name of name of this type would be LETTER~3.DOC. Assume the following short names existed: LETTER~1.DOC, LETTER~3.DOC. Again, the next auto-generated name of name of this type would be LETTER~2.DOC. However, one absolutely cannot count on this behavior. In a directory with a very large mix of names of this type, the selection algorithm is optimized for speed and may select another "n" based on the characteristics of short names that end in "~n" and have similar leading name patterns.