文件键入的危险

2020-12-06 18:27:49

假设您双击计算机上的文件。您正在执行此操作,因此您可以打开文件并使用它。但是您的操作系统知道这意味着什么吗?它怎么知道在其中打开文件?让我们看一下多年来为解决这个问题而提出的一些解决方案。

(有趣的事实:这最初是我最古老的文章之一的润色,然后才变成完整的东西,因此请稍作重读。)

无论如何,什么是文件?它是磁盘(可能是软盘)上的字节序列。或胶带。 (您可以选择盒式磁带或纸张。)或成堆的带有孔的卡片。或在前面板上手动切换。

文件类型无关紧要,因为文件不是真的。在大型机时代,您通常1.从打孔卡或Tape2将程序加载到计算机上。从电传打字机终端或从其他磁带/卡座将输入输入到该程序3。从电传打字机,行式打印机或另一个磁带/卡座收到的输出

对于某种介质上的文件有什么混乱,计算机还没有变得足够复杂,仅仅是因为处理的内容很少。如果您有一堆打孔卡,那就是您的"文件"。希望您标记了放入的盒子!

磁带更加有趣,因为它们可以容纳更多的数据。 (一个惊人的5.76兆字节,存储在3/4公里的magentic磁带上。这太令人兴奋了!)也就是说,在磁带上存储多个文件是一个奇怪的任务。操作系统还不是真的。最好的编程语言是诸如FORTRAN或COBOL之类的编程语言,其中包含针对硬件任务(例如从磁带或打孔卡中读取或写入)的语句。例如,这是IBM 704的FORTRAN手册。我们有几个命令,例如READ(来自打孔卡读取器),READ TAPE,PUNCH(新卡),PRINT(至打印机)等。

在当时的IBM磁带机(例如:IBM 727)上,磁带被分为文件和记录。在FORTRAN中,记录是在每个WRITE TAPE命令上创建的,以后可以用READ TAPE读取。可以使用BACKSPACE语句覆盖记录,然后再次写入。文件是记录的集合,可以使用END FILE命令创建。

顺便说一句,后来的编程语言(例如C)仍然共享这个时代的传统。这就是为什么我们使用printf在屏幕上将文本绘制到屏幕上的原因,而printf早前实际上已经打印到电传打字机终端上,为什么我们使用倒带,fseek,fread和fwrite读取文件,就像我们仍在磁带驱动器上一样。甚至ASCII(最常用于基本拉丁字母的编码)也具有文件,组,记录和单位分隔符的代码点。 (这也可能与块端子有关,将在以后的文章中进行讨论。)

随着大型机转向更高级的批处理和后来的交互式分时操作系统(如UNIX,OS / 360,密歇根终端系统,ITS等),它们获得了比原始磁带机访问更复杂的文件处理方法。但是随后出现了微型计算机。

我们现在有软盘。他们可以存储很多文件,重命名它们,删除它们等,而不会出现太多问题。这就是一台名为Apple II的整洁计算机,它刚刚问世。它使用这些新型磁盘,因此需要弄清楚如何在其上存储文件。

Apple DOS(在其大部分生命中都是Apple II的磁盘操作系统)存储文件的方式有些有趣。每个文件都有一个名称(最多30个字符)和一个类型代码。其中定义了8个,但只有4个重要:

Apple DOS有一些与这些类型交互的特定命令。例如,RUN命令在Interger BASIC和Applesoft BASIC程序上均可使用,并选择要使用的程序。 BRUN,二进制运行,仅适用于二进制文件。 OPEN,READ,WRITE和CLOSE只能在ASCII文本文件上使用。

这些类型比您更能帮助操作系统。这在80年代末和90年代初的HP计算器(例如HP-28c和HP-48GX)中尤为明显。这些计算器没有磁盘,但是它们确实具有永久性内存,可以像存储计算机一样将对象存储到文件夹中。

这些计算器使用了反向波兰符号。本质上,您可以通过以下方式进行数学运算:将对象放在堆栈上,然后执行命令,这些命令从堆栈中取出内容并放上新内容。 RPN中的对象是您放置在堆栈中的对象。 《 HP-48高级用户参考手册》列出了32种不同的类型,包括实数,复数,字符串,数组,列表,变量名,可执行程序,图形对象,目录等。例如,可能是ADD或一些花哨的微积分。无论他们是什么,他们都需要知道他们要处理的类型,以便他们可以拒绝输入或正确使用输入。

像Apple II一样,为类型只使用整数是完全可以的,因为类型不能为用户服务。它们就在那里,因此操作系统知道堆栈上给定的字节块是什么。对于自定义类型,有一些保留位置,但是在大多数情况下,都永远不会添加新类型,也不应该添加新类型。

