14.
Gestion des fichiers (nio2)
Dans la version 4 de Java un nouveau
modèle a été
introduit (nio - new input/output). Ce modèle a
été totalement refait dans la version 7 (nio2). Les
classes de ces modèles sont
placées dans
le package java.nio. Le
nouveau modèle est basé sur les tampons (buffers) et
canaux (channels).
Les deux modèles (les flux et nio2) ont
leurs atouts et défauts dans des
situations différentes.
14.1 La
classe Path
On peut créer un objet de la
classe en utilisant la méthode get() de la classe utilitaire Paths avec
paramètre – le chemin absolu
ou relatif.
Path path =
Paths.get("Test.txt");
//
dans le répertoire corrant
Path path =
Paths.get("D:\\data\\Test.txt");
//
système de fichiers Windows
Path path =
Paths.get("/home/data/Test.txt");
//
système de fichiers Unix
14.1.2 Opérations syntactiques
L'exemple suivant montre quelques opérations syntactiques. Elles
sont assez intuitives.
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathInf {
public static void
main(String arg[]){
Path absPath = Paths.get("D:\\iv\\dt\\sys\\Test.txt"); //windows
файлова система
System.out.format("absolute Path %n");
System.out.format("toString: %s%n",absPath.toString());
System.out.format("getFileName: %s%n", absPath.getFileName());
System.out.format("getNameCount: %d%n",absPath.getNameCount());
for(int i=0; ;i++){
try{
System.out.format("getName(%d):
%s%n", i,absPath.getName(i));
}catch(IllegalArgumentException ex){
System.out.format("no more names
%n");
break;
}
}
System.out.format("subpath(0,2): %s%n",absPath.subpath(0,2));
System.out.format("getParent: %s%n",absPath.getParent());
System.out.format("getRoot: %s%n",absPath.getRoot());
Path relPath = Paths.get("dt\\sys\\Test.txt");
System.out.format("%n relative Path %n");
System.out.format("toString: %s%n",relPath.toString());
System.out.format("getFileName: %s%n", relPath.getFileName());
System.out.format("getName(0): %s%n", relPath.getName(0));
System.out.format("getNameCount: %d%n",relPath.getNameCount());
for (Path name : relPath) { System.out.format("Name:
%s%n",name); }
System.out.format("subpath(0,2): %s%n",relPath.subpath(0,2));
System.out.format("getParent: %s%n",relPath.getParent());
System.out.format("getRoot: %s%n",relPath.getRoot());
}
}
14.2
Les tampons
Le tampon représente un tableau. Le plus souvent
est utilisé un tableau des octets – ByteBuffer,
mais on peut utiliser des classes dérivées
de la classe Buffer pour la
plupart des types
primitifs – CharBuffer, IntBuffer,
ShortBuffer, LongBuffer, FloatBuffer
et DoubleBuffer
14.2.1 Paramètres
• position
– la place d’où on peut lire ou dans laquelle
on peut lire information. On peut la consulter et modifier par
public final int position( )
public final Buffer position(int newPosition)
• capacité – le
nombre maximal d'éléments dans le tampon, consulté
par
public final int capacity( )
• limite – la
dernière position où on peut lire et écrire les
données, consultées et modifiées par
public final int limit( )
public final Buffer limit(int newLimit)
• Mark – Pour
mémoriser une position. Avec la méthode mark() on la met
à la position courante. Avec reset() on fait la position
courante égale au mark.
public final Buffer mark( )
public final Buffer reset( )
14.2.2 Création
Les tampons vides :
ByteBuffer buffer1 = ByteBuffer.allocate(100);
IntBuffer buffer2 =
IntBuffer.allocate(100);
On peut obtenir une référence de type tableau sur le
tampon par
byte[] data1 = buffer1.array();
Dans les opérations de sortie on fait un tampon comme enveloppe
sur l'information à écrire.
int[] data = {1, 3, 2, 4, 23, 53, -9, 67};
IntBuffer buffer = IntBuffer.wrap(data);
14.2.3 L'accès aux données
public abstract byte get()
public ByteBuffer get(byte[] dst)
public ByteBuffer get(byte[] dst, int
offset, int length)
public abstract byte get(int index)
public abstract ByteBuffer put(byte b)
public final ByteBuffer put(byte[]
src)
public ByteBuffer put(byte[] src, int
offset, int length)
public ByteBuffer put(ByteBuffer src)
public abstract ByteBuffer put(int
index, byte b)
public abstract char getChar()
public abstract char getChar(int
index)
public abstract double getDouble()
public abstract double getDouble(int
index)
public abstract float getFloat()
public abstract float getFloat(int
index)
public abstract int getInt()
public abstract int getInt(int index)
public abstract long getLong()
public abstract long getLong(int
index)
public abstract short getShort()
public abstract short getShort(int
index)
public abstract ByteBuffer
putChar(char value)
public abstract ByteBuffer
putChar(int index, char value)
public abstract ByteBuffer
putDouble(double value)
public abstract ByteBuffer
putDouble(int index, double value)
public abstract ByteBuffer
putFloat(float value)
public abstract ByteBuffer
putFloat(int index, float value)
public abstract ByteBuffer putInt(int
value)
public abstract ByteBuffer putInt(int
index, int value)
public abstract ByteBuffer
putLong(int index, long value)
public abstract ByteBuffer
putLong(long value)
public abstract ByteBuffer
putShort(int index, short value)
public abstract ByteBuffer
putShort(short value)
14.3
Les canaux
14.3.1 Les interfaces
14.3.2 Exemple
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class CopyNio {
public static void
main(String[] args) throws IOException {
FileInputStream inFile = new FileInputStream(args[0]);
FileOutputStream outFile = new FileOutputStream(args[1]);
FileChannel inChannel = inFile.getChannel( );
FileChannel outChannel = outFile.getChannel( );
ByteBuffer buffer = ByteBuffer.allocate(4096);
byte data[] = buffer.array();
for (; inChannel.read(buffer) != -1; buffer.clear( )) {
for (int i=0;i<data.length;i++){
if (data[i] == 't'){
data[i] = 's'; }
}
buffer.flip( );
while (buffer.hasRemaining( )) {
outChannel.write(buffer);
}
}
inChannel.close( );
outChannel.close( );
}
}
14.4
Les fichiers à l'accès direct
L'exemple: un accès direct avec la
lecture d'information au début, au milieu et à la fin du
fichier, avec un tampon 5 octets
import java.io.IOException;
import java.nio.*;
import
java.nio.channels.SeekableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.EnumSet;
public class RafRead {
public static void
main(String[] args) {
int bufLen=5;
Path path = Paths.get("Test.txt");
ByteBuffer buf = ByteBuffer.allocate(bufLen);
String encoding = System.getProperty("file.encoding");
try (SeekableByteChannel sbc = (Files.newByteChannel(
path,
EnumSet.of(StandardOpenOption.READ)))) {
System.out.println("the size of the file is
"+sbc.size());
sbc.position(0);
System.out.println("\nReading "+bufLen+" character
from position: " + sbc.position());
do{ sbc.read(buf);
} while(buf.hasRemaining());
buf.flip();
System.out.print(Charset.forName(encoding).decode(buf));
buf.rewind();
// lecture au milieu
sbc.position(sbc.size() / 2);
System.out.println("\nReading "+bufLen+" character
from position: "+ sbc.position());
do{ sbc.read(buf);
} while(buf.hasRemaining());
buf.flip();
System.out.print(Charset.forName(encoding).decode(buf));
buf.rewind();
// fin de fichier
sbc.position(sbc.size() - bufLen);
System.out.println("\nReading "+bufLen+" character
from position: " + sbc.position());
do{ sbc.read(buf);
} while(buf.hasRemaining());
buf.flip();
System.out.print(Charset.forName(encoding).decode(buf));
buf.clear();
} catch (IOException ex) {
System.err.println(ex); }
}
}
L'exemple suivant lit les premiers 10 octets d'un fichier texte
Test.txt et les écrit sur une nouvelle ligne à la fin du
fichier.
import java.io.IOException;
import java.nio.ByteBuffer;
import
java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import
java.nio.file.StandardOpenOption;
import java.util.EnumSet;
public class RafRW {
public static void
main(String[] args) {
Path path = Paths.get("Test.txt");
ByteBuffer bf = ByteBuffer.allocate(10);
bf.put("\n".getBytes());
try (SeekableByteChannel sbc = (Files.newByteChannel(path,
EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE)))) {
bf.flip();
sbc.position(sbc.size());
while (bf.hasRemaining()) {
sbc.write(bf);
}
bf.clear();
sbc.position(0);
do { sbc.read(bf); } while (bf.hasRemaining());
bf.flip();
sbc.position(sbc.size());
while (bf.hasRemaining()) {
sbc.write(bf);
}
bf.clear();
} catch (IOException ex) {
System.err.println(ex);
}
}
}