2009-09-11 91 views
8

经典ASP,VBScript上下文。FileSystemObject - 读取Unicode文件

很多文章,包括this Microsoft one,说你不能使用FileSystemObject读取Unicode文件。

我遇到过这个问题而回,所以切换到使用ADODB.Stream代替,每例的ReadText here,而不是使用FileSystemObject.OpenTextFile(它接受一个最后一个参数指示是否打开该文件作为unicode的,但实际上没有按没有工作)。

但是,当尝试读取UNC文件共享上的文件(与权限相关的问题)时,ADODB.Stream会导致一个痛苦的世界。因此,调查这个,我碰到了下面的方法与Unicode文件工作的)迷迷糊糊的,b)可通过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文件,所以我对于包括MS在内的所有参考文献都感到困惑,称你不能使用FSO读取unicode文件。

有没有其他人使用这种方法来读取unicode文件?是否有任何隐藏的缺陷,或者你真的可以使用FSO读取unicode文件?

回答

3

是的,文档已过时。脚本组件在其早期阶段确实经历了一系列更改(如果您使用的是早期绑定,其中一些更改会发生变化),但至少WK2000 SP4和XP SP2已经非常稳定。

只要小心你的意思是unicode。有时unicode这个词更广泛地使用,可以涵盖unicode的任何编码。 FSO不读取例如unicode的UTF8编码。为此,您需要回退ADODB.Stream。

+0

谢谢。在这种情况下,读取为“unicode”的文件全部由类似的代码创建,该代码使用FSO.OpenTextFile(用于“unicode”的TriStateTrue)打开文件以写入文件,因此应该安全地使用FSO来读取它们所有。 ADODB.Stream在尝试从另一台机器上的文件共享中读取时会导致各种各样的hoo-haa,这就是为什么我要离开它的原因。 – AdaTheDev 2009-09-11 13:11:39

0

我会说,如果它的工作原理,使用它;-)

我注意到你指的是从Windows 2000(!)脚本引导MS文章。也许它已经过时了。

6

我认为微软并不正式表明它支持Unicode,因为:

  1. 它不使用字节顺序标记在文件开始检测Unicode文件,并
  2. 它仅支持小-Endian 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 
0

我正在写一个Windows 7小工具,并运行到相同的问题,如果有可能,你可以切换到另一种编码,例如:ANSI编码“windows-1251”。有了这个编码它工作正常。

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

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 
'. 
'.