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.
<source lang="java">
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(); }
}</source>
Copying a file using channels and buffers
<source lang="java">
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(); } }
}</source>
Create a read-only memory-mapped file
<source lang="java">
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()); }
}</source>
Create a read-write memory-mapped file
<source lang="java">
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()); }
}</source>
File concatenation based on new IO
<source lang="java">
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(); }
}</source>
Get FileChannel from FileInputStream
<source lang="java">
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(); }
}</source>
Lock a FileChannel and release the lock
<source lang="java">
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(); }
}</source>
Locking Copier
<source lang="java">
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(); }
}</source>
New IO Copier
<source lang="java">
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(); }
}</source>
New IO Duplicator
<source lang="java">
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(); }
}</source>
New IO Transfer
<source lang="java">
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(); }
}</source>
Save and read text using FileChannel without encoding
<source lang="java">
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(); }
}</source>
Save and read text using FileChannel with UTF-16BE encoding
<source lang="java">
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()); }
} /**/</source>
Some text
Test overlapping locks on different file channels
<source lang="java">
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"); }
}</source>
The Gathering Write
<source lang="java">
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(); }
}</source>
Using a Channel to Write a String to a File
<source lang="java">
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); } }
}</source>
Using FileChannel to random access to a File
<source lang="java">
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; } }
}</source>
File written is 40bytes. 3 5 1 7 7 5 7 1 7 1
Using FileChannel to read text file
<source lang="java">
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(); }
}</source>
Using transferTo() between channels
<source lang="java">
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()); }
}</source>
Writing and Appending a ByteBuffer to a File
<source lang="java">
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(); }
}</source>
Writing a String as Bytes
<source lang="java">
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); } }
}</source>
Writing Mixed Data to a File
<source lang="java">
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); } }
}</source>
Writing Numerical Data to a File
<source lang="java">
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); } }
}</source>
Writing Varying Length Strings to a File
<source lang="java">
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); } }
}</source>