FileSystemObject - 读取Unicode文件

13

Classic ASP, VBScript环境。

许多文章,包括这篇来自微软的文章,都说你不能使用FileSystemObject读取Unicode文件。

我遇到过这个问题,所以转而使用ADODB.Stream,根据这里的ReadText示例,而不是使用FileSystemObject.OpenTextFile(后者虽然接受一个最后参数指示是否将文件作为Unicode打开,但实际上无效)。

然而,在试图在UNC文件共享上读取文件时,ADODB.Stream会导致一系列问题(涉及权限问题)。因此,我研究了以下方法,既能够使用Unicode文件,又能够跨UNC文件共享工作:

dim fso, file, stream
set fso = Server.CreateObject("Scripting.FileSystemObject")
set file = fso.GetFile("\\SomeServer\Somefile.txt")
set stream = file.OpenAsTextStream(ForReading,-1) '-1 = unicode

我使用FSO读取Unicode文件时没有出现任何明显的问题,所以我对所有参考资料——包括微软——声称不能使用FSO读取Unicode文件感到困惑。

有其他人使用过这种方法读取Unicode文件吗?我有没有忽略掉什么隐藏的陷阱,或者你真的可以使用FSO读取Unicode文件?

5个回答

12

我认为微软没有正式声明对Unicode的支持是因为:

  1. 它不会使用文件开头的字节顺序标记检测Unicode文件,以及
  2. 它仅支持小端UTF-16 Unicode文件(如果存在字节顺序标记,则需要将其删除)。

以下是一些示例代码,我已经成功使用它们(数年来)自动检测和读取带有FSO的Unicode文件(假设它们是小端,并包含BOM):

'Detect Unicode Files
Set Stream = FSO.OpenTextFile(ScriptFolderObject.Path & "\" & FileName, 1, False)
intAsc1Chr = Asc(Stream.Read(1))
intAsc2Chr = Asc(Stream.Read(1))
Stream.Close
If intAsc1Chr = 255 And intAsc2Chr = 254 Then 
    OpenAsUnicode = True
Else
    OpenAsUnicode = False
End If

'Get script content
Set Stream = FSO.OpenTextFile(ScriptFolderObject.Path & "\" & FileName, 1, 0, OpenAsUnicode)
TextContent = Stream.ReadAll()
Stream.Close

4
'assume we have detected that it is Unicode file - then very straightforward 
'byte-by-byte crawling sorted out my problem:
'.
'.
'.
else
   eilute=f.ReadAll
   'response.write("&#268;IA BUVO &#268;ARLIS<br/>")
   'response.write(len(eilute))
   'response.write("<br/>")
   elt=""
   smbl=""
   for i=3 to len(eilute)  'First 2 bytes are 255 and 254
     baitas=asc(mid(eilute,i,1)) 
     if (i+1) <= len(eilute) then
      i=i+1 
    else
     exit for
    end if
    antras=asc(mid(eilute,i,1))*256 ' raidems uzteks
    'response.write(baitas)
    'response.write(asc(mid(eilute,i,1)))
    'response.write("<br/>")
    if baitas=13 and antras=0 then 'LineFeed
      response.write(elt)
      response.write("<br/>")
      elt=""
      if (i+2) <= len(eilute) then i=i+2 'persokam per CarriageReturn
    else
      skaicius=antras+baitas
      smbl="&#" & skaicius & ";"
      elt=elt & smbl
    end if
    next
   if elt<>"" then
    response.write(elt)
    response.write("<br/>")
    elt=""
   end if
  end if
 f.Close
 '.
 '.

4

是的,那份文档已经过时了。脚本组件在早期进行了一系列更改(如果您使用早期绑定,则其中一些更改会破坏代码),但自至少WK2000 SP4和XP SP2以来,它就非常稳定。

只要小心unicode的含义。有时候“unicode”这个词的范围被使用得更广泛,可以覆盖任何unicode编码。比如FSO不能读取UTF8编码的unicode。为此,您需要退而求其次采用ADODB.Stream。


谢谢。在这种情况下,以“unicode”格式读取的文件都是由类似代码创建的,该代码使用FSO.OpenTextFile(使用TriStateTrue参数设置为“unicode”)打开文件进行写入,因此继续使用FSO来读取它们应该是安全的。当尝试从另一台机器上的文件共享中读取时,ADODB.Stream会引起各种问题,这就是我不再使用它的原因。 - AdaTheDev

0

我正在编写一个Windows 7小工具,遇到了同样的问题。如果可能的话,您可以将文件切换到另一种编码方式,例如:ANSI编码“windows-1251”。使用这种编码方式可以正常工作。

如果您正在用它来编写网站,那么最好使用另一种开发方法来避免这些对象。


0

我会说如果它能用,就用它 ;-)

我注意到你提到的 MS 文章来自于 Windows 2000 (!) 脚本指南。也许已经过时了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接