@@ -348,6 +348,30 @@ impl File {
348348            inner :  self . inner . duplicate ( ) ?
349349        } ) 
350350    } 
351+ 
352+     /// Reads a number of bytes starting from a given offset. 
353+ /// 
354+ /// The offset is relative to the file start and thus independent from the 
355+ /// current cursor. 
356+ /// 
357+ /// Note that similar to `File::read`, it is not an error to return a short 
358+ /// read. 
359+ #[ unstable( feature = "file_offset" ,  issue = "35918" ) ]  
360+     pub  fn  read_at ( & self ,  buf :  & mut  [ u8 ] ,  offset :  u64 )  -> io:: Result < usize >  { 
361+         self . inner . read_at ( buf,  offset) 
362+     } 
363+ 
364+     /// Writes a number of bytes starting from a given offset. 
365+ /// 
366+ /// The offset is relative to the file start and thus independent from the 
367+ /// current cursor. 
368+ /// 
369+ /// Note that similar to `File::write`, it is not an error to return a 
370+ /// short write. 
371+ #[ unstable( feature = "file_offset" ,  issue = "35918" ) ]  
372+     pub  fn  write_at ( & self ,  buf :  & [ u8 ] ,  offset :  u64 )  -> io:: Result < usize >  { 
373+         self . inner . write_at ( buf,  offset) 
374+     } 
351375} 
352376
353377impl  AsInner < fs_imp:: File >  for  File  { 
@@ -1893,6 +1917,53 @@ mod tests {
18931917        check ! ( fs:: remove_file( filename) ) ; 
18941918    } 
18951919
1920+     #[ test]  
1921+     fn  file_test_io_read_write_at ( )  { 
1922+         let  tmpdir = tmpdir ( ) ; 
1923+         let  filename = tmpdir. join ( "file_rt_io_file_test_read_write_at.txt" ) ; 
1924+         let  mut  buf = [ 0 ;  256 ] ; 
1925+         let  write1 = "asdf" ; 
1926+         let  write2 = "qwer-" ; 
1927+         let  write3 = "-zxcv" ; 
1928+         let  content = "qwer-asdf-zxcv" ; 
1929+         { 
1930+             let  oo = OpenOptions :: new ( ) . create_new ( true ) . write ( true ) . read ( true ) . clone ( ) ; 
1931+             let  mut  rw = check ! ( oo. open( & filename) ) ; 
1932+             assert_eq ! ( check!( rw. write_at( write1. as_bytes( ) ,  5 ) ) ,  write1. len( ) ) ; 
1933+             assert_eq ! ( check!( rw. seek( SeekFrom :: Current ( 0 ) ) ) ,  0 ) ; 
1934+             assert_eq ! ( check!( rw. read_at( & mut  buf,  5 ) ) ,  write1. len( ) ) ; 
1935+             assert_eq ! ( str :: from_utf8( & buf[ ..write1. len( ) ] ) ,  Ok ( write1) ) ; 
1936+             assert_eq ! ( check!( rw. seek( SeekFrom :: Current ( 0 ) ) ) ,  0 ) ; 
1937+             assert_eq ! ( check!( rw. write( write2. as_bytes( ) ) ) ,  write2. len( ) ) ; 
1938+             assert_eq ! ( check!( rw. seek( SeekFrom :: Current ( 0 ) ) ) ,  5 ) ; 
1939+             assert_eq ! ( check!( rw. read( & mut  buf) ) ,  write1. len( ) ) ; 
1940+             assert_eq ! ( str :: from_utf8( & buf[ ..write1. len( ) ] ) ,  Ok ( write1) ) ; 
1941+             assert_eq ! ( check!( rw. seek( SeekFrom :: Current ( 0 ) ) ) ,  9 ) ; 
1942+             assert_eq ! ( check!( rw. read_at( & mut  buf[ ..write2. len( ) ] ,  0 ) ) ,  write2. len( ) ) ; 
1943+             assert_eq ! ( str :: from_utf8( & buf[ ..write2. len( ) ] ) ,  Ok ( write2) ) ; 
1944+             assert_eq ! ( check!( rw. seek( SeekFrom :: Current ( 0 ) ) ) ,  9 ) ; 
1945+             assert_eq ! ( check!( rw. write_at( write3. as_bytes( ) ,  9 ) ) ,  write3. len( ) ) ; 
1946+             assert_eq ! ( check!( rw. seek( SeekFrom :: Current ( 0 ) ) ) ,  9 ) ; 
1947+         } 
1948+         { 
1949+             let  mut  read = check ! ( File :: open( & filename) ) ; 
1950+             assert_eq ! ( check!( read. read_at( & mut  buf,  0 ) ) ,  content. len( ) ) ; 
1951+             assert_eq ! ( str :: from_utf8( & buf[ ..content. len( ) ] ) ,  Ok ( content) ) ; 
1952+             assert_eq ! ( check!( read. seek( SeekFrom :: Current ( 0 ) ) ) ,  0 ) ; 
1953+             assert_eq ! ( check!( read. seek( SeekFrom :: End ( -5 ) ) ) ,  9 ) ; 
1954+             assert_eq ! ( check!( read. read_at( & mut  buf,  0 ) ) ,  content. len( ) ) ; 
1955+             assert_eq ! ( str :: from_utf8( & buf[ ..content. len( ) ] ) ,  Ok ( content) ) ; 
1956+             assert_eq ! ( check!( read. seek( SeekFrom :: Current ( 0 ) ) ) ,  9 ) ; 
1957+             assert_eq ! ( check!( read. read( & mut  buf) ) ,  write3. len( ) ) ; 
1958+             assert_eq ! ( str :: from_utf8( & buf[ ..write3. len( ) ] ) ,  Ok ( write3) ) ; 
1959+             assert_eq ! ( check!( read. seek( SeekFrom :: Current ( 0 ) ) ) ,  14 ) ; 
1960+             assert_eq ! ( check!( read. read_at( & mut  buf,  0 ) ) ,  content. len( ) ) ; 
1961+             assert_eq ! ( str :: from_utf8( & buf[ ..content. len( ) ] ) ,  Ok ( content) ) ; 
1962+             assert_eq ! ( check!( read. seek( SeekFrom :: Current ( 0 ) ) ) ,  14 ) ; 
1963+         } 
1964+         check ! ( fs:: remove_file( & filename) ) ; 
1965+     } 
1966+ 
18961967    #[ test]  
18971968    fn  file_test_stat_is_correct_on_is_file ( )  { 
18981969        let  tmpdir = tmpdir ( ) ; 
0 commit comments