Jak wczytać cały plik tekstowy, zamiast wczytywać go wiersz po wierszu?
Skrypciarze odpowiadają na Wasze pytania
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! 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ść, 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 |