Dlang File.detach() 和 File.close() 的区别及错误分析
我遇到以下 Dlang 代码运行报错的问题,代码如下:
import std.stdio;
void main()
{
auto file1 = File('example.txt', 'w');
file1.writeln('Hello, world!');
auto file2 = File('example.txt', 'r');
writeln(file2.name()); // 输出 'example.txt'
writeln(file2.eof()); // 输出 false
file2.detach();
writeln(file1.eof()); // 输出 false
file1.readln(); // 读取 'Hello, world!'
writeln(file1.eof()); // 输出 true
file1.close(); // 关闭文件
}
运行报错如下:
example.txt
false
false
std.stdio.StdioException@std/stdio.d(5156): Bad file descriptor
----------------
??:? @safe void std.stdio.StdioException.opCall() [0x44ecf1]
??:? @trusted const(long) std.stdio.readlnImpl(shared(core.stdc.stdio._IO_FILE)*, ref char[], dchar, std.stdio.File.Orientation).__lambda9() [0x442d90]
??:? @safe ulong std.stdio.readlnImpl(shared(core.stdc.stdio._IO_FILE)*, ref char[], dchar, std.stdio.File.Orientation) [0x442cf8]
??:? @safe ulong std.stdio.File.readln!(char).readln(ref char[], dchar) [0x43dd6c]
??:? @safe immutable(char)[] std.stdio.File.readln!(immutable(char)[]).readln(dchar) [0x43dcae]
??:? _Dmain [0x43c97d]
为什么调用 file2.detach(); 后 file1.readln 无法读取了呢?我查阅了 Dlang 文档 https://dlang.org/phobos/std_stdio.html 对 detach 的介绍,如下:
@trusted void detach();
Detaches from the underlying file. If the sole owner, calls close.
Throws:
ErrnoException on failure if closing the file.
我的理解是 detach() 和 close() 的区别在于,detach() 方法只是将 File 对象与底层文件分离,但不会关闭文件,而 close() 方法会关闭文件,释放资源。难道我的理解有误?请帮我分析解释 detach 和 close 的区别到底是什么?
分析解释:
根据你的代码和报错信息,我可以看出问题出在了 file2.detach() 这一行。在调用 detach() 方法后,你已经将 file2 对象与底层文件分离了,因此在后续调用 file1.readln() 时,它仍然会尝试读取 example.txt 这个文件,但此时文件已经被 file2 对象分离了,因此会抛出 Bad file descriptor 的异常。
至于 detach() 和 close() 的区别,你的理解是正确的。detach() 方法只是将 File 对象与底层文件分离,但不会关闭文件,而 close() 方法会关闭文件,释放资源。在你的代码中,可以看到 file1.close() 是在读取完文件后调用的,这是正确的做法。如果你想在读取文件之前关闭文件,可以使用 scope 语句来确保文件在离开该作用域时被关闭,例如:
import std.stdio;
void main()
{
{
auto file1 = File('example.txt', 'w');
file1.writeln('Hello, world!');
} // 文件会在离开这个作用域时被关闭
auto file2 = File('example.txt', 'r');
writeln(file2.name()); // 输出 'example.txt'
writeln(file2.eof()); // 输出 false
file2.detach();
{
auto file1 = File('example.txt', 'r');
writeln(file1.readln()); // 读取 'Hello, world!'
writeln(file1.eof()); // 输出 true
} // 文件会在离开这个作用域时被关闭
}
总结:
detach() 方法只是将 File 对象与底层文件分离,但不会关闭文件,而 close() 方法会关闭文件,释放资源。在使用 detach() 方法后,File 对象不再与底层文件绑定,因此无法再使用该对象进行文件操作。建议在使用 detach() 方法后,确保不再使用该 File 对象进行文件操作。
原文地址: http://www.cveoy.top/t/topic/ox9e 著作权归作者所有。请勿转载和采集!