### Java'da I/O ve NIO Kullanımı
Java'da I/O (Input/Output) işlemleri, veri okuma ve yazma işlemlerini gerçekleştirmek için kullanılır. Java'da I/O işlemleri genellikle iki ana paket üzerinden gerçekleştirilir: `java.io` ve `java.nio`. Aşağıda bu paketlerin kullanımı ve socket programlama ile ilgili detaylar bulunmaktadır.
---
### IO Sınıfları Kullanımı
Java'nın `java.io` paketi, dosya ve veri akışları ile çalışmak için gerekli sınıfları sağlar. Bu paket, iki ana kategoriye ayrılır: byte tabanlı ve karakter tabanlı I/O.
#### Byte Tabanlı I/O
1. **InputStream ve OutputStream Sınıfları**
- **`InputStream`**: Byte verilerini okur.
- **`OutputStream`**: Byte verilerini yazar.
##### `FileInputStream` ve `FileOutputStream` Kullanımı
```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteIOExample {
public static void main(String[] args) {
String inputFile = "input.txt";
String outputFile = "output.txt";
try (FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile)) {
int byteData;
while ((byteData = fis.read()) != -1) {
fos.write(byteData);
}
System.out.println("Veri başarıyla kopyalandı!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
- **`FileInputStream`**: Dosyadan byte okur.
- **`FileOutputStream`**: Dosyaya byte yazar.
- **`read()`**: Bir byte okur.
- **`write(byte)`**: Bir byte yazar.
#### Karakter Tabanlı I/O
1. **Reader ve Writer Sınıfları**
- **`Reader`**: Karakter verilerini okur.
- **`Writer`**: Karakter verilerini yazar.
##### `FileReader` ve `FileWriter` Kullanımı
```java
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharIOExample {
public static void main(String[] args) {
String inputFile = "input.txt";
String outputFile = "output.txt";
try (FileReader fr = new FileReader(inputFile);
FileWriter fw = new FileWriter(outputFile)) {
int charData;
while ((charData = fr.read()) != -1) {
fw.write(charData);
}
System.out.println("Karakter verisi başarıyla kopyalandı!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
- **`FileReader`**: Dosyadan karakter okur.
- **`FileWriter`**: Dosyaya karakter yazar.
- **`read()`**: Bir karakter okur.
- **`write(int)`**: Bir karakter yazar.
---
### NIO (New I/O) ve Non-Blocking I/O
Java NIO (New I/O), daha etkili ve performanslı I/O işlemleri için geliştirilmiş bir API'dir. NIO, daha düşük seviye I/O işlemlerini destekler ve non-blocking (engellemeyen) I/O işlemleri sağlar.
#### NIO Temel Sınıfları
1. **`FileChannel`**: Dosyalarla veri okuma ve yazma işlemleri sağlar.
2. **`ByteBuffer`**: Byte verilerini tamponda tutar.
3. **`Selectors`**: Non-blocking I/O işlemleri için seçici mekanizma sağlar.
4. **`SocketChannel`** ve **`ServerSocketChannel`**: Socket bağlantıları ile veri iletimi sağlar.
##### `FileChannel` Kullanımı
```java
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.IOException;
public class FileChannelExample {
public static void main(String[] args) {
String inputFile = "input.txt";
String outputFile = "output.txt";
try (RandomAccessFile input = new RandomAccessFile(inputFile, "r");
RandomAccessFile output = new RandomAccessFile(outputFile, "rw")) {
FileChannel inChannel = input.getChannel();
FileChannel outChannel = output.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead;
while ((bytesRead = inChannel.read(buffer)) != -1) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
System.out.println("Veri başarıyla kopyalandı!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
- **`FileChannel`**: Dosya ile veri okuma/yazma sağlar.
- **`ByteBuffer`**: Verileri tamponda tutar.
- **`flip()`**: Buffer'ı okuma moduna alır.
- **`clear()`**: Buffer'ı temizler.
#### Non-Blocking I/O (Non-Blocking I/O ve Selectors)
Non-blocking I/O işlemleri, thread'lerin I/O işlemleri sırasında bloklanmadan diğer işlemleri yapmasına olanak tanır.
##### `Selector` Kullanımı
```java
import java.io.IOException;
import java.nio.channels.*;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
public class NonBlockingExample {
public static void main(String[] args) {
try (Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
SocketChannel clientChannel = serverSocketChannel.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(256);
clientChannel.read(buffer);
buffer.flip();
System.out.println("Received: " + new String(buffer.array()).trim());
}
}
selector.selectedKeys().clear();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
- **`Selector`**: Non-blocking I/O işlemleri için seçici.
- **`SelectionKey`**: Bir kanalın belirli I/O olaylarını temsil eder.
- **`select()`**: İlgili kanallarda olay olup olmadığını kontrol eder.
- **`register()`**: Kanalı seçiciye kaydeder.
---
### Socket Programlama
Java'da socket programlama, ağ üzerindeki iki uygulama arasında veri alışverişi sağlar. `java.net` paketi, socket programlama için gerekli sınıfları içerir.
#### Basit Bir TCP Socket Server ve Client
##### Server
```java
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(12345)) {
System.out.println("Server başlatıldı, bağlantı bekleniyor...");
Socket clientSocket = serverSocket.accept();
System.out.println("Client bağlı!");
try (PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {
out.println("Merhaba, client!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
##### Client
```java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 12345);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String message = in.readLine();
System.out.println("Server'dan gelen mesaj: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
- **`ServerSocket`**: Server tarafında socket oluşturur ve bağlantı kabul eder.
- **`Socket`**: Client tarafında socket oluşturur ve server ile bağlantı kurar.
- **`PrintWriter`**: Socket üzerinden veri gönderir.
- **`BufferedReader`**: Socket üzerinden veri okur.
---
### Özet
Bu ders notları, Java'da I/O ve NIO kullanımı, senkronizasyon, ve socket programlama konularını kapsamaktadır. `java.io` paketi, temel I/O işlemlerini sağlar, `java.nio` paketi ise daha performanslı ve non-blocking I/O işlemleri sunar. Socket programlama, ağ üzerinden veri alışverişi için kullanılır. Bu bilgilerle, Java'da çeşitli I/O ve ağ işlemlerini gerçekleştirebilirsiniz.