Is it possible to get the underlying source (file, device-id, socket name) of a reader which implements Read
trait. As of now I'm explicitly passing a parameter in the below code which looks kind of awkward to me. Same thing for writer that implements Write
trait as well. The reason I need them is for debugging/logging purpose
fn copy<R: Read, W: Write>(&self, reader: R, src_file_name: &str, writer: W, dst_file_name: &str) -> Result<(), String>;
Is it possible to get the underlying source (file, device-id, socket name) of a reader which implements Read
trait. As of now I'm explicitly passing a parameter in the below code which looks kind of awkward to me. Same thing for writer that implements Write
trait as well. The reason I need them is for debugging/logging purpose
fn copy<R: Read, W: Write>(&self, reader: R, src_file_name: &str, writer: W, dst_file_name: &str) -> Result<(), String>;
Share
Improve this question
asked Mar 25 at 5:51
HarryHarry
3,2481 gold badge24 silver badges46 bronze badges
2
|
1 Answer
Reset to default 4You cannot just with Read
/Write
. This is by design. There may be more things than just files, devices, and sockets you can write to. Even Vec<u8>
implements Write
, for example -- what is a Vec<u8>
's "file name?"
In theory you could implement this with your own trait on File
, but then you'll run into another problem -- there is no way to get the backing filename from a File
. Note that there are platform-specific ways to get a file descriptor's filename on various platforms, but they are not guaranteed to be accurate. In particular, on POSIX systems you can create a file, open it, then unlink the file, and it will continue to exist until the last file descriptor is closed. In this case, the file does not have a name anymore. This may be why Rust does not expose a way to obtain a filename from a File
.
The only way I can really see to handle this differently from what you're doing is to combine both a name and a stream into a struct, like:
struct StreamWithName<S> {
stream: S,
name: String,
}
impl<S> StreamWithName<S> {
pub fn new(stream: S, name: String) -> Self {
Self { stream, name }
}
pub fn name(&self) -> &str {
&self.name
}
}
impl<W: Write> Write for StreamWithName<W> {
// Implement Write's methods and proxy calls to self.stream
}
impl<R: Read> Read for StreamWithName<R> {
// Implement Read's methods and proxy calls to self.stream
}
Then accept StreamWithName<_>
instead.
I'm not entirely sure this is better than just accepting names as separate arguments.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744215804a4563547.html
R = &[u8]
, which implementsRead
? What "underlying source" you'd expect to get in that case? – Cerberus Commented Mar 25 at 5:59copy
generic if you know your readers and writers are files? – kmdreko Commented Mar 25 at 18:08