简体   繁体   English

open()不起作用后关闭文件

[英]Close file after open() doesn't work

When I run this function, it hangs because I am using the open() function to read a csv and I need to close it. 当我运行此函数时,它挂起,因为我正在使用open()函数读取csv,并且需要将其关闭。 I put the close() function where I think it's supposed to go, however it doesn't seem to be working. 我把close()函数放到了我认为应该去的地方,但是似乎没有用。 I've put the close() function in line with the "while True" indent, "for i in byte" indent and it doesn't work on either. 我已经将close()函数与“ while True”缩进符,“ for i in byte”缩进符放在一起,并且对任何一个都不起作用。 What am I doing wrong? 我究竟做错了什么?

def parse(text):
    #states
    is_token = False
    previous_character_is_escape = False
    no_quote_value = True
    quote_value = False


    file_base = os.path.basename('"app/csv_upload_directory/%s' % text)
    new_base = os.path.splitext(file_base)[0]

    row_counter = 1
    token_counter = 0
    fo = open("csv_upload_directory/%s_results.csv" % new_base, "w+")

    fo.write("Row %i" % row_counter + '\n')
    row_counter += 1
    with io.open(text,'rb',newline=None) as f:
        while True:
            byte = f.read(1)
            for i in byte:
                #print "%s,%s" % (no_quote_value,previous_character_is_escape)
                if is_token == False:
                    if i == '"':
                        fo.write(i)
                        token_counter = 0
                        is_token = True
                        no_quote_value = False
                        quote_value = True
                    elif i == '\n':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        fo.write("Row %i" % (row_counter))
                        fo.write("\n")
                        token_counter = 0
                        row_counter += 1
                    elif i == ',':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        token_counter = 0
                    elif no_quote_value == True:
                        fo.write(i)
                        token_counter += 1
                        is_token = True
                        quote_value = False
                    else:
                        fo.write(i)
                        token_counter += 1


                elif is_token == True:
                    # start of an escape sequence
                    if i == '\\':
                        fo.write(i)
                        token_counter += 1
                        previous_character_is_escape = True
                    # for line delimiter, the quoted values are being processed outside token
                    elif no_quote_value == True and i == '\n':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        fo.write("Row %i" % (row_counter))
                        fo.write("\n")
                        token_counter = 0
                        row_counter += 1
                        is_token = False
                    # if token is not a quoted value but ends with quotes, and there is no escape character
                    elif no_quote_value == True and previous_character_is_escape == False and i == '"':
                        fo.write(i)
                        fo.write("This is a not a valid token, this is not a quoted value but there is an ending quote")
                        return False
                    # builds off previous_character_is_escape and captures any escape sequence
                    elif previous_character_is_escape == True:
                        fo.write(i)
                        token_counter += 1
                        previous_character_is_escape = False
                    # this type of quote is the end of token, returns back to other if statement
                    elif previous_character_is_escape == False and i == '"':
                        fo.write(i)
                        no_quote_value = True
                        quote_value = False
                        is_token = False
                    # if token starts as a quote but ends without quotes
                    elif quote_value == True and previous_character_is_escape == False and i == ',':
                        fo.write(i)
                        fo.write("This is not a valid token, there should be a quote at the end of this token")
                        return False
                    # this comma marks the end of a non quoted token, this invokes a newline
                    elif no_quote_value == True and previous_character_is_escape == False and i == ',':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        token_counter = 0
                        is_token = False
                    elif no_quote_value == False and i == ',':
                        fo.write(i)
                        fo.write("DONG")
                    else:
                        fo.write(i)
                        token_counter += 1
        fo.close()

parse('example.csv')

From your comment, it sounds like closing the files is not actually your issue (though it is something you should take care of). 从您的评论看来,关闭文件实际上不是您的问题(尽管这是您应该注意的问题)。 The real issue is that your function never ends. 真正的问题是您的功能永无止境。

This is because you're looping forever, attempting to read one character per iteration. 这是因为您将永远循环,尝试每次迭代读取一个字符。 When the file has all been read, you're not noticing it that you get empty bytestrings from f.read(1) . 读取完所有文件后,您不会注意到它从f.read(1)获得空字节f.read(1) You should add some logic to break out of the loop when that happens. 您应该添加一些逻辑以在发生这种情况时跳出循环。

A further issue: you're currently using a for loop to iterate over the one-byte string you're getting from read(1) . 另一个问题:您当前正在使用for循环遍历从read(1)获得的一字节字符串。 There's no need for that loop, and it makes it hard to break out of the while loop using a break statement. 不需要该循环,这使得使用break语句很难打破while循环。

Try: 尝试:

with io.open(text,'rb',newline=None) as f, fo:   # add fo to the with statement
    while True:
        i = f.read(1)        # read directly to "i", no need for the extra loop on bytes
        if i == '':          # check if read gave us an empty string (happens at EOF)
            break
        if is_token == True:
            # ...

So, you are opening two files here. 因此,您将在此处打开两个文件。 One with the reference of fo and the other with f . 一个以fo为参考,另一个以f为参考。

For fo , you are using open() method to perform file operations and you need to close it appropriately with fo.close() . 对于fo ,您正在使用open()方法执行文件操作,您需要使用fo.close()将其适当关闭。

However, this is not the case with f . 但是, f并非如此。 Since you are using with ... open() method, you don't need to close it as it efficiently handles closing the file after its completes code block execution. 由于您使用的with ... open()方法,因此不需要关闭它,因为它可以在完成代码块执行后有效地处理关闭文件。 Read about the related documentation here . 在此处阅读相关文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM