Skip to content

Commit 86bad7a

Browse files
committed
Updated readme document
1 parent 575229c commit 86bad7a

File tree

2 files changed

+220
-1
lines changed

2 files changed

+220
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ yer aldığı repodur.
2323
- [Destekleyici Bölümler]()
2424
- [Birim Test](UnitTests.md)
2525
- [Hata Yönetimi](ErrorHandling.md)
26+
- [Temel I/O İşlemleri](./io.md)
2627
- [Yardımcı Kaynaklar](#yardımcı-kaynaklar)
2728
- [Örnek Uygulamalar](#örnek-uygulamalar)
2829

@@ -66,4 +67,5 @@ Rust dilinde **isimlendirme standartları _(Naming Conventions)_** da kod okunur
6667
- sysco; Basit bir terminal aracı. Lesson_01 dersinde kullanılan örneğin farklı bir sürümü.
6768
- sysco2; sysco programının daha iyileştirilmiş bir sürümü.
6869
- collector; sysinfo küfesini kullanarak cpu, memory metrikleri toplayan uygulama.
69-
- drone-lab; konu tekrarı, birim testler, temel dosya I/O operasyonları
70+
- drone-lab; Konu tekrarı, birim testler, lifetimes kullanımları.
71+
- fops; Temel I/O işlemleri.

io.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# I/O Temelleri
2+
3+
Bilgisayar programları çoğu zaman çevresel enstrümanlarla iletişim kurar. Konsol panelinden bilgi okumak, konsol
4+
ekranına bir şeyler yazdırmak, dosya hazırlamak, dosya içeriklerini doldurmak veya okumak, ağ ortamına paket yollarken
5+
girdi/çıktı kullanmak bu operasyonlar arasında sayılabilir. Rust genel olarak Input/Output işlemleri için std::io
6+
modülünü kullanır. I/O operasyonları hataya son derece açıktır. Örneğin var olmayan bir dosyaya ilave yapmaya çalışmak,
7+
yazma yetkisi olmayan bir dosyaya bilgi yazmak gibi birçok durum hataya sebebiyet verir. Dolayısıyla tüm I/O
8+
operasyonları Result<T,E> türünü döner. I/O işlemleri ayrıca blocking ve non-blocking olarak iki şekilde de ele alınır.
9+
Blocking türünde işlemler tamamlanana kadar bekeleme yapılır. Diğerinde ise işlemin tamamlanması beklenmez.
10+
11+
Aşağıda temel dosya girdi çıktı işlemlerine ait basit örnekler yer almaktadır. Örneklerde temel olarak Game isimli bir
12+
veri yapısı da kullanılmıştır. Bir Game nesnesinin string dönüşümünü kolaylaştırmak ve böylece I/O işlemlerinde
13+
kullanabilmek için Display davranışı ile donatılmıştır.
14+
15+
```rust
16+
use std::fmt::Display;
17+
18+
#[derive(Debug)]
19+
pub struct Game {
20+
pub title: String,
21+
pub year: u16,
22+
pub popularity: f32,
23+
}
24+
25+
impl Display for Game {
26+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
27+
write!(f, "{}|{}|{}", self.title, self.year, self.popularity)
28+
}
29+
}
30+
```
31+
32+
## Standart Giriş-Çıkış İşlemleri (stdin, stdout, stderr)
33+
34+
`stdin` _(Standard Input)_, `stdout` _(Standard Output)_ ve `stderr` _(Standard Error)_, UNIX tabanlı sistemlerden beri
35+
kullanılan giriş-çıkış standartlarıdır.
36+
37+
- **stdin**: Kullanıcıdan veya başka bir programdan veri almak için kullanılır.
38+
- **stdout**: Programın normal çıktısını kullanıcıya veya başka bir programa iletmek için kullanılır.
39+
- **stderr**: Hata mesajlarını ayrı tutmak için kullanılır.
40+
41+
Terminal operatörleri ve kullanımları genel olarak aşağıdaki gibi ifade edilebilir.
42+
43+
- **Pipe (`|`)**: Bir programın **stdout** çıktısını başka bir programın **stdin** girişine yönlendirir.
44+
```sh
45+
ls | grep ".rs"
46+
```
47+
48+
- **Redirect (`>`)**: **stdout** çıktısını dosyaya yönlendirir.
49+
```sh
50+
ls > files.txt
51+
```
52+
53+
- **Append (`>>`)**: **stdout** çıktısını mevcut dosyaya ekleyerek yönlendirir.
54+
```sh
55+
echo "Some thoughts about you" >> memories.txt
56+
```
57+
58+
### Terminalden Veri Almak
59+
60+
Aşağıdaki örnekte kullanıcının terminalden girdiği bilgiler okunur ve tekrar geri yazdırılır. Bazı sistemlerin **echo**
61+
komutları bu prensibe göre çalışır.
62+
63+
```rust
64+
use std::io;
65+
66+
fn write_to_file() -> io::Result<()> {
67+
let mut input = String::new();
68+
println!("Please enter some text:");
69+
70+
io::stdin().read_line(&mut input)?;
71+
println!("Your text is: {}", input.trim());
72+
73+
Ok(())
74+
}
75+
```
76+
77+
Farklı bir örnekle devam edelim. Yine stdin ile ekrandan iki değer okuyoruz ancak bu sefer birde parse operasyonu var.
78+
I/O operasyonlarında hatalar oluşması muhtemel. Örneğin girilen değer sayısal bir değere dönüştürülemeyebilir.
79+
Dönüştürme hatası parse metodunu takiben ele alınır. read_line operasyonunda da hatalar olması muhtemeldir. Farklı
80+
kullanımları göstermek amacıyla read_line için ? operatörü kullanılmıştır.
81+
82+
```rust
83+
fn sum() -> io::Result<i32> {
84+
let mut input1 = String::new();
85+
let mut input2 = String::new();
86+
87+
println!("Please enter the first number:");
88+
io::stdin().read_line(&mut input1)?;
89+
90+
println!("Second number:");
91+
io::stdin().read_line(&mut input2)?;
92+
93+
let x: i32 = input1.trim().parse().expect("Please enter a number!");
94+
let y: i32 = input2.trim().parse().expect("Please enter a number!");
95+
96+
Ok(x + y)
97+
}
98+
```
99+
100+
Sıradaki kod parçasında ise terminalden sürekli çıktı alınması örneklenmiştir. Döngü, terminalden bilgi yazıldıkça işler
101+
ve kullanıcı Ctrl+Z gibi bir kesme gönderene kadar da çalışmaya devam eder.
102+
103+
```rust
104+
use std::io::{self, BufRead};
105+
106+
fn read() -> io::Result<()> {
107+
let stdin = io::stdin();
108+
let reader = stdin.lock();
109+
110+
println!("Please enter some text (Ctrl+Z for exit):");
111+
for line in reader.lines() {
112+
let line = line?;
113+
println!("Input: {}", line);
114+
}
115+
116+
Ok(())
117+
}
118+
```
119+
120+
### Pipe'dan Gelen Veriyi Okumak
121+
122+
Pipe operatörü kullanılarak okunan bir verinin devam eden ifadeye stdin ile aktarılması sağlanabilir. Bunun için
123+
aşağıdaki terminal komutu kullanılabilir. Buna göre logs.dat içeriği cargo run komutu sonrası ilgili programa aktarılır.
124+
125+
```sh
126+
cat logs.dat | cargo run
127+
```
128+
129+
Program koduna göre stdin ile gelen içerik _(ki örnekte logs.dat dosyasını açan cat programıdır)_ bir reader değişleni
130+
üzerinden okunarak ekrana yazdırılır.
131+
132+
```rust
133+
use std::io::{self, BufRead};
134+
135+
fn read_from_pipe() -> io::Result<()> {
136+
let stdin = io::stdin();
137+
let reader = stdin.lock();
138+
139+
println!("Data is retrieving...");
140+
for line in reader.lines() {
141+
let line = line?;
142+
println!("Data: {}", line);
143+
}
144+
145+
Ok(())
146+
}
147+
```
148+
149+
### stdout'u Dosyaya Yönlendirme
150+
151+
Çıktıyı **stdout** üzerinden bir dosyaya yönlendirmek için aşağıdaki komut kullanılabilir.
152+
153+
```sh
154+
cargo run > logs.txt
155+
```
156+
157+
Bu sefer **cargo run** ile çalıştırılan program çıktıyı logs.txt dosyasın yönlendirir. Kod içerisinde kullanılan *
158+
*writeln!** makrosu, ilk parametre olarak gelen handle değişkenine doğru yazma işlemi gerçekleştirir. handle değişkeni
159+
stdout'u kullanır.
160+
161+
```rust
162+
use std::io::{self, Write};
163+
164+
fn write_log() -> io::Result<()> {
165+
let stdout = io::stdout();
166+
let mut handle = stdout.lock();
167+
168+
writeln!(handle, "This will be written to a file.")?;
169+
170+
Ok(())
171+
}
172+
```
173+
174+
### Pipe ve Redirect Kullanımı (stdin → stdout)
175+
176+
Pipe sonrasında redirect operatörü kullanılarak da bir süreç tasarlanabilir. Aşağıdaki terminal komutuna göre logs.dat
177+
dosya içeriği cat programı ile rust koduna gönderilir ve rust kodu da bunu output_logs.txt dosyasına filtreleyerek
178+
aktarabilir.
179+
180+
```sh
181+
cat logs.dat | cargo run > output_logs.txt
182+
```
183+
184+
Örnekte, stdin üzerinden gelen içerik reader isimli handler ile okunur ve stdout kullanan writeln! makrosu üzerinden
185+
çıktı olarak dışarıya verilir.
186+
187+
```rust
188+
use std::io::{self, BufRead, Write};
189+
190+
fn double_usage() -> io::Result<()> {
191+
let stdin = io::stdin();
192+
let stdout = io::stdout();
193+
194+
let reader = stdin.lock();
195+
let mut writer = stdout.lock();
196+
197+
for line in reader.lines() {
198+
let line = line?;
199+
writeln!(writer, "Data received {}", line)?;
200+
}
201+
Ok(())
202+
}
203+
```
204+
205+
Buraya kadar ele aldığımız stdin ve stdout kullanımlarına ilişkin şunları söyleyebiliriz.
206+
207+
- **stdin** kullanarak terminalden veya başka programlardan veri okunabilir.
208+
- **stdout** kullanarak terminal ekranına veya başka programlara veri yazdırılabilir.
209+
- **stderr** hata ve uyarı mesajlarını standart çıktıdan ayırmak için kullanılır.
210+
- **Unix/Linux** ortamlarında `|`, `>` ve `>>` operatörleri standart giriş-çıkış işlemlerinde, verilerin akışını
211+
yönetmek için kullanılır.
212+
213+
## Temel Dosya I/O İşlemleri
214+
215+
Aşağıdaki örneklerde dosya okuma ve yazma işlemleri farklı şekillerde ele alınmaktadır.
216+
217+
_NotYetImplemented();_

0 commit comments

Comments
 (0)