Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Aplikacje oparte na plikach to programy zawarte w jednym *.cs pliku, które są kompilowane i uruchamiane bez odpowiedniego pliku projektu (*.csproj). Aplikacje oparte na plikach są idealne do nauki języka C#, ponieważ mają mniej złożoności: cały program jest przechowywany w jednym pliku. Aplikacje oparte na plikach są również przydatne do kompilowania narzędzi wiersza polecenia. Na platformach Unix aplikacje oparte na plikach można uruchamiać przy użyciu #!dyrektyw (shebang).
W tym samouczku nauczysz się następujących rzeczy:
- Utwórz program oparty na plikach.
- Dodaj obsługę narzędzia Shebang (
#!) systemu Unix. - Odczytywanie argumentów wiersza polecenia.
- Obsługa standardowych danych wejściowych.
- Pisanie danych wyjściowych grafiki ASCII.
- Przetwarzanie argumentów wiersza polecenia.
- Użyj przeanalizowanych wyników wiersza polecenia.
- Przetestuj ostateczną aplikację.
Tworzysz program oparty na plikach, który zapisuje tekst jako sztukę ASCII. Aplikacja jest zawarta w jednym pliku, używa pakietów NuGet, które implementują niektóre podstawowe funkcje.
Wymagania wstępne
- Zestaw .NET 10 SDK. Pobierz go z witryny pobierania platformy .NET.
- Visual Studio Code. Pobierz go ze strony głównej programu Visual Studio Code.
- (Opcjonalnie) Rozszerzenie C# DevKit dla programu Visual Studio Code. Pobierz go z witryny Marketplace programu Visual Studio Code.
Tworzenie programu opartego na plikach
Otwórz program Visual Studio Code i utwórz nowy plik o nazwie
AsciiArt.cs. Wprowadź następujący tekst:Console.WriteLine("Hello, world!");Zapisz plik. Następnie otwórz zintegrowany terminal w programie Visual Studio Code i wpisz:
dotnet run AsciiArt.cs
Przy pierwszym uruchomieniu tego programu dotnet host tworzy plik wykonywalny z pliku źródłowego, przechowuje artefakty kompilacji w folderze tymczasowym, a następnie uruchamia utworzony plik wykonywalny. Możesz zweryfikować to środowisko, wpisując dotnet run AsciiArt.cs ponownie. Tym razem host określa, dotnet że plik wykonywalny jest bieżący i uruchamia plik wykonywalny bez ponownego utworzenia pliku wykonywalnego. Nie widzisz żadnych danych wyjściowych kompilacji.
W poprzednich krokach pokazano, że aplikacje oparte na plikach nie są plikami skryptów. Są to pliki źródłowe języka C#, które są tworzone przy użyciu wygenerowanego pliku projektu w folderze tymczasowym. Jeden z wierszy danych wyjściowych wyświetlanych podczas tworzenia programu powinien wyglądać mniej więcej tak (w systemie Windows):
AsciiArt succeeded (7.3s) → AppData\Local\Temp\dotnet\runfile\AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc\bin\debug\AsciiArt.dll
Na platformach unix folder wyjściowy jest podobny do następującego:
AsciiArt succeeded (7.3s) → Library/Application Support/dotnet/runfile/AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc/bin/debug/AsciiArt.dll
Te dane wyjściowe informują o tym, gdzie są umieszczane pliki tymczasowe i dane wyjściowe kompilacji. W ramach tego samouczka podczas edytowania pliku źródłowego host aktualizuje plik dotnet wykonywalny przed jego uruchomieniem.
Aplikacje oparte na plikach to zwykłe programy w języku C#. Jedynym ograniczeniem jest to, że muszą być zapisywane w jednym pliku źródłowym. Jako punkt wejścia można użyć instrukcji najwyższego poziomu lub metody klasycznej Main . Można zadeklarować dowolne typy: klasy, interfejsy i struktury. Algorytmy można strukturę w programie opartym na plikach tak samo jak w dowolnym programie języka C#. Można nawet zadeklarować wiele przestrzeni nazw, aby zorganizować kod. Jeśli okaże się, że program oparty na plikach rośnie zbyt duży dla pojedynczego pliku, możesz przekonwertować go na program oparty na projekcie i podzielić źródło na wiele plików. Aplikacje oparte na plikach to doskonałe narzędzie do tworzenia prototypów. Możesz rozpocząć eksperymentowanie z minimalnym obciążeniem, aby udowodnić koncepcje i algorytmy kompilacji.
Obsługa systemu Unix shebang (#!)
Uwaga / Notatka
#! Obsługa dyrektyw dotyczy tylko platform unix. Nie ma podobnej dyrektywy dla systemu Windows do bezpośredniego wykonywania programu w języku C#. W systemie Windows należy użyć dotnet run polecenia w wierszu polecenia.
W systemie UNIX można uruchamiać aplikacje oparte na plikach bezpośrednio, wpisując nazwę pliku źródłowego w wierszu polecenia zamiast dotnet run. Musisz wprowadzić dwie zmiany:
Ustaw uprawnienia wykonywania w pliku źródłowym:
chmod +x AsciiArt.csDodaj dyrektywę shebang (
#!) jako pierwszy wierszAsciiArt.cspliku:#!/usr/local/share/dotnet/dotnet run
Lokalizacja dotnet programu może być inna w różnych instalacjach systemu UNIX. Użyj polecenia which dotnet , aby zlokalizować dotnet hosta w swoim środowisku.
Alternatywnie możesz użyć #!/usr/bin/env dotnet, aby automatycznie ustalić ścieżkę dotnet ze zmiennej środowiskowej PATH.
#!/usr/bin/env dotnet
Po wprowadzeniu tych dwóch zmian można uruchomić program bezpośrednio z poziomu wiersza polecenia:
./AsciiArt.cs
Jeśli wolisz, możesz usunąć rozszerzenie, aby można było wpisać ./AsciiArt zamiast tego. Możesz dodać element #! do pliku źródłowego, nawet jeśli używasz systemu Windows. Wiersz polecenia systemu Windows nie obsługuje #!programu , ale kompilator języka C# umożliwia korzystanie z tej dyrektywy w aplikacjach opartych na plikach na wszystkich platformach.
Odczytywanie argumentów wiersza polecenia
Teraz zapisz wszystkie argumenty w wierszu polecenia w danych wyjściowych.
Zastąp bieżącą zawartość
AsciiArt.csnastępującym kodem:if (args.Length > 0) { string message = string.Join(' ', args); Console.WriteLine(message); }Tę wersję można uruchomić, wpisując następujące polecenie:
dotnet run AsciiArt.cs -- This is the command line.Opcja
--wskazuje, że wszystkie następujące argumenty poleceń powinny zostać przekazane do programu AsciiArt. ArgumentyThis is the command line.są przekazywane jako tablica ciągów, gdzie każdy ciąg jest jednym wyrazem:This, ,isthe,command, iline..
Ta wersja demonstruje następujące nowe pojęcia:
- Argumenty wiersza polecenia są przekazywane do programu przy użyciu wstępnie zdefiniowanej zmiennej
args. Zmiennaargsjest tablicą ciągów:string[]. Jeśli długośćargswynosi 0, oznacza to, że nie podano żadnych argumentów. W przeciwnym razie każde słowo na liście argumentów jest przechowywane w odpowiednim wpisie w tablicy. - Metoda
string.Joinłączy wiele ciągów w jeden ciąg z określonym separatorem. W tym przypadku separator jest jedną spacją. - Console.WriteLine Zapisuje ciąg w standardowej konsoli wyjściowej, a następnie nowy wiersz.
Obsługa standardowych danych wejściowych
Obsługuje to poprawnie argumenty wiersza polecenia. Teraz dodaj kod do obsługi odczytywania danych wejściowych ze standardowych danych wejściowych (stdin) zamiast argumentów wiersza polecenia.
Dodaj następującą
elseklauzulę do instrukcjiifdodanej w poprzednim kodzie:else { while (Console.ReadLine() is string line && line.Length > 0) { Console.WriteLine(line); } }Powyższy kod odczytuje dane wejściowe konsoli do momentu odczytania pustego wiersza lub elementu
null. (Metoda Console.ReadLine zwracanull, jeśli strumień wejściowy jest zamknięty, wpisując ctrl+C.)Przetestuj odczytywanie standardowych danych wejściowych, tworząc nowy plik tekstowy w tym samym folderze. Nadaj plikowi
input.txtnazwę i dodaj następujące wiersze:Hello from ... dotnet! You can create file-based apps in .NET 10 and C# 14 Have fun writing useful utilitiesZachowaj krótkie wiersze, aby formatować je poprawnie podczas dodawania funkcji do używania grafiki ASCII.
Uruchom ponownie program.
Za pomocą powłoki bash:
cat input.txt | dotnet run AsciiArt.csLub za pomocą programu PowerShell:
Get-Content input.txt | dotnet run AsciiArt.cs
Teraz program może zaakceptować argumenty wiersza polecenia lub standardowe dane wejściowe.
Pisanie danych wyjściowych ASCII Art
Następnie dodaj pakiet, który obsługuje sztukę ASCII, Colorful.Console. Aby dodać pakiet do programu opartego na plikach, należy użyć #:package dyrektywy .
Dodaj następującą dyrektywę po
#!dyrektywie w pliku AsciiArt.cs:#:package Colorful.Console@1.2.15Ważne
Wersja
1.2.15była najnowszą wersjąColorful.Consolepakietu, gdy ten samouczek został ostatnio zaktualizowany. Sprawdź stronę NuGet pakietu dla najnowszej wersji, aby upewnić się, że używasz wersji pakietu z najnowszymi poprawkami zabezpieczeń.Zmień wiersze, które wywołają
Console.WriteLinemetodęColorful.Console.WriteAscii, aby zamiast tego użyć metody:async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }Uruchom program i zobaczysz dane wyjściowe grafiki ASCII zamiast tekstu.
Opcje polecenia procesu
Następnie dodajmy analizowanie wiersza polecenia. Bieżąca wersja zapisuje każde słowo jako inny wiersz danych wyjściowych. Dodane argumenty wiersza polecenia obsługują dwie funkcje:
Cytuj wiele wyrazów, które powinny być zapisywane w jednym wierszu:
AsciiArt.cs "This is line one" "This is another line" "This is the last line"Dodaj opcję wstrzymania
--delaymiędzy poszczególnymi wierszami:AsciiArt.cs --delay 1000
Użytkownicy powinni mieć możliwość używania obu argumentów razem.
Większość aplikacji wiersza polecenia musi analizować argumenty wiersza polecenia, aby efektywnie obsługiwać opcje, polecenia i dane wejściowe użytkownika.
BibliotekaSystem.CommandLine udostępnia kompleksowe możliwości obsługi poleceń, poleceń podrzędnych, opcji i argumentów, co pozwala skoncentrować się na tym, co robi aplikacja, a nie na mechaniki analizowania danych wejściowych wiersza polecenia.
Biblioteka System.CommandLine oferuje kilka kluczowych korzyści:
- Automatyczne generowanie tekstu i walidacja tekstu.
- Obsługa konwencji wiersza polecenia POSIX i Windows.
- Wbudowane możliwości uzupełniania kart.
- Spójne zachowanie analizowania w aplikacjach.
System.CommandLineDodaj pakiet. Dodaj tę dyrektywę po istniejącej dyrektywie pakietu:#:package System.CommandLine@2.0.0Ważne
Wersja
2.0.0była najnowszą wersją, gdy ten samouczek został ostatnio zaktualizowany. Jeśli jest dostępna nowsza wersja, użyj najnowszej wersji, aby upewnić się, że masz najnowsze pakiety zabezpieczeń. Sprawdź stronę NuGet pakietu dla najnowszej wersji, aby upewnić się, że używasz wersji pakietu z najnowszymi poprawkami zabezpieczeń.Dodaj niezbędne instrukcje using w górnej części pliku (po dyrektywach
#!i#:package):using System.CommandLine; using System.CommandLine.Parsing;Zdefiniuj opcję opóźnienia i argument komunikatów. Dodaj następujący kod, aby utworzyć
CommandLine.Optionobiekty iCommandLine.Argumentreprezentujące opcję wiersza polecenia i argument:Option<int> delayOption = new("--delay") { Description = "Delay between lines, specified as milliseconds.", DefaultValueFactory = parseResult => 100 }; Argument<string[]> messagesArgument = new("Messages") { Description = "Text to render." };W aplikacjach wiersza polecenia opcje zazwyczaj zaczynają się
--od (podwójna kreska) i mogą akceptować argumenty. Opcja--delayakceptuje argument liczby całkowitej, który określa opóźnienie w milisekundach. OkreślamessagesArgument, jak wszystkie pozostałe tokeny po opcjach są analizowane jako tekst. Każdy token staje się oddzielnym ciągiem w tablicy, ale tekst może być cytowany w celu uwzględnienia wielu wyrazów w jednym tokenie. Na przykład"This is one message"staje się pojedynczym tokenem, a jednocześnieThis is four tokensstaje się czterema oddzielnymi tokenami.Powyższy kod definiuje typ argumentu
--delaydla opcji i że argumenty są tablicąstringwartości. Ta aplikacja ma tylko jedno polecenie, więc używasz głównego polecenia.Utwórz polecenie główne i skonfiguruj je za pomocą opcji i argumentu. Dodaj argument i opcję do głównego polecenia:
RootCommand rootCommand = new("Ascii Art file-based program sample"); rootCommand.Options.Add(delayOption); rootCommand.Arguments.Add(messagesArgument);Dodaj kod, aby przeanalizować argumenty wiersza polecenia i obsłużyć wszelkie błędy. Ten kod weryfikuje argumenty wiersza polecenia i przechowuje przeanalizowane argumenty w System.CommandLine.ParseResult obiekcie:
ParseResult result = rootCommand.Parse(args); foreach (ParseError parseError in result.Errors) { Console.Error.WriteLine(parseError.Message); } if (result.Errors.Count > 0) { return 1; }
Powyższy kod weryfikuje wszystkie argumenty wiersza polecenia. Jeśli walidacja zakończy się niepowodzeniem, błędy są zapisywane w konsoli programu , a aplikacja kończy działanie.
Korzystanie z analizowanych wyników wiersza polecenia
Teraz zakończ aplikację, aby użyć przeanalizowanych opcji i zapisać dane wyjściowe. Najpierw zdefiniuj rekord do przechowywania analizowanych opcji. Aplikacje oparte na plikach mogą zawierać deklaracje typów, takie jak rekordy i klasy. Muszą one znajdować się po wszystkich instrukcjach najwyższego poziomu i funkcjach lokalnych.
Dodaj deklarację
recorddo przechowywania komunikatów i wartości opcji opóźnienia:public record AsciiMessageOptions(string[] Messages, int Delay);Dodaj następującą funkcję lokalną przed deklaracją rekordu. Ta metoda obsługuje zarówno argumenty wiersza polecenia, jak i standardowe dane wejściowe i zwraca nowe wystąpienie rekordu:
async Task<AsciiMessageOptions> ProcessParseResults(ParseResult result) { int delay = result.GetValue(delayOption); List<string> messages = [.. result.GetValue(messagesArgument) ?? Array.Empty<string>()]; if (messages.Count == 0) { while (Console.ReadLine() is string line && line.Length > 0) { Colorful.Console.WriteAscii(line); await Task.Delay(delay); } } return new([.. messages], delay); }Utwórz funkcję lokalną, aby napisać grafikę ASCII z określonym opóźnieniem. Ta funkcja zapisuje każdy komunikat w rekordzie z określonym opóźnieniem między poszczególnymi komunikatami:
async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }Zastąp zapisaną
ifwcześniej klauzulę następującym kodem, który przetwarza argumenty wiersza polecenia i zapisuje dane wyjściowe:var parsedArgs = await ProcessParseResults(result); await WriteAsciiArt(parsedArgs); return 0;
Utworzono record typ, który zapewnia strukturę analizowanych opcji wiersza polecenia i argumentów. Nowe funkcje lokalne tworzą wystąpienie rekordu i używają rekordu do zapisywania danych wyjściowych sztuki ASCII.
Testowanie ostatecznej aplikacji
Przetestuj aplikację, uruchamiając kilka różnych poleceń. Jeśli masz problem, oto gotowy przykład do porównania z utworzonymi elementami:
#!/usr/local/share/dotnet/dotnet run
#:package Colorful.Console@1.2.15
#:package System.CommandLine@2.0.0
using System.CommandLine;
using System.CommandLine.Parsing;
Option<int> delayOption = new("--delay")
{
Description = "Delay between lines, specified as milliseconds.",
DefaultValueFactory = parseResult => 100
};
Argument<string[]> messagesArgument = new("Messages")
{
Description = "Text to render."
};
RootCommand rootCommand = new("Ascii Art file-based program sample");
rootCommand.Options.Add(delayOption);
rootCommand.Arguments.Add(messagesArgument);
ParseResult result = rootCommand.Parse(args);
foreach (ParseError parseError in result.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
if (result.Errors.Count > 0)
{
return 1;
}
var parsedArgs = await ProcessParseResults(result);
await WriteAsciiArt(parsedArgs);
return 0;
async Task<AsciiMessageOptions> ProcessParseResults(ParseResult result)
{
int delay = result.GetValue(delayOption);
List<string> messages = [.. result.GetValue(messagesArgument) ?? Array.Empty<string>()];
if (messages.Count == 0)
{
while (Console.ReadLine() is string line && line.Length > 0)
{
// <WriteAscii>
Colorful.Console.WriteAscii(line);
// </WriteAscii>
await Task.Delay(delay);
}
}
return new([.. messages], delay);
}
async Task WriteAsciiArt(AsciiMessageOptions options)
{
foreach (string message in options.Messages)
{
Colorful.Console.WriteAscii(message);
await Task.Delay(options.Delay);
}
}
public record AsciiMessageOptions(string[] Messages, int Delay);
W tym samouczku przedstawiono tworzenie programu opartego na plikach, w którym program jest kompilny w jednym pliku C#. Te programy nie używają pliku projektu i mogą używać #! dyrektywy w systemach unix. Uczniowie mogą tworzyć te programy po wypróbowaniu naszych samouczków online i przed utworzeniem większych aplikacji opartych na projekcie. Aplikacje oparte na plikach są również doskonałą platformą dla narzędzi wiersza polecenia.