Java Tutorial/File/FileChannel
Содержание
- 1 A channel for a physical file
- 2 Copying a file using channels and buffers
- 3 Create a read-only memory-mapped file
- 4 Create a read-write memory-mapped file
- 5 File concatenation based on new IO
- 6 Get FileChannel from FileInputStream
- 7 Lock a FileChannel and release the lock
- 8 Locking Copier
- 9 New IO Copier
- 10 New IO Duplicator
- 11 New IO Transfer
- 12 Save and read text using FileChannel without encoding
- 13 Save and read text using FileChannel with UTF-16BE encoding
- 14 Test overlapping locks on different file channels
- 15 The Gathering Write
- 16 Using a Channel to Write a String to a File
- 17 Using FileChannel to random access to a File
- 18 Using FileChannel to read text file
- 19 Using transferTo() between channels
- 20 Writing and Appending a ByteBuffer to a File
- 21 Writing a String as Bytes
- 22 Writing Mixed Data to a File
- 23 Writing Numerical Data to a File
- 24 Writing Varying Length Strings to a File
A channel for a physical file
A channel for a physical file: provides an efficient mechanism for reading, writing, and manipulating the file.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] a) {
File aFile = new File("C:/myFile.text");
FileOutputStream outputFile = null; // Place to store an output stream
// reference
try {
// Create the stream opened to write
outputFile = new FileOutputStream(aFile);
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
}
// Get the channel for the file
FileChannel outputChannel = outputFile.getChannel();
}
}
Copying a file using channels and buffers
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
private static final int BSIZE = 1024;
public static void main(String[] args) throws Exception {
FileChannel in = new FileInputStream("source.txt").getChannel(), out = new FileOutputStream(
"target.txt").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
while (in.read(buffer) != -1) {
buffer.flip();
out.write(buffer);
buffer.clear();
}
}
}
Create a read-only memory-mapped file
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] argv) throws Exception {
File file = new File("filename");
FileChannel roChannel = new RandomAccessFile(file, "r").getChannel();
ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int) roChannel.size());
}
}
Create a read-write memory-mapped file
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] argv) throws Exception {
FileChannel rwChannel = new RandomAccessFile(new File("test.txt"), "rw").getChannel();
ByteBuffer wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, 0, (int) rwChannel.size());
}
}
File concatenation based on new IO
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) throws IOException {
if (args.length < 2) {
System.err.println("Usage: java MainClass inFile1 inFile2... outFile");
return;
}
ByteBuffer[] buffers = new ByteBuffer[args.length - 1];
for (int i = 0; i < args.length - 1; i++) {
RandomAccessFile raf = new RandomAccessFile(args[i], "r");
FileChannel channel = raf.getChannel();
buffers[i] = channel.map(FileChannel.MapMode.READ_ONLY, 0, raf.length());
}
FileOutputStream outFile = new FileOutputStream(args[args.length - 1]);
FileChannel out = outFile.getChannel();
out.write(buffers);
out.close();
}
}
Get FileChannel from FileInputStream
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) throws IOException {
FileChannel fc = new FileInputStream(new File("temp.tmp")).getChannel();
IntBuffer ib = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()).asIntBuffer();
while (ib.hasRemaining())
ib.get();
fc.close();
}
}
Lock a FileChannel and release the lock
import java.io.FileOutputStream;
import java.nio.channels.FileLock;
public class MainClass {
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("file.txt");
FileLock fl = fos.getChannel().tryLock();
if (fl != null) {
System.out.println("Locked File");
Thread.sleep(100);
fl.release();
System.out.println("Released Lock");
}
fos.close();
}
}
Locking Copier
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class MainClass {
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();
FileLock outLock = outChannel.lock();
FileLock inLock = inChannel.lock(0, inChannel.size(), true);
inChannel.transferTo(0, inChannel.size(), outChannel);
outLock.release();
inLock.release();
inChannel.close();
outChannel.close();
}
}
New IO Copier
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
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();
for (ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); inChannel.read(buffer) != -1; buffer
.clear()) {
buffer.flip();
while (buffer.hasRemaining())
outChannel.write(buffer);
}
inChannel.close();
outChannel.close();
}
}
New IO Duplicator
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
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(1024 * 1024);
int bytesRead = 0;
while (bytesRead >= 0 || buffer.hasRemaining()) {
if (bytesRead != -1)
bytesRead = inChannel.read(buffer);
buffer.flip();
outChannel.write(buffer);
buffer.rupact();
}
inChannel.close();
outChannel.close();
}
}
New IO Transfer
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
public class MainClass {
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();
inChannel.transferTo(0, inChannel.size(), outChannel);
inChannel.close();
outChannel.close();
}
}
Save and read text using FileChannel without encoding
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
public class MainClass {
private static final int BSIZE = 1024;
public static void main(String[] args) throws Exception {
FileChannel fc = new FileOutputStream("data2.txt").getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes()));
fc.close();
fc = new FileInputStream("data2.txt").getChannel();
ByteBuffer buff = ByteBuffer.allocate(BSIZE);
fc.read(buff);
buff.flip();
System.out.println(buff.asCharBuffer());
// Decode using this system"s default Charset:
buff.rewind();
String encoding = System.getProperty("file.encoding");
System.out.println("Decoded using " + encoding + ": " + Charset.forName(encoding).decode(buff));
// Or, we could encode with something that will print:
fc = new FileOutputStream("data2.txt").getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes("UTF-16BE")));
fc.close();
}
}
Save and read text using FileChannel with UTF-16BE encoding
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
public class MainClass {
private static final int BSIZE = 1024;
public static void main(String[] args) throws Exception {
FileChannel fc = new FileOutputStream("data2.txt").getChannel();
fc.write(ByteBuffer.wrap(
"Some text".getBytes("UTF-16BE")));
fc.close();
ByteBuffer buff = ByteBuffer.allocate(BSIZE);
// Now try reading again:
fc = new FileInputStream("data2.txt").getChannel();
buff.clear();
fc.read(buff);
buff.flip();
System.out.println(buff.asCharBuffer());
}
}
/**/
Some text
Test overlapping locks on different file channels
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class MainClass {
public static void main(String[] argv) throws Exception {
String filename = "test.dat";
RandomAccessFile raf1 = new RandomAccessFile(filename, "rw");
FileChannel fc1 = raf1.getChannel();
RandomAccessFile raf2 = new RandomAccessFile(filename, "rw");
FileChannel fc2 = raf2.getChannel();
System.out.println("Grabbing first lock");
FileLock lock1 = fc1.lock(0L, Integer.MAX_VALUE, false);
System.out.println("Grabbing second lock");
FileLock lock2 = fc2.lock(5, 10, false);
System.out.println("Exiting");
}
}
The Gathering Write
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) {
try {
test();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void test() throws Exception {
long[] primes = new long[] { 1, 2, 3, 5, 7 };
File aFile = new File("C:/test/primes.txt");
FileOutputStream outputFile = null;
outputFile = new FileOutputStream(aFile);
FileChannel file = outputFile.getChannel();
ByteBuffer[] buffers = new ByteBuffer[3];
buffers[0] = ByteBuffer.allocate(8);
buffers[2] = ByteBuffer.allocate(8);
String primeStr = null;
for (long prime : primes) {
primeStr = "prime = " + prime;
buffers[0].putDouble((double) primeStr.length()).flip();
buffers[1] = ByteBuffer.allocate(primeStr.length());
buffers[1].put(primeStr.getBytes()).flip();
buffers[2].putLong(prime).flip();
file.write(buffers);
buffers[0].clear();
buffers[2].clear();
}
System.out.println("File written is " + file.size() + "bytes.");
outputFile.close();
}
}
Using a Channel to Write a String to a File
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) {
String phrase = new String("text \n");
String dirname = "C:/test";
String filename = "charData.txt";
File dir = new File(dirname);
File aFile = new File(dir, filename);
FileOutputStream outputFile = null;
try {
outputFile = new FileOutputStream(aFile, true);
System.out.println("File stream created successfully.");
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
}
FileChannel outChannel = outputFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
System.out.println("New buffer: position = " + buf.position() + "\tLimit = "
+ buf.limit() + "\tcapacity = " + buf.capacity());
for (char ch : phrase.toCharArray()) {
buf.putChar(ch);
}
System.out.println("Buffer after loading: position = " + buf.position() + "\tLimit = "
+ buf.limit() + "\tcapacity = " + buf.capacity());
buf.flip();
System.out.println("Buffer after flip: position = " + buf.position() + "\tLimit = "
+ buf.limit() + "\tcapacity = " + buf.capacity());
try {
outChannel.write(buf);
outputFile.close();
System.out.println("Buffer contents written to file.");
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
Using FileChannel to random access to a File
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) throws Exception {
createFile();
File aFile = new File("C:/primes.bin");
FileInputStream inFile = new FileInputStream(aFile);
FileChannel inChannel = inFile.getChannel();
final int PRIMESREQUIRED = 10;
ByteBuffer buf = ByteBuffer.allocate(8 * PRIMESREQUIRED);
long[] primes = new long[PRIMESREQUIRED];
int index = 0; // Position for a prime in the file
// Count of primes in the file
final int PRIMECOUNT = (int) inChannel.size() / 8;
// Read the number of random primes required
for (int i = 0; i < PRIMESREQUIRED; i++) {
index = 8 * (int) (PRIMECOUNT * Math.random());
inChannel.read(buf, index); // Read the value
buf.flip();
primes[i] = buf.getLong(); // Save it in the array
buf.clear();
}
for (long prime : primes) {
System.out.printf("%12d", prime);
}
inFile.close(); // Close the file and the channel
}
private static void createFile() throws Exception {
long[] primes = new long[] { 1, 2, 3, 5, 7 };
File aFile = new File("C:/primes.bin");
FileOutputStream outputFile = new FileOutputStream(aFile);
FileChannel file = outputFile.getChannel();
final int BUFFERSIZE = 100;
ByteBuffer buf = ByteBuffer.allocate(BUFFERSIZE);
LongBuffer longBuf = buf.asLongBuffer();
int primesWritten = 0;
while (primesWritten < primes.length) {
longBuf.put(primes, primesWritten, min(longBuf.capacity(), primes.length - primesWritten));
buf.limit(8 * longBuf.position());
file.write(buf);
primesWritten += longBuf.position();
longBuf.clear();
buf.clear();
}
System.out.println("File written is " + file.size() + "bytes.");
outputFile.close();
}
private static int min(int a, int b) {
if (a > b) {
return b;
} else {
return a;
}
}
}
File written is 40bytes. 3 5 1 7 7 5 7 1 7 1
Using FileChannel to read text file
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) throws Exception {
File aFile = new File("charData.xml");
FileInputStream inFile = null;
inFile = new FileInputStream(aFile);
FileChannel inChannel = inFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
while (inChannel.read(buf) != -1) {
System.out.println("String read: " + ((ByteBuffer) (buf.flip())).asCharBuffer().get(0));
buf.clear();
}
inFile.close();
}
}
Using transferTo() between channels
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) throws Exception {
FileChannel in = new FileInputStream("source.txt").getChannel(), out = new FileOutputStream(
"target.txt").getChannel();
in.transferTo(0, in.size(), out);
// Or:
// out.transferFrom(in, 0, in.size());
}
}
Writing and Appending a ByteBuffer to a File
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] argv) throws Exception {
ByteBuffer bbuf = ByteBuffer.allocate(100);
File file = new File("filename");
boolean append = false;
FileChannel wChannel = new FileOutputStream(file, append).getChannel();
wChannel.write(bbuf);
wChannel.close();
}
}
Writing a String as Bytes
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) {
String phrase = new String("text\n");
String dirname = "C:/test"; // Directory name
String filename = "byteData.txt";
File aFile = new File(dirname, filename);
// Create the file output stream
FileOutputStream file = null;
try {
file = new FileOutputStream(aFile, true);
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
}
FileChannel outChannel = file.getChannel();
ByteBuffer buf = ByteBuffer.allocate(phrase.length());
byte[] bytes = phrase.getBytes();
buf.put(bytes);
buf.flip();
try {
outChannel.write(buf);
file.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
Writing Mixed Data to a File
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.LongBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) {
long[] primes = new long[] { 1, 2, 3, 5, 7 };
File aFile = new File("C:/test/primes.txt");
FileOutputStream outputFile = null;
try {
outputFile = new FileOutputStream(aFile);
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
}
FileChannel file = outputFile.getChannel();
final int BUFFERSIZE = 100;
ByteBuffer buf = ByteBuffer.allocate(BUFFERSIZE);
DoubleBuffer doubleBuf = buf.asDoubleBuffer();
buf.position(8);
CharBuffer charBuf = buf.asCharBuffer();
for (long prime : primes) {
String primeStr = "prime = " + prime;
doubleBuf.put(0, (double) primeStr.length());
charBuf.put(primeStr);
buf.position(2 * charBuf.position() + 8);
LongBuffer longBuf = buf.asLongBuffer();
longBuf.put(prime);
buf.position(buf.position() + 8);
buf.flip();
try {
file.write(buf);
} catch (IOException e) {
e.printStackTrace(System.err);
}
buf.clear();
doubleBuf.clear();
charBuf.clear();
}
try {
System.out.println("File written is " + file.size() + "bytes.");
outputFile.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
Writing Numerical Data to a File
import static java.lang.Math.min;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) {
long[] primes = new long[] { 1, 2, 3, 5, 7 };
File aFile = new File("C:/test/primes.bin");
FileOutputStream outputFile = null;
try {
outputFile = new FileOutputStream(aFile);
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
}
FileChannel file = outputFile.getChannel();
final int BUFFERSIZE = 100;
ByteBuffer buf = ByteBuffer.allocate(BUFFERSIZE);
LongBuffer longBuf = buf.asLongBuffer();
int primesWritten = 0;
while (primesWritten < primes.length) {
longBuf.put(primes, primesWritten, min(longBuf.capacity(), primes.length - primesWritten));
buf.limit(8 * longBuf.position());
try {
file.write(buf);
primesWritten += longBuf.position();
} catch (IOException e) {
e.printStackTrace(System.err);
}
longBuf.clear();
buf.clear();
}
try {
System.out.println("File written is " + file.size() + "bytes.");
outputFile.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
Writing Varying Length Strings to a File
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
public static void main(String[] args) {
String dirName = "c:/test";
String fileName = "test.txt";
String[] sayings = { "A1", "B12", "C123", "D1234", "E12345", "F123456", "G1234567" };
File aFile = new File(dirName, fileName);
FileOutputStream outputFile = null;
try {
outputFile = new FileOutputStream(aFile, true);
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
}
FileChannel outChannel = outputFile.getChannel();
int maxLength = 0;
for (String saying : sayings) {
if (maxLength < saying.length()){
maxLength = saying.length();
}
}
ByteBuffer buf = ByteBuffer.allocate(2 * maxLength + 4);
try {
for (String saying : sayings) {
buf.putInt(saying.length()).asCharBuffer().put(saying);
buf.position(buf.position() + 2 * saying.length()).flip();
outChannel.write(buf);
buf.clear();
}
outputFile.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}