1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use super::{BufWriter, ErrorKind, Read, Result, Write, DEFAULT_BUF_SIZE};
use crate::mem::MaybeUninit;

/// 将 reader 的全部内容复制到 writer 中。
///
/// 此函数将连续从 `reader` 读取数据,然后以流方式将其写入 `writer`,直到 `reader` 返回 EOF。
///
///
/// 成功后,将返回从 `reader` 复制到 `writer` 的字节总数。
///
/// 如果要将一个文件的内容复制到另一个文件,并且正在使用文件系统路径,请参见 [`fs::copy`] 函数。
///
/// [`fs::copy`]: crate::fs::copy
///
/// # Errors
///
/// 如果对 [`read`] 或 [`write`] 的任何调用返回错误,则此函数将立即返回错误。
/// 此函数将处理 [`ErrorKind::Interrupted`] 的所有实例,并重试基础操作。
///
/// [`read`]: Read::read
/// [`write`]: Write::write
///
/// # Examples
///
/// ```
/// use std::io;
///
/// fn main() -> io::Result<()> {
///     let mut reader: &[u8] = b"hello";
///     let mut writer: Vec<u8> = vec![];
///
///     io::copy(&mut reader, &mut writer)?;
///
///     assert_eq!(&b"hello"[..], &writer[..]);
///     Ok(())
/// }
/// ```
///
///
///
///
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
where
    R: Read,
    W: Write,
{
    cfg_if::cfg_if! {
        if #[cfg(any(target_os = "linux", target_os = "android"))] {
            crate::sys::kernel_copy::copy_spec(reader, writer)
        } else {
            generic_copy(reader, writer)
        }
    }
}

/// `io::copy` 的用户空间读写循环实现,当特定于 OS 的专门用于复制卸载的专业化不可用或不适用时,将使用该 `io::copy`。
///
pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
where
    R: Read,
    W: Write,
{
    BufferedCopySpec::copy_to(reader, writer)
}

/// 使用栈缓冲区或重用 BufWriter 的内部缓冲区的读写循环的特殊化
///
trait BufferedCopySpec: Write {
    fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64>;
}

impl<W: Write + ?Sized> BufferedCopySpec for W {
    default fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
        stack_buffer_copy(reader, writer)
    }
}

impl<I: Write> BufferedCopySpec for BufWriter<I> {
    fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
        if writer.capacity() < DEFAULT_BUF_SIZE {
            return stack_buffer_copy(reader, writer);
        }

        // FIXME: #42788
        //
        //   - 这将创建 (mut) 对 _uninitialized_ 整数切片的引用,这是 **未定义的行为**
        //
        //   - 基于标准库对不稳定 rustc 内部的权限知识,只有标准库才能做到这一点。
        //
        //
        //
        unsafe {
            let spare_cap = writer.buffer_mut().spare_capacity_mut();
            reader.initializer().initialize(MaybeUninit::slice_assume_init_mut(spare_cap));
        }

        let mut len = 0;

        loop {
            let buf = writer.buffer_mut();
            let spare_cap = buf.spare_capacity_mut();

            if spare_cap.len() >= DEFAULT_BUF_SIZE {
                match reader.read(unsafe { MaybeUninit::slice_assume_init_mut(spare_cap) }) {
                    Ok(0) => return Ok(len), // 到达 EOF
                    Ok(bytes_read) => {
                        assert!(bytes_read <= spare_cap.len());
                        // SAFETY: 初始化契约保证它或 `read` 都将初始化这些字节。
                        // 我们只是检查了字节数是否在缓冲区容量之内。
                        //
                        unsafe { buf.set_len(buf.len() + bytes_read) };
                        len += bytes_read as u64;
                        // 如果缓冲区仍然有足够的容量,则重新读取,如 BufWriter 本身那样。如果 reader 返回短读,则会发生这种情况
                        //
                        continue;
                    }
                    Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
                    Err(e) => return Err(e),
                }
            }

            writer.flush_buf()?;
        }
    }
}

fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
    reader: &mut R,
    writer: &mut W,
) -> Result<u64> {
    let mut buf = MaybeUninit::<[u8; DEFAULT_BUF_SIZE]>::uninit();
    // FIXME: #42788
    //
    //   - 这将创建 (mut) 对 _uninitialized_ 整数切片的引用,这是 **未定义的行为**
    //
    //   - 基于标准库对不稳定 rustc 内部的权限知识,只有标准库才能做到这一点。
    //
    //
    //
    unsafe {
        reader.initializer().initialize(buf.assume_init_mut());
    }

    let mut written = 0;
    loop {
        let len = match reader.read(unsafe { buf.assume_init_mut() }) {
            Ok(0) => return Ok(written),
            Ok(len) => len,
            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
            Err(e) => return Err(e),
        };
        writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?;
        written += len as u64;
    }
}