微型计算机真正引起了ZX Spectrum,Amstrad CPC和Commodore 64等公司的欢迎。这些是相当便宜和简单的计算机。刚推出时,这些磁带只带了盒式磁带输入,因为磁盘太贵了。

在这些计算机上,您将使用标准AUX线连接磁带播放器(尽管有些电缆(例如CPC)内置了磁带播放器),并且计算机会指示您何时启动和停止磁带。这些盒式磁带播放器通常带有一个随磁带前进的小柜台,以帮助您确定磁带在哪里。插入磁带时,将计数器重置为零。要创建文件时,请记下计数器读取的内容,然后保存文件。要加载特定文件,请寻找磁带,直到到达您写下的位置,然后开始阅读。

相反,更先进的计算机(例如Amstrad CPC)保存了一个标头,其中每个文件除其他外还包含文件名和扩展名。如果要求提供特定文件,它可以只读取磁带,直到找到它为止。后来,这些计算机获得了磁盘驱动器,并且任何临时的磁带故障都被替换为适当的文件系统,例如FAT或MFS,该文件系统存储文件在给定磁盘上的位置以及所谓的位置。

文件代码是有限的。添加更多的对象几乎是不可能的。你所拥有的就是你所拥有的。所以...如果我们只是用字母拼写代码呢?他们几个?它们可以是任何东西。然后,程序员可以提出他们想要的任何文件扩展名,并且可以。

假设在MS-DOS中,您有一个名为REPORT.TXT的文件。 REPORT是文件名,TXT是扩展名。文件扩展名可以轻松,一致地指示文件包含的内容。 TXT文件包含文本,BMP文件是位图,等等。

某些文件扩展名(例如EXE,BAT,SYS和COM)具有特殊含义,其方式与Apple DOS代码具有特殊含义的方式相同,但除此之外,它们只是在帮助用户。用户必须手动选择要使用的程序。这使用户可以根据最有帮助的方式选择要使用的视图或编辑器。不幸的是,没有默认程序。如果用户不知道哪个程序(例如,VIZ文件)用于该程序,那么他们就不走运了。它是可视化的吗?一些漫画吗?一个可爱的互联网幽灵的数字表现形式,谁呆得太晚了,就不了解旧计算机了吗?世界可能永远不知道...

让我们跳到Macintosh上一秒钟。在1984年这是一件新奇的事情,它有机会重新发明轮子并破坏与CP / M和大型机传统的兼容性。确实如此。

最初的128K Macintosh使用了400K软盘,这在当时是不完全可怕的空间。它使用了MFS,该MFS不支持目录但支持文件。它也完全由图形驱动。 Finder被认为是与文件进行交互的主要方式,而File>打开命令可以启动创建文件的程序。它是如何做到的?

Macintosh使用文件类型和创建者代码代替文件扩展名。这些是4个字母的标识符,很像文件扩展名,它标识文件的类型和用于创建文件的应用程序。用户通常看不到它们。他们只是看到了文件名和该类型的图标。

为此,系统保留了代码及其相关图标和程序的数据库。首次运行时,程序会告诉OS它的创建者代码是什么以及它支持的文件类型。然后,操作系统会将这些信息保存在启动磁盘上。稍后,当用户打开文件时,操作系统将对照其存储列表检查其类型和创建者代码,以确定要使用哪个应用程序。这工作得很好。

Macintosh资源使用了类似的系统。每个文件中都有一个资源列表,按四个字母的类型,然后按数字ID和一个可选名称的形式分组。这种方法更像是数据库而不是文件系统,并且以不灵活为代价很好地发挥了作用。这对于程序资源的内部数据库来说很好,但是对于用户想要排序和组织的文件来说,文件较少。

快进到大约Windows 95左右。有问题。它想从Mac上窃取一些页面,以使操作系统更以文件为中心……但这不是Windows 3.1或DOS的工作方式。

DOS的处理方式仍然受旧的大型机和微型计算机的启发。加载程序,执行程序中所需的操作,然后退出。 Windows 95想要做的是创建一个以文档为中心的工作流,该应用程序使用户无法使用它,并且它仅提供了一种让用户操作文件的方法。

它需要以某种方式采取以文件为中心的工作流程,并将其栓接到以应用程序为中心的DOS上。文件需要以某种方式绑定到扩展名。附加类型或创建者代码或省略扩展名是不合理的,因为这会破坏兼容性。

而不是将文件的类型绑定到创建者/类型代码,Windows 95而是使用了已经存在的文件扩展名。安装后,应用程序可以注册它们支持的扩展以及如何在文件管理器中显示它们。在文件管理器中打开文件时,Windows会在注册的应用程序中打开该文件。很简单,对不对?

