文件写入未按程序流程预期发生
这对我来说不是个新问题。从C语言到PERL,再到Python,在Windows Mobile、Windows XP和其他Windows版本上,这个问题一直存在,让我很烦。
现在在我最新的脚本中,这个问题又出现了。具体来说,我用Python写了一个简单的脚本。这个脚本在调试器中运行时能正确写入文件,但在调试器外运行时就不行了。它在应该写入文件的时候却没有写。
我使用的是Python 2.6,搭配Eclipse和PyDev。
这是代码
import httplib2
import thread
ht = httplib2.Http();
list = []
k = 0
def check(proxy, port):
global list
global k
try:
head = ht.request(proxy, 'HEAD')
except:
return
k = k + 1
list.append(proxy)
list.append(port)
def OnListCaller(ProxyList, OutFile, NListLen):
global list
global k
filei = open(ProxyList, 'r')
fileo = open(OutFile, 'a')
while 1:
proxy = filei.readline()
if not proxy: continue
port = filei.readline()
proxy = proxy.rstrip()
port = port.rstrip()
thread.start_new(check, (proxy, port,))
if k >= NListLen:
for t in list:
fileo.write(t + "\n")
list = []
fileo.close()
fileo = open(OutFile, 'a')
k = 0
OnListCaller('C:\proxy\input.txt', 'C:\proxy\checked.txt', 1)
问题出在OnListCaller的if k>=NListLen这一行。当k大于等于某个值时,文件应该被更新。感谢大家。
5 个回答
import httplib2
import thread
import os
import sys
proxy = proxy.rstrip()
port = port.rstrip()
#TODO: regleaza pentru unix cand o sa fie nevoie
thread.start_new(check, (proxy, port, OutFile,))
这段代码主要是用来检查代理服务器的。下面我来给你简单解释一下每一部分。
首先,代码中引入了一个叫做`httplib2`的库,这个库可以帮助我们发送网络请求。
接下来,定义了一个叫`check`的函数,这个函数需要三个参数:`proxy`(代理地址)、`port`(端口号)和`OutFile`(输出文件名)。
在这个函数里,首先用`ht.request(proxy, 'HEAD')`来发送一个请求,目的是检查这个代理是否可用。如果请求失败了,就会跳过这个代理,不做任何处理。
如果请求成功,代码会打开一个文件(`OutFile`),并把代理地址和端口号写进去。写完后,还会确保文件内容被保存,然后关闭文件。
接下来是另一个函数,叫`OnListCaller`,这个函数的作用是读取一个包含代理地址的文件(`ProxyList`),并逐行处理这些代理。
在这个函数中,首先打开代理列表文件,然后用一个无限循环来逐行读取代理地址。如果读取到的行是空的,就会继续下一次循环,跳过这一行。接着,它还会读取对应的端口号。
最后,代码中有一行调用了`OnListCaller`函数,传入了三个参数:代理列表文件的路径、输出文件的路径和一个数字(这里是1)。
最后一句话提到“这是修正后的代码”,说明之前的代码可能有问题,现在这个版本是经过修改的。
记住你妈妈教过你的:
一定要记得清空缓存()
(在Python中,就是先用 file_object.flush()
,然后再用 os.fsync(file_object.fileno())
)
关于这段代码:
看起来真正的问题是和线程有关,而不是文件:
当你在执行这段代码的时候:
for t in list:
fileo.write(t + "\n")
list = []
fileo.close()
fileo = open(OutFile, 'a')
k = 0
list
正在被你创建的线程修改。我不太清楚 'for x in y' 在多线程下是怎么工作的,但我想可能是因为在第一次执行循环体后,添加到列表中的元素没有被包含进来。
要解决这个问题,你需要为 list
使用一个互斥锁(mutex),在整个循环期间都要锁住它(直到你清空列表),而且每次你往列表里添加东西的时候也要锁住。