pythonsave

After clearing the file, I cannot save more data


I have a code whose role is to save data to a text file. I also have a function defined to clear the file. Unfortunately, after clearing the file, no more data gets saved. I'm saving the output of iperf.

 def start_client_and_print_results(self):
    '''Start iperf client and print results to console'''

    my_iperf_process = subprocess.Popen([self.initalize_iperf, "-c", self.ip_addr, self.force_flush],stdout=subprocess.PIPE)

    for line in my_iperf_process.stdout:
        print(line)
        self.starting_index_position += 1
        if (self.starting_index_position > self.start_line_to_write_into_file and self.starting_index_position < self.end_line): 
            self.save_results_to_file_txt(str(line) + "\n")
            self.save_results_to_file_csv(str(line) + "\n")

Function used to save data:

def save_results_to_file_txt(self, output):
    '''Save results to a text file'''
    client_results = open("client_results.txt", "a")
    client_results.write(output)
    client_results.close()

Clear data with:

def clear_file(self):
    clear = open("client_results.txt", "w")
    clear.close()

The above-mentioned functions are used together with the tkinter library, for which I have defined buttons with the appropriate functions.

button_iperf = tk.Button(root, text = "Start iperf client", command = iperfing.start_client_and_print_results)

button_clear = tk.Button(root, text = "Clear", command = iperfing.clear_file)

Any ideas?

I tried using the with statement in the file definition, but it didn't work.

Functions are defined in a class.

class Iperf():
    '''Class to handle iperf client functionality'''
    def __init__(self, initalize_iperf: str, force_flush: str, ip_addr: str, starting_index_position: int, start_line_to_write_into_file: int, end_line: int):
        '''Initialize the iperf client instance'''

        self.initalize_iperf  = initalize_iperf
        self.force_flush = force_flush
        self.ip_addr = ip_addr
        self.starting_index_position = starting_index_position
        self.start_line_to_write_into_file = start_line_to_write_into_file
        self.end_line = end_line

so full code looks like:

class Iperf():
    '''Class to handle iperf client functionality'''
    def __init__(self, initalize_iperf: str, force_flush: str, ip_addr: str, starting_index_position: int, start_line_to_write_into_file: int, end_line: int):
        '''Initialize the iperf client instance'''

        self.initalize_iperf  = initalize_iperf
        self.force_flush = force_flush
        self.ip_addr = ip_addr
        self.starting_index_position = starting_index_position
        self.start_line_to_write_into_file = start_line_to_write_into_file
        self.end_line = end_line

    def start_client_and_print_results(self):
        '''Start iperf client and print results to console'''

        my_iperf_process = subprocess.Popen([self.initalize_iperf, "-c", self.ip_addr, self.force_flush],stdout=subprocess.PIPE)

        for line in my_iperf_process.stdout:
            print(line)
            self.starting_index_position += 1
            if (self.starting_index_position > self.start_line_to_write_into_file and self.starting_index_position < self.end_line): 
                self.save_results_to_file_txt(str(line) + "\n")
                self.save_results_to_file_csv(str(line) + "\n")

        my_iperf_process.kill()

    def start_server(self):
        '''Start iperf server'''
        my_iperf_process = subprocess.Popen(["iperf3","-s","-B", self.ip_addr, self.force_flush],stdout=subprocess.PIPE)

    def save_results_to_file_txt(self, output):
        '''Save results to a text file'''
        client_results = open("client_results.txt", "a")
        client_results.write(output)
        client_results.close()

    def clear_file(self):
        clear = open("client_results.txt", "w")
        clear.close()

I use these parameters in the class.

iperf_path = "iperf3"
force_flush = "--forceflush"
ip_addr = ""  # Example IP address
starting_index_position = 0
start_line = 3
end_line = 14

Solution

  • Ok, I managed to find a workaround that looks like this. I'm not handling file saving through Python but doing it directly from the terminal instead:

    class Iperf:
        '''Class to handle iperf client functionality'''
        def __init__(self, initialize_iperf: str, force_flush: str, ip_addr: str, starting_index_position: int, start_line_to_write_into_file: int, end_line: int):
            '''Initialize the iperf client instance'''
            self.initialize_iperf = initialize_iperf
            self.force_flush = force_flush
            self.ip_addr = ip_addr
            self.starting_index_position = starting_index_position
            self.start_line_to_write_into_file = start_line_to_write_into_file
            self.end_line = end_line
            self.my_iperf_process = None  # Hold reference to the subprocess
    
        def start_client_and_print_results(self):
            '''Start iperf client and print results to console'''
            subprocess.run("iperf3 -c ip-address --forceflush > client_results.txt", shell=True)
            
    
        def start_server(self):
            '''Start iperf server'''
            my_iperf_process = subprocess.Popen(["iperf3", "-s", "-B", self.ip_addr, self.force_flush], stdout=subprocess.PIPE)
    
        def clear_file(self):
            '''Delete file'''
            os.remove("client_results.txt")
    
    # Example usage:
    iperf_instance = Iperf("iperf3", "--forceflush", "ip-address", 0, 5, 20)
    iperf_instance.start_client_and_print_results()
    iperf_instance.clear_file()
    iperf_instance.start_client_and_print_results()
    

    So even after deleting the file, I can overwrite it again. Thanks everyone for your time! Maybe we'll find another solution as well