如果操作系统始终知道要在其中打开文件的程序,并且该操作系统具有友好的名称和图标来向用户显示特定类型的文件...我们是否需要显示文件扩展名? Windows 95团队决定隐藏文件扩展名,因为它们只会使用户感到困惑。我认为,这是一个糟糕的主意。为什么? MS-DOS。

这三个字母的扩展名是相当有限的,并且不是文档是什么的非常可靠的指示。充其量,文件扩展名充其量只表示文件的存储格式,而不是文件的类型。例如,文件的格式可以是图像,但类型可以是照片,像素艺术,文档扫描或许多其他事物。某些应用程序可能会保存为相同的格式,但处理的文档却根本不同。您不会使用像素艺术编辑器来修饰照片。

Windows 95无法并且没有考虑到" Open With"菜单,允许用户选择一个应用程序。但是,目标是让用户根据文件而不是应用程序进行思考。另一方面,由于创建者代码的原因,Macintosh可能会将相同格式的文件注册到不同的应用程序。这不是一个完美的解决方案(如果用户要对文件做其他事情怎么办?),但是对于大多数用例来说,额外的信息会有所帮助。

另外,隐藏扩展名会导致一些实际的麻烦。如果两个文件具有相同的名称和不同的扩展名,则它们都将以相同的名称显示。如果图标相同,则很难区分它们。最常见的示例位于安装CD的根目录中,在该目录中可以将一个图标文件存储在已安装的CD旁边,并使用相同的名称和图标。区分它们的唯一方法是读取每个文件列出的类型。

另一个不好的例子是误导文件类型。假设您有一个文件,“奶奶的照片”。它看起来像一张图片,带有图片图标。但是,当您打开它时,它会感染病毒。事实证明,图片不是图片,而是带有图片图标的程序。在我看来,隐藏类型信息比忽略它更加危险和混乱。 (就其价值而言,Macintosh也可能受到这种攻击,并且反恶意软件扫描程序也可以阻止这些死路。但这是一个长期的问题。)

UNIX和Linux从来没有概念代码或文件扩展名。文件名只是一个文件名。希望用户知道它是哪种文件。这与UNIX诞生的大型机和小型计算机非常相似。但是,没有什么阻止他们添加自己的扩展名。只是没有针对它们的特定操作系统支持。

后来,决定这是一个愚蠢的主意。但是,无法将类型信息添加到文件中。而是编写程序来查看文件类型的幻数。这些是文件中的简短标识符,用于指示文件的类型。如果您使用的是Linux或Mac OS X,则可以通过打开终端并在任意放置的位置运行file命令来实际尝试此操作。

在某种程度上,这很好,因为扩展名是什么,甚至是否具有扩展名也无所谓。从理论上讲,没有办法歪曲文件的类型。但是这种方法存在问题。

与仅检查某些字母是否匹配相比,检查文件的类型在计算上是昂贵的过程。

文件格式不指示文件的类型,不考虑文件的格式实际上包含的数据类型。

某些文件格式基于其他文件格式(例如Firefox扩展和Word文档都是ZIP存档),这使分析变得复杂。

某些文件格式可能同时是两种不同的格式!这包括恶意构​​建的多语言文件以及包含ZIP存档数据的ex:安装程序。

这并不是说他们没有自己的优势。给定一个随机的,未命名或错误键入的文件,您可以轻松地恢复该类型。但是我得出的结论是,它们过于脆弱和脆弱,无法在所有文件类型的日常使用中有效。

随着互联网的发展,人们需要一种标准化的方式来定义文件格式。输入MIME类型。这些文件主要用于,以向Web浏览器或电子邮件客户端发出信号,指示文件的类型,但它们也用于其他情况。

例如,文本文件是应用程序/文本,图像可以是image / png。 MIME类型通常被认为是该文件是什么类型的权威的,机器可读的答案。大多数Linux发行版附带一个共享的MIME信息数据库,该数据库包含从MIME类型到魔术数字,图标,名称,备用MIME以及它们继承的任何类型的映射。该数据库非常全面,几乎包含值得分类的每种文件格式。

也就是说,很少有操作系统实际存储MIME类型,即使它们能够使用备用数据流或扩展属性来存储MIME类型。 MIME类型几乎总是从文件扩展名或幻数衍生而来。他们仍然无法解决种类与格式的问题。

更高版本的macOS(10.4和更高版本)在内部使用统一类型标识符。这些基本上是MIME类型,但格式更好。这是其中的一大堆。这些是用一种相当不错的方式定义的,其中类型可以是另一种更通用类型的特化,而MIME只存储给定格式所源自的格式。 (例如:MP3是音频文件)这样可以方便地按类型搜索。 (例如:查找所有音频文件)

这确实取决于上下文。为什么要问这个问题,您在谈论什么设备,等等。这是我认为每种策略的利弊的快速清单。随意选择最适合您的目的的东西。