Java NIO - Hızlı Kılavuz
Java.nio paketi, java 1.4'te tanıtıldı. Java NIO'daki java G / Ç'nin aksine, G / Ç işlemleri için arabellek ve kanala yönelik veri akışı tanıtıldı ve sonuçta daha hızlı yürütme ve daha iyi performans sağlandı.
Ayrıca NIO API, eşzamansız veya engellemesiz bir şekilde IO olayları için birden fazla kanalı dinleme işlevselliğini tanıtan seçiciler sunar.
NIO API'lerinin temel soyutlamaları şu şekildedir:
Bayt ve Unicode karakterleri arasında çeviri yapan veri, karakter kümeleri ve bunlarla ilişkili kod çözücüler ve kodlayıcılar için kaplar olan tamponlar.
G / Ç işlemlerini gerçekleştirebilen varlıklara bağlantıları temsil eden çeşitli türlerdeki kanallar
Seçilebilir kanallarla birlikte çoklanmış, engellemesiz bir G / Ç tesisini tanımlayan seçiciler ve seçim tuşları.
Bu bölüm, makinenize Java'yı nasıl indirip kuracağınız konusunda size yol gösterir. Ortamı kurmak için lütfen aşağıdaki adımları izleyin.
Java SE, Java İndirme bağlantısından ücretsiz olarak edinilebilir . Böylece işletim sisteminize göre bir sürüm indirirsiniz.
Java'yı indirmek için talimatları izleyin ve .exeMakinenize Java yüklemek için. Java'yı makinenize yükledikten sonra, ortam değişkenlerini doğru yükleme dizinlerini gösterecek şekilde ayarlamanız gerekir -
Windows 2000 / XP için yolun ayarlanması
Java'yı c: \ Program Files \ java \ jdk dizinine kurduğunuzu varsayarsak -
"Bilgisayarım" ı sağ tıklayın ve "Özellikler" i seçin.
"Gelişmiş" sekmesinin altındaki "Ortam değişkenleri" düğmesini tıklayın.
Şimdi 'Path' değişkenini, Java yürütülebilir dosyasının yolunu da içerecek şekilde değiştirin. Örneğin, yol şu anda 'C: \ WINDOWS \ SYSTEM32' olarak ayarlanmışsa, yolunuzu 'C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin' olarak değiştirin.
Windows 95/98 / ME için yolu ayarlama
Java'yı c: \ Program Files \ java \ jdk dizinine kurduğunuzu varsayarsak -
'C: \ autoexec.bat' dosyasını düzenleyin ve sonuna şu satırı ekleyin:
'SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin'
Linux, UNIX, Solaris, FreeBSD için yolu ayarlama
PATH ortam değişkeni, java ikili dosyalarının kurulu olduğu yeri gösterecek şekilde ayarlanmalıdır. Bunu yapmakta sorun yaşıyorsanız, kabuk belgelerinize bakın.
Örneğin, kabuğunuz olarak bash kullanırsanız , aşağıdaki satırı '.bashrc: export PATH = / path / to / java: $ PATH'in sonuna eklersiniz.
Popüler Java Editörleri
Java programlarınızı yazmak için bir metin düzenleyiciye ihtiyacınız olacak. Piyasada daha da sofistike IDE mevcuttur. Ancak şimdilik aşağıdakilerden birini düşünebilirsiniz -
Notepad - Windows makinede, Not Defteri (Bu eğitim için önerilir), TextPad gibi herhangi bir basit metin düzenleyiciyi kullanabilirsiniz.
Netbeans - açık kaynak kodlu ve ücretsiz bir Java IDE'dir, buradan indirilebilir http://www.netbeans.org/index.html.
Eclipse - aynı zamanda eclipse açık kaynak topluluğu tarafından geliştirilmiş bir java IDE'dir ve buradan indirilebilir https://www.eclipse.org/.
Java NIO'nun geleneksel java IO API'nin geliştirilmesi için tanıtıldığını bildiğimiz gibi NIO'yu IO'dan daha verimli kılan ana iyileştirmeler, NIO'da kullanılan kanal veri akışı modeli ve geleneksel IO görevleri için işletim sisteminin kullanılmasıdır.
Java NIO ve Java IO arasındaki fark şu şekilde açıklanabilir -
Önceki gönderide belirtildiği gibi, G / Ç işlemleri için daha hızlı yürütme ve GÇ'ye kıyasla daha iyi performans sağlayan G / Ç işlemleri için NIO arabelleği ve kanala yönelik veri akışı.Ayrıca NIO, geleneksel G / Ç görevleri için işletim sistemini kullanarak yine daha verimli hale getiriyor.
NIO ve IO arasındaki farkın diğer bir yönü, bu IO'nun akış hattı veri akışını kullanması, yani her seferinde bir bayt daha kullanması ve veri nesnelerinin bayta dönüştürülmesine ve bunun tersine NIO, bayt parçaları olan veri bloklarıyla ilgilenmesidir.
Java'da IO akış nesneleri tek yönlüdür, NIO kanallarında ise çift yönlüdür, yani bir kanal hem veri okumak hem de yazmak için kullanılabilir.
IO'daki düzene veri akışı, verilerde ileri ve geri hareket etmeye izin vermez. Bir akıştan okunan verilerde ileri ve geri hareket etmek gerekirse, önce onu bir arabellekte önbelleğe almamız gerekir.NIO durumunda ise arabellek yönelimli kullanırız önbelleğe almaya gerek kalmadan verilere ileri ve geri erişim sağlar.
NIO API ayrıca çoklu iş parçacığını destekler, böylece veriler, IO işlemlerini gerçekleştirirken mevcut iş parçacığının engellenmemesi gibi eşzamansız olarak okunabilir ve yazılabilir. Bu da onu geleneksel java IO API'den daha verimli hale getirir.
Çoklu iş parçacığı kavramı tanıtıldı Selectors java NIO'da, eşzamansız veya engellemesiz bir şekilde IO olayları için birden fazla kanalı dinlemeye izin verir.
NIO'da çoklu iş parçacığı, engellemesiz hale getirir; bu, iş parçacığının yalnızca veri mevcut olduğunda okunması veya yazılması istendiği anlamına gelir, aksi takdirde iş parçacığı, diğer görevlerde ortalama süre boyunca kullanılabilir. onu Engelleme olarak yapan desteklenir.
NIO, yalnızca tek bir iş parçacığı kullanarak birden fazla kanalı yönetmeye izin verir, ancak bunun maliyeti, verilerin ayrıştırılması, java IO durumunda bir engelleme akışından veri okurken olduğundan biraz daha karmaşık olabilir. Bu nedenle, çok yüksek bant genişliğine sahip daha az bağlantı gerektiğinde bir seferde çok fazla veri göndererek, bu durumda java IO API en uygun seçenek olabilir.
Açıklama
Adından da anlaşılacağı gibi kanal, bir uçtan diğerine veri akışının bir aracı olarak kullanılır. Burada java NIO kanalı, tampon ve diğer uçtaki bir varlık arasında aynı davranır, diğer bir deyişle kanal, verileri arabelleğe okumak ve ayrıca arabellekten veri yazmak için kullanılır.
Geleneksel Java IO kanallarında kullanılan akışlardan farklı olarak iki yönlüdür, yani hem okuyabilir hem de yazabilir. Java NIO kanalı, hem engelleme hem de engellemesiz modda eşzamansız veri akışını destekler.
Kanal Uygulamaları
Java NIO kanalı öncelikle aşağıdaki sınıflarda uygulanır -
FileChannel- Dosyadan veri okumak için dosya kanalını kullanıyoruz. Dosya kanalının nesnesi, doğrudan dosya nesnesini oluşturamadığımızdan, dosya nesnesinde getChannel () yöntemi çağrılarak oluşturulabilir.
DatagramChannel - Datagram kanalı, verileri UDP (Kullanıcı Datagram Protokolü) aracılığıyla ağ üzerinden okuyabilir ve yazabilir. DataGramchannel nesnesi fabrika yöntemleri kullanılarak oluşturulabilir.
SocketChannel- SocketChannel kanalı, verileri TCP (İletim Kontrol Protokolü) aracılığıyla ağ üzerinden okuyabilir ve yazabilir. Ayrıca yeni nesneyi oluşturmak için fabrika yöntemlerini kullanır.
ServerSocketChannel- ServerSocketChannel, verileri bir web sunucusunda olduğu gibi TCP bağlantıları üzerinden okur ve yazar. Her gelen bağlantı için bir SocketChannel oluşturulur.
Misal
Aşağıdaki örnek, bir metin dosyasından C:/Test/temp.txt ve içeriği konsola yazdırır.
temp.txt
Hello World!
ChannelDemo.java
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ChannelDemo {
public static void main(String args[]) throws IOException {
RandomAccessFile file = new RandomAccessFile("C:/Test/temp.txt", "r");
FileChannel fileChannel = file.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
while (fileChannel.read(byteBuffer) > 0) {
// flip the buffer to prepare for get operation
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
System.out.print((char) byteBuffer.get());
}
}
file.close();
}
}
Çıktı
Hello World!
Açıklama
Daha önce belirtildiği gibi, Java NIO kanalının FileChannel uygulaması, dosyanın oluşturma, değiştirme, boyut vb. Dahil meta veri özelliklerine erişmek için tanıtıldı. Bu Dosya Kanalları ile birlikte çok iş parçacıklıdır, bu da Java NIO'yu Java IO'dan daha verimli hale getirir.
Genel olarak FileChannel, bir dosyadan veri okuyabileceğiniz ve bir dosyaya veri yazabileceğiniz bir dosyaya bağlı bir kanaldır diyebiliriz.FileChannel'in bir diğer önemli özelliği ise bloke edici olmayan moda ayarlanamamasıdır. ve her zaman engelleme modunda çalışır.
Dosya kanalı nesnesini doğrudan alamıyoruz, dosya kanalının nesnesi şu şekilde elde edilir -
getChannel() - herhangi bir FileInputStream, FileOutputStream veya RandomAccessFile üzerinde yöntem.
open() - varsayılan olarak kanalı açan Dosya kanalı yöntemi.
Dosya kanalının nesne türü, nesne oluşturmadan çağrılan sınıfın türüne bağlıdır, yani nesne, FileInputStream'in getchannel yöntemi çağrılarak oluşturulmuşsa, Dosya kanalı okuma için açılır ve ona yazmaya çalışılması durumunda NonWritableChannelException atar.
Misal
Aşağıdaki örnek, Java NIO FileChannel'dan nasıl veri okunacağını ve yazılacağını gösterir.
Aşağıdaki örnek, bir metin dosyasından C:/Test/temp.txt ve içeriği konsola yazdırır.
temp.txt
Hello World!
FileChannelDemo.java
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashSet;
import java.util.Set;
public class FileChannelDemo {
public static void main(String args[]) throws IOException {
//append the content to existing file
writeFileChannel(ByteBuffer.wrap("Welcome to TutorialsPoint".getBytes()));
//read the file
readFileChannel();
}
public static void readFileChannel() throws IOException {
RandomAccessFile randomAccessFile = new RandomAccessFile("C:/Test/temp.txt",
"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
Charset charset = Charset.forName("US-ASCII");
while (fileChannel.read(byteBuffer) > 0) {
byteBuffer.rewind();
System.out.print(charset.decode(byteBuffer));
byteBuffer.flip();
}
fileChannel.close();
randomAccessFile.close();
}
public static void writeFileChannel(ByteBuffer byteBuffer)throws IOException {
Set<StandardOpenOption> options = new HashSet<>();
options.add(StandardOpenOption.CREATE);
options.add(StandardOpenOption.APPEND);
Path path = Paths.get("C:/Test/temp.txt");
FileChannel fileChannel = FileChannel.open(path, options);
fileChannel.write(byteBuffer);
fileChannel.close();
}
}
Çıktı
Hello World! Welcome to TutorialsPoint
Java NIO Datagram, bağlantısız bir protokol üzerinden UDP paketleri gönderip alabilen bir kanal olarak kullanılır.Varsayılan datagram kanalı bloke olurken bloke olmayan modda kullanılabilir.Onu bloke etmemek için configureBlocking'i kullanabiliriz ( false) method.DataGram kanalı, olarak adlandırılan statik yöntemlerden biri çağrılarak açılabilir. open() IP adresini de parametre olarak alabilir, böylece çoklu yayın için kullanılabilir.
FileChannel gibi Datagram kanalı varsayılan olarak bağlanmaz, bağlanmasını sağlamak için açıkça connect () yöntemini çağırmamız gerekir, ancak gönderme ve alma yöntemlerinin bağlanırken kullanılması için datagram kanalının bağlanması gerekmez. okuma ve yazma yöntemlerini kullanmak için, çünkü bu yöntemler soket adreslerini kabul etmez veya döndürmez.
Datagram kanalının bağlantı durumunu, onu arayarak kontrol edebiliriz. isConnected() Bağlandıktan sonra, bir datagram kanalı bağlantısı kesilene veya kapatılana kadar bağlı kalır.Datagram kanalları iş parçacığı güvenlidir ve aynı anda çoklu iş parçacığı ve eşzamanlılığı destekler.
Datagram kanalının önemli yöntemleri
bind(SocketAddress local) - Bu yöntem, datagram kanalının soketini, bu yönteme parametre olarak sağlanan yerel adrese bağlamak için kullanılır.
connect(SocketAddress remote) - Bu yöntem soketi uzak adrese bağlamak için kullanılır.
disconnect() - Bu yöntem soketin uzak adresle olan bağlantısını kesmek için kullanılır.
getRemoteAddress() - Bu yöntem, kanal soketinin bağlı olduğu uzak konumun adresini döndürür.
isConnected() - Daha önce de belirtildiği gibi, bu yöntem verikatarının bağlantı durumunu, yani bağlı olup olmadığını döndürür.
open() and open(ProtocolFamily family) - Açık yöntem, tek adres için bir datagram kanalı açıkken, protokol ailesi olarak temsil edilen çoklu adresler için parametrize açık yöntem açık kanal kullanılır.
read(ByteBuffer dst) - Bu yöntem, verikatar kanalı aracılığıyla verilen arabellekten veri okumak için kullanılır.
receive(ByteBuffer dst) - Bu yöntem, bu kanal üzerinden datagram almak için kullanılır.
send(ByteBuffer src, SocketAddress target) - Bu yöntem, bu kanal üzerinden datagram göndermek için kullanılır.
Misal
Aşağıdaki örnek, Java NIO DataGramChannel'dan nasıl veri gönderileceğini gösterir.
Sunucu: DatagramChannelServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
public class DatagramChannelServer {
public static void main(String[] args) throws IOException {
DatagramChannel server = DatagramChannel.open();
InetSocketAddress iAdd = new InetSocketAddress("localhost", 8989);
server.bind(iAdd);
System.out.println("Server Started: " + iAdd);
ByteBuffer buffer = ByteBuffer.allocate(1024);
//receive buffer from client.
SocketAddress remoteAdd = server.receive(buffer);
//change mode of buffer
buffer.flip();
int limits = buffer.limit();
byte bytes[] = new byte[limits];
buffer.get(bytes, 0, limits);
String msg = new String(bytes);
System.out.println("Client at " + remoteAdd + " sent: " + msg);
server.send(buffer,remoteAdd);
server.close();
}
}
Çıktı
Server Started: localhost/127.0.0.1:8989
İstemci: DatagramChannelClient.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
public class DatagramChannelClient {
public static void main(String[] args) throws IOException {
DatagramChannel client = null;
client = DatagramChannel.open();
client.bind(null);
String msg = "Hello World!";
ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
InetSocketAddress serverAddress = new InetSocketAddress("localhost",
8989);
client.send(buffer, serverAddress);
buffer.clear();
client.receive(buffer);
buffer.flip();
client.close();
}
}
Çıktı
İstemciyi çalıştırmak, aşağıdaki çıktıyı sunucuda yazdıracaktır.
Server Started: localhost/127.0.0.1:8989
Client at /127.0.0.1:64857 sent: Hello World!
Java NIO soket kanalı seçilebilir tipte bir kanaldır, yani seçici kullanılarak çoğullanabilir, akış yönelimli veri akışı bağlantı soketleri için kullanılır. Soket kanalı statik çağrılarak oluşturulabilir. open() yöntem, önceden var olan herhangi bir soketin mevcut olmaması durumunda, soket kanalı açık yöntemi çağırarak oluşturulur ancak henüz bağlanmaz. soket kanalını bağlamak için connect() Burada bahsedilmesi gereken bir nokta, eğer kanal bağlı değilse ve herhangi bir G / Ç işlemi denenmeye çalışılırsa, bu kanal tarafından NotYetConnectedException atılır.Bu nedenle herhangi bir GÇ gerçekleştirmeden önce kanalın bağlı olduğundan emin olunmalıdır. Kanal bağlandığında, kapanana kadar bağlı kalır. Soket kanalının durumu, kanalın durumu çağrılarak belirlenebilir. isConnected yöntem.
Soket kanalının bağlantısı, kendi finishConnect() Bir bağlantı işleminin devam edip etmediği isConnectionPending yöntemi çağrılarak belirlenebilir.Varsayılan olarak yuva kanalı, engellemesiz bağlantıyı destekler.Ayrıca, Channel sınıfında belirtilen eşzamansız kapatma işlemine benzer şekilde eşzamansız kapatmayı destekler.
Soket kanalları birden çok eşzamanlı iş parçacığı tarafından kullanım için güvenlidir. Eşzamanlı okuma ve yazmayı desteklerler, ancak en fazla bir iş parçacığı okuyor olabilir ve herhangi bir zamanda en fazla bir ileti dizisi yazıyor olabilir. Connect ve finishConnect yöntemleri karşılıklı olarak birbiriyle senkronize edilir ve bu yöntemlerden birinin çağrılması devam ederken bir okuma veya yazma işlemini başlatma girişimi, bu çağrı tamamlanana kadar engellenir.
Soket kanalının önemli yöntemleri
bind(SocketAddress local) - Bu yöntem, soket kanalını bu yönteme parametre olarak sağlanan yerel adrese bağlamak için kullanılır.
connect(SocketAddress remote) - Bu yöntem soketi uzak adrese bağlamak için kullanılır.
finishConnect() - Bu yöntem, bir soket kanalı bağlama işlemini bitirmek için kullanılır.
getRemoteAddress() - Bu yöntem, kanal soketinin bağlı olduğu uzak konumun adresini döndürür.
isConnected() - Daha önce belirtildiği gibi, bu yöntem soket kanalının bağlantı durumunu, yani bağlı olup olmadığını döndürür.
open() and open((SocketAddress remote) - Açık yöntemi, belirtilen uzak adres için parametreleştirilmiş açık yöntem açık kanal açarken, belirtilmemiş bir adres için bir soket kanalı açıkken kullanılır ve aynı zamanda ona bağlanır. soket kanalı, uzaktan geçirme ve sonra o kanala geri dönme.
read(ByteBuffer dst) - Bu yöntem, verili tampondan soket kanalı üzerinden veri okumak için kullanılır.
isConnectionPending() - Bu yöntem, bu kanalda bir bağlantı işleminin devam edip etmediğini söyler.
Misal
Aşağıdaki örnek, Java NIO SocketChannel'dan nasıl veri gönderileceğini gösterir.
C: /Test/temp.txt
Hello World!
İstemci: SocketChannelClient.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
public class SocketChannelClient {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocket = null;
SocketChannel client = null;
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9000));
client = serverSocket.accept();
System.out.println("Connection Set: " + client.getRemoteAddress());
Path path = Paths.get("C:/Test/temp1.txt");
FileChannel fileChannel = FileChannel.open(path,
EnumSet.of(StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)
);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(client.read(buffer) > 0) {
buffer.flip();
fileChannel.write(buffer);
buffer.clear();
}
fileChannel.close();
System.out.println("File Received");
client.close();
}
}
Çıktı
İstemciyi çalıştırmak, sunucu başlayana kadar hiçbir şey yazdırmaz.
Sunucu: SocketChannelServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SocketChannelServer {
public static void main(String[] args) throws IOException {
SocketChannel server = SocketChannel.open();
SocketAddress socketAddr = new InetSocketAddress("localhost", 9000);
server.connect(socketAddr);
Path path = Paths.get("C:/Test/temp.txt");
FileChannel fileChannel = FileChannel.open(path);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(fileChannel.read(buffer) > 0) {
buffer.flip();
server.write(buffer);
buffer.clear();
}
fileChannel.close();
System.out.println("File Sent");
server.close();
}
}
Çıktı
Sunucuyu çalıştırmak aşağıdakileri yazdıracaktır.
Connection Set: /127.0.0.1:49558
File Received
Java NIO sunucu soket kanalı yine akış odaklı veri akışı bağlantı soketleri için kullanılan seçilebilir tip bir kanaldır.Sunucu Soket kanalı statik çağrılarak oluşturulabilir open() yöntemi, önceden var olan herhangi bir soket sağlamak için zaten mevcut değildir.Sunucu Soket kanalı, açık yöntemi çağırarak oluşturulur ancak henüz bağlı değildir. soket kanalına bağlanmak için bind() yöntem çağrılacak.
Burada belirtilmesi gereken bir nokta, eğer kanal bağlı değilse ve herhangi bir G / Ç işlemi denenmeye çalışılırsa, bu kanal tarafından NotYetBoundException atılır.Bu nedenle herhangi bir IO işlemi gerçekleştirmeden önce kanalın sınırlı olduğundan emin olunmalıdır.
Sunucu soket kanalı için gelen bağlantılar, ServerSocketChannel.accept () yöntemi çağrılarak dinlenir. Accept () yöntemi döndüğünde, gelen bağlantıyla bir SocketChannel döndürür. Bu nedenle, accept () yöntemi gelen bir bağlantı gelene kadar bloke eder. Kanal engellemesiz moddaysa, bekleyen bağlantı yoksa kabul yöntemi hemen null döndürür. Aksi takdirde, yeni bir bağlantı mevcut olana veya bir G / Ç hatası oluşana kadar süresiz olarak bloke olacaktır.
Yeni kanalın soketi başlangıçta bağlantısızdır; bağlantılar kabul edilmeden önce soketinin bağlama yöntemlerinden biri aracılığıyla belirli bir adrese bağlanması gerekir.Ayrıca yeni kanal, sistem genelinde varsayılan SelectorProvider nesnesinin openServerSocketChannel yöntemi çağrılarak oluşturulur.
Soket kanalı gibi sunucu soket kanalı da verileri okuyabilir read()İlk olarak tampon tahsis edilir. ServerSocketChannel'dan okunan veriler arabellekte depolanır. İkincisi, ServerSocketChannel.read () yöntemini çağırırız ve bir ServerSocketChannel'dan verileri bir arabelleğe okur. Read () yönteminin tamsayı değeri, arabelleğe kaç bayt yazıldığını döndürür
Benzer şekilde veriler sunucu soket kanalına kullanılarak yazılabilir. write() Bir parametre olarak arabelleği kullanan yöntem. Genellikle, Arabellek'te yazmak için başka bayt kalmayıncaya kadar write () yöntemini tekrarlamak gerektiği için while döngüsünde write yöntemini kullanır.
Soket kanalının önemli yöntemleri
bind(SocketAddress local) - Bu yöntem, soket kanalını bu yönteme parametre olarak sağlanan yerel adrese bağlamak için kullanılır.
accept() - Bu yöntem, bu kanalın soketine yapılan bir bağlantıyı kabul etmek için kullanılır.
connect(SocketAddress remote) - Bu yöntem soketi uzak adrese bağlamak için kullanılır.
finishConnect() - Bu yöntem, bir soket kanalı bağlama işlemini bitirmek için kullanılır.
getRemoteAddress() - Bu yöntem, kanal soketinin bağlı olduğu uzak konumun adresini döndürür.
isConnected() - Daha önce belirtildiği gibi, bu yöntem soket kanalının bağlantı durumunu, yani bağlı olup olmadığını döndürür.
open() - Açık yöntemi, belirtilmemiş bir adres için bir soket kanalını açmak için kullanılır.Bu kolaylık yöntemi, open () yöntemini çağırarak, ortaya çıkan sunucu soket kanalı üzerinde bağlantı yöntemini çağırarak, onu uzaktan geçirerek ve sonra o kanalı döndürerek çalışır.
read(ByteBuffer dst) - Bu yöntem, verili tampondan soket kanalı üzerinden veri okumak için kullanılır.
setOption(SocketOption<T> name, T value) - Bu yöntem, bir soket seçeneğinin değerini belirler.
socket() - Bu yöntem, bu kanalla ilişkilendirilmiş bir sunucu soketini alır.
validOps() - Bu yöntem, bu kanalın desteklenen işlemlerini tanımlayan bir işlem kümesi döndürür.Sunucu soket kanalları yalnızca yeni bağlantıların kabul edilmesini destekler, bu nedenle bu yöntem SelectionKey.OP_ACCEPT döndürür.
Misal
Aşağıdaki örnek, Java NIO ServerSocketChannel'dan nasıl veri gönderileceğini gösterir.
C: /Test/temp.txt
Hello World!
İstemci: SocketChannelClient.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
public class SocketChannelClient {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocket = null;
SocketChannel client = null;
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9000));
client = serverSocket.accept();
System.out.println("Connection Set: " + client.getRemoteAddress());
Path path = Paths.get("C:/Test/temp1.txt");
FileChannel fileChannel = FileChannel.open(path,
EnumSet.of(StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)
);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(client.read(buffer) > 0) {
buffer.flip();
fileChannel.write(buffer);
buffer.clear();
}
fileChannel.close();
System.out.println("File Received");
client.close();
}
}
Çıktı
İstemciyi çalıştırmak, sunucu başlayana kadar hiçbir şey yazdırmaz.
Sunucu: SocketChannelServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SocketChannelServer {
public static void main(String[] args) throws IOException {
SocketChannel server = SocketChannel.open();
SocketAddress socketAddr = new InetSocketAddress("localhost", 9000);
server.connect(socketAddr);
Path path = Paths.get("C:/Test/temp.txt");
FileChannel fileChannel = FileChannel.open(path);
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(fileChannel.read(buffer) > 0) {
buffer.flip();
server.write(buffer);
buffer.clear();
}
fileChannel.close();
System.out.println("File Sent");
server.close();
}
}
Çıktı
Sunucuyu çalıştırmak aşağıdakileri yazdıracaktır.
Connection Set: /127.0.0.1:49558
File Received
Java NIO'nun, Java'nın geleneksel IO API'sine kıyasla veri GÇ işlemleri için daha optimize edilmiş bir API olduğunu bildiğimiz için Java NIO'nun sağladığı bir başka ek destek, verileri birden çok arabellekten kanala okumak / yazmaktır. ve yazma desteği, verilerin yazılması durumunda birden çok arabellekten tek kanala veri toplanırken verilerin tek kanaldan birden çok arabelleğe dağıtıldığı Scatter ve Topla olarak adlandırılır.
Bu çoklu okuma ve yazma kanalından elde etmek için, Java NIO'nun aşağıdaki örnekte gösterildiği gibi verileri okumak ve yazmak için sağladığı ScatteringByteChannel ve GatheringByteChannel API vardır.
ScatteringByteChannel
Read from multiple channels - Bunun için tek bir kanaldan birden çok arabelleğe veri okumak için yaptık. Bunun için birden çok arabellek tahsis edilir ve bir arabellek türü dizisine eklenir.Sonra bu dizi ScatteringByteChannel read () yöntemine parametre olarak aktarılır ve daha sonra verileri yazar sıradaki kanal dizide arabellek oluşur. Bir arabellek dolduğunda, kanal bir sonraki arabelleği doldurmak için ilerler.
Aşağıdaki örnek, Java NIO'da veri dağılımının nasıl yapıldığını gösterir.
C: /Test/temp.txt
Hello World!
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ScatteringByteChannel;
public class ScatterExample {
private static String FILENAME = "C:/Test/temp.txt";
public static void main(String[] args) {
ByteBuffer bLen1 = ByteBuffer.allocate(1024);
ByteBuffer bLen2 = ByteBuffer.allocate(1024);
FileInputStream in;
try {
in = new FileInputStream(FILENAME);
ScatteringByteChannel scatter = in.getChannel();
scatter.read(new ByteBuffer[] {bLen1, bLen2});
bLen1.position(0);
bLen2.position(0);
int len1 = bLen1.asIntBuffer().get();
int len2 = bLen2.asIntBuffer().get();
System.out.println("Scattering : Len1 = " + len1);
System.out.println("Scattering : Len2 = " + len2);
}
catch (FileNotFoundException exObj) {
exObj.printStackTrace();
}
catch (IOException ioObj) {
ioObj.printStackTrace();
}
}
}
Çıktı
Scattering : Len1 = 1214606444
Scattering : Len2 = 0
Son olarak, Java NIO'daki dağılım / toplama yaklaşımının, doğru kullanıldığında optimize edilmiş ve çok görevli bir yaklaşım olarak sunulduğu sonucuna varılabilir. Okuduğunuz verileri birden çok kovaya ayırma veya bir araya getirme işini işletim sistemine devretmenize olanak tanır. Şüphesiz bu, arabellek kopyalarından kaçınarak zamandan tasarruf sağlar ve işletim sistemini daha verimli kullanır ve yazma ve hata ayıklama için gereken kod miktarını azaltır.
Java NIO'nun, Java'nın geleneksel IO API'sine kıyasla veri GÇ işlemleri için daha optimize edilmiş bir API olduğunu bildiğimiz için Java NIO'nun sağladığı bir başka ek destek, verileri birden çok arabellekten kanala okumak / yazmaktır. ve yazma desteği, verilerin yazılması durumunda birden çok arabellekten tek kanala veri toplanırken verilerin tek kanaldan birden çok arabelleğe dağıtıldığı Scatter ve Topla olarak adlandırılır.
Bu çoklu okuma ve yazma kanalından elde etmek için, Java NIO'nun aşağıdaki örnekte gösterildiği gibi verileri okumak ve yazmak için sağladığı ScatteringByteChannel ve GatheringByteChannel API vardır.
ToplamaByteChannel
write to multiple channels - Bunun için birden çok arabellekten tek bir kanala veri yazmak için yaptık.Bunun için yine birden çok arabellek atanır ve bir arabellek türü dizisine eklenir.Sonra bu dizi GatheringByteChannel write () yöntemine parametre olarak aktarılır ve daha sonra veri yazar Sıradaki çoklu tamponlardan dizide tamponlar oluşur. Burada hatırlanması gereken bir nokta sadece tamponların konumu ile sınırı arasındaki verilerin yazılmasıdır.
Aşağıdaki örnek, Java NIO'da veri toplamanın nasıl gerçekleştirildiğini gösterir.
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;
public class GatherExample {
private static String FILENAME = "C:/Test/temp.txt";
public static void main(String[] args) {
String stream1 = "Gather data stream first";
String stream2 = "Gather data stream second";
ByteBuffer bLen1 = ByteBuffer.allocate(1024);
ByteBuffer bLen2 = ByteBuffer.allocate(1024);
// Next two buffer hold the data we want to write
ByteBuffer bstream1 = ByteBuffer.wrap(stream1.getBytes());
ByteBuffer bstream2 = ByteBuffer.wrap(stream2.getBytes());
int len1 = stream1.length();
int len2 = stream2.length();
// Writing length(data) to the Buffer
bLen1.asIntBuffer().put(len1);
bLen2.asIntBuffer().put(len2);
System.out.println("Gathering : Len1 = " + len1);
System.out.println("Gathering : Len2 = " + len2);
// Write data to the file
try {
FileOutputStream out = new FileOutputStream(FILENAME);
GatheringByteChannel gather = out.getChannel();
gather.write(new ByteBuffer[] {bLen1, bLen2, bstream1, bstream2});
out.close();
gather.close();
}
catch (FileNotFoundException exObj) {
exObj.printStackTrace();
}
catch(IOException ioObj) {
ioObj.printStackTrace();
}
}
}
Çıktı
Gathering : Len1 = 24
Gathering : Len2 = 25
Son olarak, Java NIO'daki dağılım / toplama yaklaşımının, doğru kullanıldığında optimize edilmiş ve çok görevli bir yaklaşım olarak sunulduğu sonucuna varılabilir. Okuduğunuz verileri birden çok kovaya ayırma veya bir araya getirme işini işletim sistemine devretmenize olanak tanır. Şüphesiz bu, arabellek kopyalarından kaçınarak zamandan tasarruf sağlar ve işletim sistemini daha verimli kullanır ve yazma ve hata ayıklama için gereken kod miktarını azaltır.
Java NIO'daki tamponlar, kanala veri yazmak veya kanaldan verileri okumak için kullanılabilen sabit boyutlu bir veri parçası kabı olarak hareket eden basit bir nesne olarak ele alınabilir, böylece tamponlar kanallara uç noktalar olarak davranır.
Kanallardan veri okumak ve bunlardan veri yazmak için bellek bloğu ile uğraşmayı daha kolay hale getiren bir dizi yöntem sağlar.
Tamponlar, IO verilerinin eşzamansız ve eşzamanlı veri akışını desteklemeyen akışlar biçiminde ele alınması durumunda, NIO paketini klasik IO'ya kıyasla daha verimli ve daha hızlı hale getirir.Ayrıca IO, yığın veya bayt grubunda veri yürütülmesine izin vermez .
Java NIO tamponunu tanımlayan birincil parametreler şu şekilde tanımlanabilir:
Capacity - Tamponda saklanabilecek maksimum veri / bayt miktarı. Bir tamponun kapasitesi değiştirilemez. Tampon dolduğunda, üzerine yazmadan önce silinmelidir.
Limit - Limit, Tampon moduna göre anlamlıdır, yani Tampon Limitinin yazma modunda kapasiteye eşittir, bu da tamponda yazılabilecek maksimum verinin olduğu anlamına gelir. Tamponun okuma modunda Limit, ne kadar verinin olabileceğinin limiti anlamına gelir. Buffer'dan okuyun.
Position - Arabellekte imlecin geçerli konumunu gösterir. Başlangıçta arabellek oluşturulduğunda 0 olarak ayarlanır veya başka bir deyişle, get () ve put () ile otomatik olarak güncellenen okunacak veya yazılacak sonraki öğenin dizinidir. ) yöntemleri.
Mark - Bir arabellekte konumun yer imini işaretleyin. Mark () yöntemi çağrıldığında, geçerli konum kaydedilir ve reset () çağrıldığında işaretli konum geri yüklenir.
Tampon Tipi
Java NIO arabellekleri, arabelleğin ilgilendiği veri türlerine göre aşağıdaki değişkenlerde sınıflandırılabilir:
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
Tamponun önemli yöntemleri
Daha önce de belirtildiği gibi, Buffer, bellek bloğu ile başa çıkmayı daha kolay hale getiren bir dizi yöntem sağlayan bir bellek nesnesi görevi görür. Aşağıda, Buffer'ın önemli yöntemleri verilmiştir -
allocate(int capacity) - Bu yöntem, parametre olarak kapasiteye sahip yeni bir arabellek ayırmak için kullanılır.Allocate yöntemi, aktarılan kapasitenin negatif bir tamsayı olması durumunda IllegalArgumentException oluşturur.
read() and put() - kanal okuma yöntemi, verileri kanaldan tampona yazmak için kullanılırken, tamponda veri yazmak için kullanılan bir arabellek yöntemidir.
flip() - Çevirme yöntemi, Buffer modunu yazma modundan okuma moduna geçirir. Ayrıca konumu tekrar 0'a ayarlar ve limiti, pozisyonun yazma sırasında olduğu yere ayarlar.
write() and get() - Kanalın yazma yöntemi, arabellekten kanala veri yazmak için kullanılırken get, arabellekten verileri okumak için kullanılan bir arabellek yöntemidir.
rewind() - konumu yeniden sıfıra ayarladığı ve limit değerini değiştirmediği için yeniden okuma gerektiğinde geri sarma yöntemi kullanılır.
clear() and compact() - her iki yöntem de okuma modundan yazma moduna tampon yapmak için kullanılır.clear() yöntem konumu sıfıra ve limit kapasiteye eşittir, bu yöntemde arabellekteki veriler temizlenmez, sadece işaretçiler yeniden başlatılır.
Diğer yandan compact() yöntem, okunmamış veriler kaldığında kullanılır ve bu durumda hala tampon yazma modunu kullanırız, kompakt yöntem tüm okunmamış verileri tamponun başlangıcına kopyalar ve konumu son okunmamış öğenin hemen sonrasına ayarlar. limit özelliği hala kapasiteye ayarlayın.
mark() and reset() - İsmin önerdiği gibi, işaretleme yöntemi, bir tampondaki herhangi bir belirli konumu işaretlemek için kullanılırken, sıfırlama konumu işaretli konuma geri döndürür.
Misal
Aşağıdaki örnek, yukarıda tanımlanan yöntemlerin uygulanmasını gösterir.
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
public class BufferDemo {
public static void main (String [] args) {
//allocate a character type buffer.
CharBuffer buffer = CharBuffer.allocate(10);
String text = "bufferDemo";
System.out.println("Input text: " + text);
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
//put character in buffer.
buffer.put(c);
}
int buffPos = buffer.position();
System.out.println("Position after data is written into buffer: " + buffPos);
buffer.flip();
System.out.println("Reading buffer contents:");
while (buffer.hasRemaining()) {
System.out.println(buffer.get());
}
//set the position of buffer to 5.
buffer.position(5);
//sets this buffer's mark at its position
buffer.mark();
//try to change the position
buffer.position(6);
//calling reset method to restore to the position we marked.
//reset() raise InvalidMarkException if either the new position is less
//than the position marked or merk has not been setted.
buffer.reset();
System.out.println("Restored buffer position : " + buffer.position());
}
}
Çıktı
Input text: bufferDemo
Position after data is written into buffer: 10
Reading buffer contents:
b
u
f
f
e
r
D
e
m
o
Restored buffer position : 5
Java NIO'nun kanallardan ve arabellekten çoklu işlemi desteklediğini bildiğimiz gibi. Yani bir veya daha fazla NIO Kanalını incelemek ve hangi kanalların veri işlemine hazır olduğunu belirlemek, yani Java NIO okumak veya yazmak için Selector sağlar.
Selector ile hangi kanalın veri yazma ve okuma için hazır olduğunu bilmek için bir iş parçacığı oluşturabilir ve bu belirli kanalı yönetebiliriz.
Statik yöntemini çağırarak seçici örneğini alabiliriz open()Seçiciyi açtıktan sonra, onunla bir SelectionKey örneğini döndüren engelleyici olmayan bir mod kanalı kaydetmemiz gerekir.
SelectionKey, temelde kanal ile yapılabilen bir işlem koleksiyonudur veya seçim tuşu yardımıyla kanalın durumunu bilebildiğimizi söyleyebiliriz.
Seçim tuşuyla gösterilen ana işlemler veya kanal durumu şunlardır:
SelectionKey.OP_CONNECT - Sunucuya bağlanmaya hazır olan kanal.
SelectionKey.OP_ACCEPT - Gelen bağlantıları kabul etmeye hazır olan kanal.
SelectionKey.OP_READ - Veri okumaya hazır kanal.
SelectionKey.OP_WRITE - Veri yazmaya hazır kanal.
Kayıttan sonra elde edilen seçim anahtarı, aşağıda belirtildiği gibi bazı önemli yöntemlere sahiptir -
attach() - Bu yöntem, anahtarla bir nesne eklemek için kullanılır. Bir nesneyi bir kanala bağlamanın temel amacı, aynı kanalı tanımaktır.
attachment() - Bu yöntem, ekli nesneyi kanaldan tutmak için kullanılır.
channel() - Bu yöntem, belirli bir anahtarın oluşturulduğu kanalı elde etmek için kullanılır.
selector() - Bu yöntem, belirli bir anahtarın oluşturulduğu seçiciyi elde etmek için kullanılır.
isValid() - Bu yöntem, anahtarın geçerli olup olmadığı durumunu döndürür.
isReadable() - Bu yöntem, hava durumu anahtarının kanalının okunmaya hazır olup olmadığını belirtir.
isWritable() - Bu yöntem, hava durumu anahtarının kanalının yazmaya hazır olup olmadığını belirtir.
isAcceptable() - Bu yöntem, hava durumu anahtarının kanalının gelen bağlantıyı kabul etmeye hazır olup olmadığını belirtir.
isConnectable() - Bu yöntem, bu anahtarın kanalının soket bağlantı işlemini bitirip bitirmediğini test eder.
isAcceptable() - Bu yöntem, bu anahtarın kanalının yeni bir soket bağlantısını kabul etmeye hazır olup olmadığını test eder.
interestOps() - Bu yöntem, bu anahtarın faiz setini alır.
readyOps() - Bu yöntem, kanalın hazır olduğu işlemler kümesi olan hazır seti alır.
Statik yöntemini çağırarak selector'dan bir kanal seçebiliriz select()Seçici yöntemi şu şekilde aşırı yüklendi -
select() - Bu yöntem, kayıtlı olduğu olaylar için en az bir kanal hazır olana kadar mevcut iş parçacığını engeller.
select(long timeout) - Bu yöntem, iş parçacığını maksimum zaman aşımı milisaniye (parametre) için engellemesi dışında select () ile aynı işlevi görür.
selectNow() - Bu yöntem hiç engellemez, hazır olan kanallarla hemen geri döner.
Ayrıca seçme yöntemini çağıran engellenmiş bir iş parçacığı bırakmak için,wakeup() yöntem seçici örneğinden çağrılabilir ve ardından select () içinde bekleyen iş parçacığı hemen geri dönecektir.
Sonunda arayarak seçiciyi kapatabiliriz close() seçicinin kapatılmasıyla birlikte bu Seçiciye kaydedilen tüm SelectionKey örneklerini de geçersiz kılan yöntem.
Misal
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class SelectorDemo {
public static void main(String[] args) throws IOException {
String demo_text = "This is a demo String";
Selector selector = Selector.open();
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.bind(new InetSocketAddress("localhost", 5454));
serverSocket.configureBlocking(false);
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer buffer = ByteBuffer.allocate(256);
while (true) {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
int interestOps = key.interestOps();
System.out.println(interestOps);
if (key.isAcceptable()) {
SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
client.read(buffer);
if (new String(buffer.array()).trim().equals(demo_text)) {
client.close();
System.out.println("Not accepting client messages anymore");
}
buffer.flip();
client.write(buffer);
buffer.clear();
}
iter.remove();
}
}
}
}
Java'da NIO boru, iki iş parçacığı arasında veri yazmak ve okumak için kullanılan bir bileşendir. Boru, esas olarak veri yayılımından sorumlu iki kanaldan oluşur.
İki kurucu kanaldan biri, esas olarak veri yazmak için olan Sink kanalı olarak adlandırılır ve diğeri, temel amacı Sink kanalından veri okumak olan Kaynak kanaldır.
Verilerin Boruya yazıldıkları sırayla okunması gerektiğinden, veri yazma ve okuma sırasında veri senkronizasyonu düzenli tutulur.
Bunun Boru içinde tek yönlü bir veri akışı olduğu unutulmamalıdır, yani veriler sadece Sink kanalında yazılır ve sadece Kaynak kanalından okunabilir.
Java'da NIO boru, ikisi soyut olan temelde üç yöntemle soyut bir sınıf olarak tanımlanır.
Boru sınıfı yöntemleri
open() - Bu yöntem bir Boru örneğini almak için kullanılır veya borunun bu yöntemi çağırarak oluşturulduğunu söyleyebiliriz.
sink() - Bu yöntem, veri yazma yöntemini çağırarak veri yazmak için kullanılan Borunun havuz kanalını döndürür.
source() - Bu yöntem, okuma yöntemini çağırarak verileri okumak için kullanılan Borunun kaynak kanalını döndürür.
Misal
Aşağıdaki örnek, Java NIO borusunun uygulanmasını gösterir.
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
public class PipeDemo {
public static void main(String[] args) throws IOException {
//An instance of Pipe is created
Pipe pipe = Pipe.open();
// gets the pipe's sink channel
Pipe.SinkChannel skChannel = pipe.sink();
String testData = "Test Data to Check java NIO Channels Pipe.";
ByteBuffer buffer = ByteBuffer.allocate(512);
buffer.clear();
buffer.put(testData.getBytes());
buffer.flip();
//write data into sink channel.
while(buffer.hasRemaining()) {
skChannel.write(buffer);
}
//gets pipe's source channel
Pipe.SourceChannel sourceChannel = pipe.source();
buffer = ByteBuffer.allocate(512);
//write data into console
while(sourceChannel.read(buffer) > 0){
//limit is set to current position and position is set to zero
buffer.flip();
while(buffer.hasRemaining()){
char ch = (char) buffer.get();
System.out.print(ch);
}
//position is set to zero and limit is set to capacity to clear the buffer.
buffer.clear();
}
}
}
Çıktı
Test Data to Check java NIO Channels Pipe.
Bir metin dosyamız olduğunu varsayarsak c:/test.txt, aşağıdaki içeriğe sahip. Bu dosya, örnek programımız için bir girdi olarak kullanılacaktır.
Adından da anlaşılacağı gibi Yol, dosya veya bir dosya sistemindeki bir dizin gibi bir varlığın belirli konumudur, böylece kişi o belirli konumda arama yapabilir ve erişebilir.
Java açısından teknik olarak Path, Java sürüm 7 sırasında Java NIO dosya paketinde tanıtılan ve belirli dosya sisteminde konumun temsilidir.Yol arayüzü Java NIO paketinde olduğundan nitelikli adını java olarak alır. .nio.file.Path.
Genel olarak, bir varlığın yolu iki tipte olabilir; biri mutlak yol ve diğeri göreceli yoldur. Her iki yolun adı, mutlak yolun, kökten bulduğu varlığa olan konum adresi olduğunu, göreli yol ise konum adresidir. Bu, başka bir yolla ilişkilidir. Yol, tanımında Windows için "\" ve unix işletim sistemleri için "/" olarak sınırlayıcıları kullanır.
Path örneğini elde etmek için java.nio.file.Paths sınıfının statik yöntemini kullanabiliriz. get()Bu yöntem, bir yol dizesini veya bir yol dizesi olarak birleştirildiğinde bir dizi dizesini bir Path örneğine dönüştürür. Bu yöntem ayrıca, iletilen bağımsız değişkenler geçersiz karakterler içeriyorsa çalışma zamanı InvalidPathException oluşturur.
Yukarıda bahsedildiği gibi, mutlak yol, kök eleman ve dosyayı bulmak için gerekli olan tam dizin listesi geçilerek alınır. Göreceli yol, temel yol ile göreli yol birleştirilerek alınabilirken, her iki yolun da geri alınması aşağıdaki örnekte gösterilecektir.
Misal
package com.java.nio;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.file.FileSystem;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathDemo {
public static void main(String[] args) throws IOException {
Path relative = Paths.get("file2.txt");
System.out.println("Relative path: " + relative);
Path absolute = relative.toAbsolutePath();
System.out.println("Absolute path: " + absolute);
}
}
Şimdiye kadar yol arayüzünün ne olduğunu biliyoruz, neden buna ihtiyacımız var ve ona nasıl erişebiliriz.Şimdi Path arayüzünün bize sağladığı önemli yöntemlerin neler olduğunu bileceğiz.
Yol Arayüzünün önemli yöntemleri
getFileName() - Bu nesneyi oluşturan dosya sistemini döndürür.
getName() - Yol nesnesi olarak bu yolun bir ad öğesini döndürür.
getNameCount() - Yoldaki ad öğelerinin sayısını döndürür.
subpath() - Bu yolun ad öğelerinin bir alt dizisi olan göreli bir Yol döndürür.
getParent() - Üst yolu döndürür veya bu yolun bir üst öğesi yoksa null.
getRoot() - Bu yolun kök bileşenini bir Yol nesnesi olarak veya bu yolun bir kök bileşeni yoksa boş olarak döndürür.
toAbsolutePath() - Bu yolun mutlak yolunu temsil eden bir Path nesnesi döndürür.
toRealPath() - Mevcut bir dosyanın gerçek yolunu döndürür.
toFile() - Bu yolu temsil eden bir File nesnesi döndürür.
normalize() - Gereksiz ad öğelerinin kaldırıldığı bu yol olan bir yol döndürür.
compareTo(Path other) - İki soyut yolu sözlüksel olarak karşılaştırır.Bu yöntem, argüman bu yola eşitse sıfır, bu yol sözlükbilimsel olarak argümandan küçükse sıfırdan küçük bir değer veya bu yol sözlüksel olarak argümandan büyükse sıfırdan büyük bir değer döndürür .
endsWith(Path other) - Bu yolun verilen yolla bitip bitmediğini test eder. Verilen yolun N öğesi varsa ve kök bileşeni yoksa ve bu yolun N veya daha fazla öğesi varsa, her yolun son N öğesi varsa bu yol verilen yolla biter, kökten en uzak öğeden başlayarak eşittir.
endsWith(String other) - Bu yolun, belirtilen yol dizesini tam olarak uçlarWith (Yol) yöntemi tarafından belirtilen şekilde dönüştürülerek oluşturulan bir Yol ile bitip bitmediğini test eder.
Misal
Aşağıdaki örnek, yukarıda bahsedilen farklı Yol arayüzü yöntemlerini açıklamaktadır -
package com.java.nio;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.file.FileSystem;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathDemo {
public static void main(String[] args) throws IOException {
Path path = Paths.get("D:/workspace/ContentW/Saurav_CV.docx");
FileSystem fs = path.getFileSystem();
System.out.println(fs.toString());
System.out.println(path.isAbsolute());
System.out.println(path.getFileName());
System.out.println(path.toAbsolutePath().toString());
System.out.println(path.getRoot());
System.out.println(path.getParent());
System.out.println(path.getNameCount());
System.out.println(path.getName(0));
System.out.println(path.subpath(0, 2));
System.out.println(path.toString());
System.out.println(path.getNameCount());
Path realPath = path.toRealPath(LinkOption.NOFOLLOW_LINKS);
System.out.println(realPath.toString());
String originalPath = "d:\\data\\projects\\a-project\\..\\another-project";
Path path1 = Paths.get(originalPath);
Path path2 = path1.normalize();
System.out.println("path2 = " + path2);
}
}
Java NIO paketi, temelde çoğunlukla Path nesnesi üzerinde çalışan statik yöntemlerini kullanarak dosyaları ve dizinleri işlemek için kullanılan, Dosyalar olarak adlandırılan bir yardımcı program API'si sağlar.
Yol öğreticisinde belirtildiği gibi, Dosya paketindeki Java 7 sürümü sırasında Java NIO paketinde Yol arayüzünün tanıtıldığı, bu nedenle bu eğitim aynı Dosya paketi içindir.
Bu sınıf, yalnızca dosyalar, dizinler veya diğer dosya türleri üzerinde çalışan statik yöntemlerden oluşur. Çoğu durumda, burada tanımlanan yöntemler, dosya işlemlerini gerçekleştirmek için ilişkili dosya sistemi sağlayıcısına yetki verir.
Dosyalar sınıfında tanımlanmış ve Java belgelerinden de okunabilen birçok yöntem vardır. Bu eğitimde Java NIO Files sınıfının tüm yöntemleri arasında önemli yöntemlerden bazılarını ele almaya çalıştık.
Dosyalar sınıfının önemli yöntemleri.
Aşağıda Java NIO Files sınıfında tanımlanan önemli yöntemler yer almaktadır.
createFile(Path filePath, FileAttribute attrs) - Dosyalar sınıfı, belirtilen Yolu kullanarak dosya oluşturmak için bu yöntemi sağlar.
Misal
package com.java.nio;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CreateFile {
public static void main(String[] args) {
//initialize Path object
Path path = Paths.get("D:file.txt");
//create file
try {
Path createdFilePath = Files.createFile(path);
System.out.println("Created a file at : "+createdFilePath);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Çıktı
Created a file at : D:\data\file.txt
copy(InputStream in, Path target, CopyOption… options) - Bu yöntem, belirtilen giriş akışındaki tüm baytları belirtilen hedef dosyaya kopyalamak ve uzun değer olarak okunan veya yazılan bayt sayısını döndürmek için kullanılır. Bu parametre için aşağıdaki değerlere sahip LinkOption -
COPY_ATTRIBUTES - öznitelikleri yeni dosyaya kopyala, örneğin son değiştirilme zamanı özelliği.
REPLACE_EXISTING - varsa, mevcut bir dosyayı değiştirin.
NOFOLLOW_LINKS - Bir dosya sembolik bir bağlantıysa, bağlantının hedefi değil, bağın kendisi kopyalanır.
Misal
package com.java.nio;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
public class WriteFile {
public static void main(String[] args) {
Path sourceFile = Paths.get("D:file.txt");
Path targetFile = Paths.get("D:fileCopy.txt");
try {
Files.copy(sourceFile, targetFile,
StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException ex) {
System.err.format("I/O Error when copying file");
}
Path wiki_path = Paths.get("D:fileCopy.txt");
Charset charset = Charset.forName("ISO-8859-1");
try {
List<String> lines = Files.readAllLines(wiki_path, charset);
for (String line : lines) {
System.out.println(line);
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
Çıktı
To be or not to be?
createDirectories(Path dir, FileAttribute<?>...attrs) - Bu yöntem, var olmayan tüm ana dizinleri oluşturarak verilen yolu kullanarak dizinler oluşturmak için kullanılır.
delete(Path path) - Bu yöntem, dosyayı belirtilen yoldan silmek için kullanılır. Dosya belirtilen yolda yoksa veya dosya dizin ise ve boş olmayabilir ve silinemezse NoSuchFileException atar.
exists(Path path) - Bu yöntem, dosyanın belirtilen yolda olup olmadığını kontrol etmek için kullanılır ve dosya mevcutsa doğru veya yanlış döndürür.
readAllBytes(Path path) - Bu yöntem, dosyadan belirli bir yoldaki tüm baytları okumak ve dosyadan okunan baytları içeren bayt dizisini döndürmek için kullanılır.
Misal
package com.java.nio;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class ReadFile {
public static void main(String[] args) {
Path wiki_path = Paths.get("D:file.txt");
Charset charset = Charset.forName("ISO-8859-1");
try {
List<String> lines = Files.readAllLines(wiki_path, charset);
for (String line : lines) {
System.out.println(line);
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
Çıktı
Welcome to file.
size(Path path) - Bu yöntem, dosyanın boyutunu bayt cinsinden belirtilen yolda almak için kullanılır.
write(Path path, byte[] bytes, OpenOption… options) - Bu yöntem, baytları belirtilen yoldaki bir dosyaya yazmak için kullanılır.
Misal
package com.java.nio;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class WriteFile {
public static void main(String[] args) {
Path path = Paths.get("D:file.txt");
String question = "To be or not to be?";
Charset charset = Charset.forName("ISO-8859-1");
try {
Files.write(path, question.getBytes());
List<String> lines = Files.readAllLines(path, charset);
for (String line : lines) {
System.out.println(line);
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
Çıktı
To be or not to be?
Java NIO'nun eşzamanlılık ve çoklu iş parçacığını desteklediğini bildiğimiz için aynı anda farklı kanallarla aynı anda ilgilenmemize izin verir.Yani Java NIO paketinde bundan sorumlu olan API, NIO kanalları paketi altında tanımlanan AsynchronousFileChannel'dir. AsynchronousFileChannel için java.nio.channels.AsynchronousFileChannel.
AsynchronousFileChannel, NIO'nun FileChannel'ına benzer, ancak bu kanal, bir iş parçacığının bir eyleme girdiği ve istek tamamlanana kadar beklediği zaman uyumlu G / Ç işleminden farklı olarak dosya işlemlerinin eşzamansız olarak yürütülmesini sağlar. birden çok eşzamanlı iş parçacığı tarafından.
Eşzamansız olarak istek, iş parçacığı başka bir işi işlemeye devam ederken, iş parçacığı tarafından işletim sisteminin çekirdeğine iletilir. Gerektiği gibi I / O işi.
Eşzamanlılık elde etmek için bu kanal, birini geri dönüş olarak içeren iki yaklaşım sunar. java.util.concurrent.Future object ve diğeri de işleme türünde bir nesne geçirmektir. java.nio.channels.CompletionHandler.
Her iki yaklaşımı da örnekler yardımıyla tek tek anlayacağız.
Future Object - Bunda bir Gelecek Arayüzü örneği kanaldan döndürülür.Gelecek arayüzde var get() Diğer görevin daha fazla yürütülmesine karar verilebilmesi temelinde eşzamansız olarak işlenen işlemin durumunu döndüren yöntem.Ayrıca, görevin tamamlanıp tamamlanmadığını da arayarak kontrol edebiliriz. isDone yöntem.
Misal
Aşağıdaki örnek, Future nesnesinin nasıl kullanılacağını ve zaman uyumsuz olarak nasıl görev yapılacağını gösterir.
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class FutureObject {
public static void main(String[] args) throws Exception {
readFile();
}
private static void readFile() throws IOException, InterruptedException, ExecutionException {
String filePath = "D:fileCopy.txt";
printFileContents(filePath);
Path path = Paths.get(filePath);
AsynchronousFileChannel channel =AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(400);
Future<Integer> result = channel.read(buffer, 0); // position = 0
while (! result.isDone()) {
System.out.println("Task of reading file is in progress asynchronously.");
}
System.out.println("Reading done: " + result.isDone());
System.out.println("Bytes read from file: " + result.get());
buffer.flip();
System.out.print("Buffer contents: ");
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
System.out.println(" ");
buffer.clear();
channel.close();
}
private static void printFileContents(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String textRead = br.readLine();
System.out.println("File contents: ");
while (textRead != null) {
System.out.println(" " + textRead);
textRead = br.readLine();
}
fr.close();
br.close();
}
}
Çıktı
File contents:
To be or not to be?
Task of reading file is in progress asynchronously.
Task of reading file is in progress asynchronously.
Reading done: true
Bytes read from file: 19
Buffer contents: To be or not to be?
Completion Handler -
Bu yaklaşım oldukça basittir, çünkü burada CompletionHandler arayüzünü kullanıyoruz ve iki yöntemini geçersiz kılıyoruz. completed() G / Ç işlemi başarıyla tamamlandığında ve diğeri olduğunda çağrılan yöntem failed() G / Ç işlemleri başarısız olursa çağrılan yöntem.Burada, bir görev tamamlandıktan sonra eşzamansız bir G / Ç işleminin sonucunu tüketmek için bir işleyici oluşturulur, o zaman yalnızca işleyicinin çalıştırılan işlevleri vardır.
Misal
Aşağıdaki örnek, zaman uyumsuz olarak görev yapmak için CompletionHandler'ın nasıl kullanılacağını gösterir.
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class CompletionHandlerDemo {
public static void main (String [] args) throws Exception {
writeFile();
}
private static void writeFile() throws IOException {
String input = "Content to be written to the file.";
System.out.println("Input string: " + input);
byte [] byteArray = input.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
Path path = Paths.get("D:fileCopy.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
CompletionHandler handler = new CompletionHandler() {
@Override
public void completed(Object result, Object attachment) {
System.out.println(attachment + " completed and " + result + " bytes are written.");
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println(attachment + " failed with exception:");
exc.printStackTrace();
}
};
channel.write(buffer, 0, "Async Task", handler);
channel.close();
printFileContents(path.toString());
}
private static void printFileContents(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String textRead = br.readLine();
System.out.println("File contents: ");
while (textRead != null) {
System.out.println(" " + textRead);
textRead = br.readLine();
}
fr.close();
br.close();
}
}
Çıktı
Input string: Content to be written to the file.
Async Task completed and 34 bytes are written.
File contents:
Content to be written to the file.
Java'da her karakter için, JVM tarafından dahili olarak işlenen iyi tanımlanmış bir unicode kod birimi vardır. Yani Java NIO paketi, esas olarak karakter kümesinin ve UNICODE'un kodlanması ve kodunun çözülmesi için kullanılan Charset olarak adlandırılan soyut bir sınıfı tanımlar.
Standart karakter kümeleri
Java'da desteklenen Karakter Kümesi aşağıda verilmiştir.
US-ASCII - Yedi bit ASCII karakterleri.
ISO-8859-1 - ISO Latin alfabesi.
UTF-8 - Bu 8 bit UCS dönüştürme formatıdır.
UTF-16BE - Bu, büyük endian bayt sırasına sahip 16 bit UCS dönüştürme formatıdır.
UTF-16LE - Bu, küçük endian bayt sırasına sahip 16 bit UCS dönüşümüdür.
UTF-16 - 16 bit UCS dönüştürme formatı.
Charset sınıfının önemli yöntemleri
forName() - Bu yöntem, verilen karakter kümesi adı için bir karakter kümesi nesnesi oluşturur. Ad, kurallı veya bir takma ad olabilir.
displayName() - Bu yöntem, verilen karakter kümesinin kanonik adını döndürür.
canEncode() - Bu yöntem, verilen karakter kümesinin kodlamayı destekleyip desteklemediğini kontrol eder.
decode() - Bu yöntem, belirli bir karakter kümesinin dizesini Unicode karakter kümesinin karakter tamponuna dönüştürür.
encode() - Bu yöntem, verilen karakter kümesinin bayt arabelleğine unicode karakter kümesinin karakter tamponunu kodlar.
Misal
Aşağıdaki örnek, Charset sınıfının önemli yöntemlerini göstermektedir.
package com.java.nio;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
public class CharsetExample {
public static void main(String[] args) {
Charset charset = Charset.forName("US-ASCII");
System.out.println(charset.displayName());
System.out.println(charset.canEncode());
String str = "Demo text for conversion.";
//convert byte buffer in given charset to char buffer in unicode
ByteBuffer byteBuffer = ByteBuffer.wrap(str.getBytes());
CharBuffer charBuffer = charset.decode(byteBuffer);
//convert char buffer in unicode to byte buffer in given charset
ByteBuffer newByteBuffer = charset.encode(charBuffer);
while(newbb.hasRemaining()){
char ch = (char) newByteBuffer.get();
System.out.print(ch);
}
newByteBuffer.clear();
}
}
Çıktı
US-ASCII
Demo text for conversion.
Java NIO'nun eşzamanlılığı ve çoklu iş parçacığını desteklediğini bildiğimiz için, aynı anda birden fazla dosya üzerinde çalışan birden çok iş parçacığı ile başa çıkabilmesini sağlar, ancak bazı durumlarda dosyamızın herhangi bir iş parçacığı tarafından paylaşılmamasını ve erişilememesini isteriz.
Bu tür bir gereklilik için NIO, dosyanın veya bir kısmının paylaşılmaması veya erişilebilir olmaması için tüm dosya veya dosyanın bir parçası üzerinde kilit sağlamak için kullanılan ve FileLock olarak bilinen bir API sağlar.
Böyle bir kilidi sağlamak veya uygulamak için iki yöntem sağlayan FileChannel veya AsynchronousFileChannel kullanmalıyız. lock() ve tryLock()Bu amaç için Sağlanan kilit iki tipte olabilir -
Exclusive Lock - Özel bir kilit, diğer programların her iki türden de çakışan bir kilidi almasını engeller.
Shared Lock - Paylaşılan bir kilit, eşzamanlı olarak çalışan diğer programların örtüşen bir özel kilit almasını engeller, ancak bunların örtüşen paylaşılan kilitleri almasına izin verir.
Dosya üzerinden kilit elde etmek için kullanılan yöntemler -
lock() - Bu FileChannel veya AsynchronousFileChannel yöntemi, belirli bir kanalla ilişkilendirilmiş bir dosya üzerinde özel bir kilit elde eder. Bu yöntemin geri dönüş türü, elde edilen kilidi izlemek için ayrıca kullanılan FileLock'tur.
lock(long position, long size, boolean shared) - Bu yöntem yine aşırı yüklenmiş kilitleme yöntemidir ve bir dosyanın belirli bir bölümünü kilitlemek için kullanılır.
tryLock() - Bu yöntem, kilit alınamazsa ve bu kanalın dosyasında açıkça özel bir kilit almaya çalışırsa bir FileLock veya null döndürür.
tryLock(long position, long size, boolean shared) - Bu yöntem, bu kanalın belirli bir bölgesinde özel veya paylaşılan tipte bir kilit elde etmeye çalışır.
FileLock Sınıfının Yöntemleri
acquiredBy() - Bu yöntem, dosya kilidi alınmış olan kanalı döndürür.
position() - Bu yöntem, kilitli bölgenin ilk baytının dosyası içindeki konumu döndürür. Kilitli bir bölgenin asıl temel dosya içinde yer alması veya hatta örtüşmesi gerekmez, bu nedenle bu yöntemle döndürülen değer dosyanın geçerli boyutunu aşabilir.
size() - Bu yöntem, kilitli bölgenin boyutunu bayt cinsinden döndürür. Kilitli bir bölgenin asıl temel dosya içinde yer alması veya hatta örtüşmesi gerekmez, bu nedenle bu yöntemle döndürülen değer dosyanın geçerli boyutunu aşabilir.
isShared() - Bu yöntem, kilidin paylaşılıp paylaşılmadığını belirlemek için kullanılır.
overlaps(long position,long size) - Bu yöntem, bu kilidin verilen kilit aralığı ile örtüşüp örtüşmediğini söyler.
isValid() - Bu yöntem, elde edilen kilidin geçerli olup olmadığını söyler. Bir kilit nesnesi, serbest bırakılıncaya veya ilişkili dosya kanalı kapatılıncaya kadar (hangisi önce gelirse) geçerliliğini korur.
release()- Elde edilen kilidi serbest bırakır. Kilit nesnesi geçerliyse, bu yöntemin çağrılması kilidi serbest bırakır ve nesneyi geçersiz kılar. Bu kilit nesnesi geçersizse, bu yöntemi çağırmanın bir etkisi yoktur.
close()- Bu yöntem, release () yöntemini çağırır. Otomatik kaynak yönetimi blok yapısı ile birlikte kullanılabilmesi için sınıfa eklenmiştir.
Dosya kilidini göstermek için örnek.
Aşağıdaki örnek bir dosya üzerinde kilit oluştur ve ona içerik yaz
package com.java.nio;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class FileLockExample {
public static void main(String[] args) throws IOException {
String input = "Demo text to be written in locked mode.";
System.out.println("Input string to the test file is: " + input);
ByteBuffer buf = ByteBuffer.wrap(input.getBytes());
String fp = "D:file.txt";
Path pt = Paths.get(fp);
FileChannel channel = FileChannel.open(pt, StandardOpenOption.WRITE,StandardOpenOption.APPEND);
channel.position(channel.size() - 1); // position of a cursor at the end of file
FileLock lock = channel.lock();
System.out.println("The Lock is shared: " + lock.isShared());
channel.write(buf);
channel.close(); // Releases the Lock
System.out.println("Content Writing is complete. Therefore close the channel and release the lock.");
PrintFileCreated.print(fp);
}
}
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class PrintFileCreated {
public static void print(String path) throws IOException {
FileReader filereader = new FileReader(path);
BufferedReader bufferedreader = new BufferedReader(filereader);
String tr = bufferedreader.readLine();
System.out.println("The Content of testout.txt file is: ");
while (tr != null) {
System.out.println(" " + tr);
tr = bufferedreader.readLine();
}
filereader.close();
bufferedreader.close();
}
}
Çıktı
Input string to the test file is: Demo text to be written in locked mode.
The Lock is shared: false
Content Writing is complete. Therefore close the channel and release the lock.
The Content of testout.txt file is:
To be or not to be?Demo text to be written in locked mode.