文件写入未按程序流程预期发生

2 投票
5 回答
6862 浏览
提问于 2025-04-15 17:33

这对我来说不是个新问题。从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 个回答

1

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)。

最后一句话提到“这是修正后的代码”,说明之前的代码可能有问题,现在这个版本是经过修改的。

8

记住你妈妈教过你的:

一定要记得清空缓存()

(在Python中,就是先用 file_object.flush(),然后再用 os.fsync(file_object.fileno())

2

关于这段代码:

看起来真正的问题是和线程有关,而不是文件:

当你在执行这段代码的时候:

    for t in list:
        fileo.write(t + "\n")
    list = []
    fileo.close()
    fileo = open(OutFile, 'a')
    k = 0

list 正在被你创建的线程修改。我不太清楚 'for x in y' 在多线程下是怎么工作的,但我想可能是因为在第一次执行循环体后,添加到列表中的元素没有被包含进来。

要解决这个问题,你需要为 list 使用一个互斥锁(mutex),在整个循环期间都要锁住它(直到你清空列表),而且每次你往列表里添加东西的时候也要锁住。

撰写回答