2009-09-11 5 views
8

ASP cổ điển, ngữ cảnh VBScript.FileSystemObject - Đọc các tệp Unicode

Rất nhiều bài viết bao gồm this Microsoft one, giả sử bạn không thể sử dụng FileSystemObject để đọc tệp Unicode.

Tôi gặp phải vấn đề này một thời gian, do đó, chuyển sang sử dụng ADODB.Stream thay vì sử dụng here, thay vì sử dụng FileSystemObject.OpenTextFile (chấp nhận tham số cuối cùng cho biết có mở tệp dưới dạng unicode hay không) 't làm việc).

Tuy nhiên, ADODB.Stream dẫn đến một thế giới đau đớn khi cố đọc một tệp trên tệp UNC (vấn đề liên quan đến quyền). Vì vậy, điều tra này, tôi tình cờ phương pháp sau đây mà làm việc a) với các tập tin unicode, và b) trên UNC fileshares:

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 

này được sử dụng FSO để đọc một file unicode mà không cần bất kỳ vấn đề rõ ràng, vì vậy tôi bị nhầm lẫn với tất cả các tham chiếu, bao gồm MS, nói rằng bạn không thể sử dụng FSO để đọc các tệp unicode.

Có ai khác đã sử dụng phương pháp này để đọc các tệp unicode không? Có bất kỳ gotchas ẩn tôi đang mất tích, hoặc có thể bạn thực sự thực sự đọc các tập tin unicode bằng cách sử dụng FSO?

Trả lời

3

Có tài liệu đã lỗi thời. Các thành phần kịch bản đã đi qua một bộ thay đổi trong những ngày đầu của nó (một số người trong số họ đã phá vỡ những thay đổi nếu bạn đang sử dụng đầu ràng buộc) tuy nhiên kể từ ít nhất WK2000 SP4 và XP SP2 nó đã rất ổn định.

Chỉ cần cẩn thận ý bạn là gì bằng unicode. Đôi khi từ unicode được sử dụng rộng rãi hơn và có thể bao gồm bất kỳ mã hóa unicode nào. FSO không đọc ví dụ mã hóa UTF8 của unicode. Cho rằng bạn sẽ cần phải quay trở lại trên ADODB.Stream.

+0

Cảm ơn.Trong trường hợp này, các tệp được đọc là "unicode" đều được tạo bởi mã tương tự sử dụng FSO.OpenTextFile (với TriStateTrue cho "unicode") để mở tệp để ghi vào nó, vì vậy phải an toàn gắn bó với FSO để đọc chúng tất cả các. ADODB.Stream gây ra tất cả các loại hoo-haa khi cố gắng đọc từ một fileshare trên máy khác đó là lý do tại sao tôi di chuyển ra khỏi đó. – AdaTheDev

0

tôi muốn nói nếu nó hoạt động, sử dụng nó ;-)

tôi nhận thấy bài viết MS bạn tham khảo là từ năm 2000 (!) Kịch bản hướng dẫn Windows. Có lẽ nó đã lỗi thời.

6

Tôi nghĩ rằng MS không chính thức tuyên bố rằng nó hỗ trợ unicode vì:

  1. Nó không phát hiện các file unicode sử dụng nhãn hiệu byte đặt hàng vào lúc bắt đầu của tập tin, và
  2. Nó chỉ hỗ trợ nhỏ Các tệp unicode -Endian UTF-16 (và bạn cần loại bỏ dấu thứ tự byte nếu có).

Dưới đây là một số mẫu mã mà tôi đã được sử dụng thành công (một vài năm) để tự động dò tìm và đọc file unicode với FSO (giả sử họ ít về cuối nhỏ và chứa 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

Tôi đang viết một cửa sổ 7 tiện ích và chạy vào cùng một vấn đề, và nếu có thể bạn chỉ có thể chuyển đổi tệp của bạn sang một mã hóa khác, ví dụ: ANSI encoding "windows-1251". Với mã hóa này, nó hoạt động tốt.

Nếu bạn đang sử dụng điều này để viết một trang web, thì tốt hơn là sử dụng một cách tiếp cận phát triển khác để tránh đối tượng này.

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