将第一行写入CSV文件时出现问题



我使用一个线程来运行我代码中的一个函数,下面是一个代码片段:

with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for addresses in ipa_str_s:
futures.append(executor.submit(checking_connection, ip_address=addresses))
for future in concurrent.futures.as_completed(futures):
save_result = (future.result())
saving_statistics(save_result, saving)

变量ipa_str_s有一个IP地址列表。

saving_statistics函数,它等待checking_connection函数的每次调用给我save the result的机会。

被调用函数saving_statistics:

def saving_statistics(save_result, saving):
with open(saving, 'a', encoding='utf-8') as csv_file:
csv_writer = csv.writer(csv_file, delimiter=';')
csv_writer.writerow(['IP-address', 'Packets_transmitted', 'Packets_received'])
csv_writer.writerow(save_result)

如果指定模式a,那么得到这个结果:

IP-address;Packets_transmitted;Packets_received
192.168.1.1;3;3
IP-address;Packets_transmitted;Packets_received;
192.168.1.2;3;0
IP-address;Packets_transmitted;Packets_received;
192.168.1.3;3;0

如果指定模式w,那么得到这个结果:

IP-address;Packets_transmitted;Packets_received
192.168.1.3;3;0

你能告诉我,我怎样才能找到这样一个文件的正常内容吗?

IP-address;Packets_transmitted;Packets_received
192.168.1.1;3;3
192.168.1.2;3;0
192.168.1.3;3;0

非常感谢!

每次调用saving_statistics函数时,函数都会写入第一行(ip地址;packets_transmit; packets_received)。

我看到三个解决方案:

  1. 在其他地方打开文件并写入第一行,然后根据需要调用该函数。当程序终止时关闭文件。
  2. 在函数第一次调用时设置一个变量为True,然后将其更改为false。使用此参数确定是否打印标题行
  3. 将ip地址保存在一个列表对象中,并在程序终止时写入所有ip地址。

根据您希望它运行的时间更改最佳选项。如果你计划让它运行一段时间,我会做1,并在main()的末尾有一个file.close(),或者你正在运行它。如果项目数量不多,3个可能是最简单的。2将导致最少的代码更改。

我认为你的整个过程就像进行一些异步网络连接一样简单,然后将结果收集到CSV文件中,并且这个过程可能在合理的时间内运行,并且不会重新启动。如果是,不要追加。

就像Loydms说的,只要打开然后写然后关闭:

import csv
import random
import time
import concurrent.futures

def checking_connection(addr):
sleep_ms = random.randrange(50, 100) / 1000
time.sleep(sleep_ms)
pckts_in = random.randrange(500, 1000)
pckts_out = random.randrange(500, 1000)
return addr, pckts_in, pckts_out, sleep_ms

with concurrent.futures.ThreadPoolExecutor() as executor:
futures = []
for address in [f"192.168.1.{x}" for x in range(256)]:
futures.append(executor.submit(checking_connection, address))

with open("data.csv", "w", newline="") as f:
writer = csv.writer(f, delimiter=";")
writer.writerow(["IP_address", "Packets_transmitted", "Packets_received", "Sleep"])
for future in concurrent.futures.as_completed(futures):
writer.writerow(future.result())

当我运行这段代码时,我每次都会得到一个新的CSV,带有一个标题和256行假IP统计数据,大约在1.8秒内:

| IP_address    | Packets_transmitted | Packets_received | Sleep |
|---------------|---------------------|------------------|-------|
| 192.168.1.94  | 879                 | 933              | 0.063 |
| 192.168.1.245 | 846                 | 577              | 0.079 |
| 192.168.1.144 | 555                 | 656              | 0.099 |
| 192.168.1.127 | 659                 | 936              | 0.06  |
| 192.168.1.43  | 706                 | 740              | 0.091 |
...

如果你的进程花费了不合理的时间,或者需要重新启动,那么要么选择日志记录方法,要么使用Python的SQLite3模块创建一个小数据库并进行插入。

当最终需要时,可以从日志文件或DB中创建CSV。

最新更新