package main import ( "bufio" "fmt" "log" "net/http" "os" "sync" ) func main() { // Check if the correct number of arguments is passed if len(os.Args) < 2 { fmt.Println("Usage: go run main.go ") return } // Get the input file from command line arguments inputFile := os.Args[1] // Open the input file file, err := os.Open(inputFile) if err != nil { log.Fatalf("Failed to open file: %v\n", err) } defer file.Close() // Create output files for works and failed URLs worksFile, err := os.Create("works.txt") if err != nil { log.Fatalf("Failed to create works.txt: %v\n", err) } defer worksFile.Close() failedFile, err := os.Create("failed.txt") if err != nil { log.Fatalf("Failed to create failed.txt: %v\n", err) } defer failedFile.Close() // Create a scanner to read the input file line by line scanner := bufio.NewScanner(file) // Channels for results worksChan := make(chan string) failedChan := make(chan string) // WaitGroup to wait for all goroutines to finish var wg sync.WaitGroup // Worker function to check URL checkURL := func(url string) { defer wg.Done() // Decrease the counter when the goroutine completes // Check if the URL is accessible resp, err := http.Get(url) if err != nil || resp.StatusCode != http.StatusOK { // If there's an error or the status is not 200 OK, send to failed channel failedChan <- url } else { // If the URL is successful, send to works channel worksChan <- url } // Close the response body if the request was successful if resp != nil { resp.Body.Close() } } // Goroutine to handle writing to works.txt go func() { for url := range worksChan { worksFile.WriteString(url + "\n") } }() // Goroutine to handle writing to failed.txt go func() { for url := range failedChan { failedFile.WriteString(url + "\n") } }() // Iterate through each line (URL) in the file and start a goroutine for each for scanner.Scan() { url := scanner.Text() wg.Add(1) // Increase the counter for each goroutine go checkURL(url) } // Wait for all goroutines to finish wg.Wait() // Close the channels once all URLs have been processed close(worksChan) close(failedChan) // Check for any scanner errors if err := scanner.Err(); err != nil { log.Fatalf("Error reading file: %v\n", err) } fmt.Println("URL check completed. See works.txt and failed.txt for results.") }