<p>实际上,由于<code>struct.calcsize()</code>将告诉您它期望的长度,因此无大小记录相当容易处理。您可以使用它和数据的实际长度为<code>unpack()</code>构造一个新的格式字符串,其中包含正确的字符串长度。在</p>
<p>此函数只是<code>unpack()</code>的包装,允许在最后一个位置添加一个新的格式字符,该字符将删除终端NUL:</p>
<pre><code>import struct
def unpack_with_final_asciiz(fmt, dat):
"""
Unpack binary data, handling a null-terminated string at the end
(and only at the end) automatically.
The first argument, fmt, is a struct.unpack() format string with the
following modfications:
If fmt's last character is 'z', the returned string will drop the NUL.
If it is 's' with no length, the string including NUL will be returned.
If it is 's' with a length, behavior is identical to normal unpack().
"""
# Just pass on if no special behavior is required
if fmt[-1] not in ('z', 's') or (fmt[-1] == 's' and fmt[-2].isdigit()):
return struct.unpack(fmt, dat)
# Use format string to get size of contained string and rest of record
non_str_len = struct.calcsize(fmt[:-1])
str_len = len(dat) - non_str_len
# Set up new format string
# If passed 'z', treat terminating NUL as a "pad byte"
if fmt[-1] == 'z':
str_fmt = "{0}sx".format(str_len - 1)
else:
str_fmt = "{0}s".format(str_len)
new_fmt = fmt[:-1] + str_fmt
return struct.unpack(new_fmt, dat)
</code></pre>
<hr/>
^{pr2}$