Centrum skryptów - Systemy operacyjne

Jak wczytać cały plik tekstowy, zamiast wczytywać go wiersz po wierszu?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak wczytać cały plik tekstowy, zamiast wczytywać go wiersz po wierszu?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Używam obecnie skryptu otwierającego plik zawierające nazwy komputerów. Skrypt odczytuje pierwszy wiersz pliku i łączy się z danym komputerem, a następnie odczytuje drugi wiersz i łączy się z kolejnym komputerem. Czy jest jakiś sposób, żeby zachować te nazwy w zmiennej lub czymś podobnym, żeby nie było potrzeby ciągłego odczytywania pliku?

-- KS

Cześć Skrypciarze! Odpowiedź

Cześć, KS. Zakładam, że Twój skrypt w chwili obecnej wygląda podobnie do mojego. W tym testowym skrypcie otwieramy plik tekstowy (servers.txt), odczytujemy pierwszy wiersz (zakładam ponadto, że jednemu wierszowi w pliku odpowiada jeden komputer), a następnie wywołujemy echo nazwy tego komputera. (W Twoim skrypcie, prawdopodobnie następuje w tym momencie połączenie z danym zdalnym komputerem.) Teraz odczytujemy drugi wiersz pliku tekstowego, wywołujemy echo nazwy tego komputera, kontynuujemy działanie pętli, odczytujemy trzeci wiersz pliku tekstowego i działamy w ten sposób, dopóki nie zakończymy odczytywania każdego wiersza z pliku:

Const ForReading = 1



Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile _

    ("c:\scripts\servers.txt", ForReading)



Do Until objTextFile.AtEndOfStream

    strComputer = objTextFile.ReadLine

    Wscript.Echo strComputer

Loop



objTextFile.Close

Nie ma nic złego w odczytywaniu pliku tekstowego w ten sposób; wszystko działa bez zarzutu. Ale mogę sobie wyobrazić, dlaczego chcesz odczytać cały plik za jednym razem i pracować z listą umieszczoną w pamięci. W końcu, przypuśćmy, że nasz plik tekstowy znajduje się na zdalnym komputerze. Konieczne jest nie tylko ciągłe podróżowanie po sieci w celu odczytania jednego wiersza z pliku tekstowego, ale w przypadku awarii tego komputera, wystąpi także awaria skryptu.

Zatem czy można oczytać plik tekstowy za jednym razem, zachować tę informację w zmiennej, a następnie pracować z listą komputerów umieszczoną w pamięci? Oczywiście, że tak:

Const ForReading = 1



Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile _

    ("c:\scripts\servers.txt", ForReading)



strText = objTextFile.ReadAll

objTextFile.Close



arrComputers = Split(strText, vbCrLf)



For Each strComputer in arrComputers

    Wscript.Echo strComputer

Next

Oto, jak działa ten skrypt. Podobnie jak w Twoim obecnym skrypcie, tworzymy stałą (ForReading) i przypisujemy jej wartość 1; jest to wymagane podczas używania obiektu FileSystemObject do odczytu pliku tekstowego. Następnie tworzymy wystąpienie obiektu FileSystemObject i używamy metody OpenTextFile w celu otwarcia pliku C:\Scripts\Servers.txt. Ale to przecież nie wymagało wyjaśnienie, prawda?

Teraz przechodzimy do najistotniejszej części. Zamiast odczytywać plik wiersz po wierszu, używamy metody ReadAll w celu odczytania całego pliku tekstowego za jednym zamachem, zachowując ten plik w zmiennej o nazwie strText. Zmienna strText staje się teraz dokładną kopią pliku tekstowego. Załóżmy, że nasz plik tekstowy wygląda tak:

atl-ws-01

atl-ws-02

atl-ws-03

atl-ws-04

Zgadnijcie teraz, co zostanie wyświetlone na ekranie, jeżeli wywołamy echo wartości strText? Racja:

atl-ws-01

atl-ws-02

atl-ws-03

atl-ws-04

Jak do tej pory udało nam się odczytać cały plik tekstowy i zachować go w zmiennej. Niewiele nam to jednak daje; w końcu gdybyśmy spróbowali połączyć się z komputerem za pomocą zmiennej strText, połączylibyśmy się z całym plikiem tekstowym zamiast z pojedynczym komputerem, co nigdy nie zadziała. Teraz musimy oddzielić poszczególne nazwy komputerów, tak abyśmy mogli połączyć się z nimi pojedynczo.

Do tego posłuży nam następujący wiersz kodu:

arrComputers = Split(strText, vbCrLf)

Na podstawie danych (w tym przypadku zmiennej strText), polecenie Split tworzy tablicę. Jak ono rozpozna, w którym miejscu kończy się jedna nazwa komputera, a zaczyna kolejna? W naszym przykładzie delimiterem oddzielającym jedną nazwę komputera od drugiej jest znak powrotu karetki; w naszym pliku tekstowym wpisujemy jedną nazwę komputera, naciskamy klawisz ENTER i wpisujemy kolejną nazwę komputera. Stała vbCrLf skryptu VBScript używana razem z funkcją Split reprezentuje klawisz ENTER. Załóżmy, ze zmienna strText wygląda tak:

atl-ws-01,atl-ws-02,atl-ws-03,atl-ws-04

W tym przypadku, naszym delimiterem będzie przecinek, a polecenie Split będzie wyglądało tak:

arrComputers = Split(strText, “,”)

Innymi słowy, przekazujemy poleceniu Split nazwę zmiennej oraz delimiter, a ono załatwi resztę.

Kiedy już mamy nazwy komputerów bezpiecznie ukryte w tablicy, możemy powtórzyć każdy element w tej tablicy za pomocą pętli For Each:

For Each strComputer in arrComputers

    Wscript.Echo strComputer

Next

Gwoli otrzymania bardziej realistycznego przykładu, oto skrypt używający usługi WMI do połączenia się z każdym komputerem w pliku tekstowym i pobrania nazwy zainstalowanego systemu operacyjnego:

Const ForReading = 1



Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objTextFile = objFSO.OpenTextFile _

    ("c:\scripts\servers.txt", ForReading)



strText = objTextFile.ReadAll

objTextFile.Close



arrComputers = Split(strText, vbCrLf)



For Each strComputer in arrComputers



    Set objWMIService = GetObject _

        ("winmgmts:\\" & strComputer & "\root\cimv2")

    Set colItems = objWMIService.ExecQuery _

        ("Select * From Win32_OperatingSystem")

    For Each objItem in ColItems

        Wscript.Echo strComputer & ": " & objItem.Caption

    Next



Next
 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne