第一章
第一节,Buffuer
案例一 从buffur 读出数据,
创建了一个 FileInputStream
对象,并通过调用 getChannel()
方法获取了与之关联的 FileChannel
。然后,
我们创建了一个 ByteBuffer
,并使用 channel.read(buffer)
方法从文件中读取数据到缓冲区。最后,我们通过循环将缓冲区中的数据打印出来。
package cn.itcast.netty.c1; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class TestByteBuffer { public static void main(String[] args) { // 使用 FileChannel 从文件中读取数据到 ByteBuffer try (FileChannel channel = new FileInputStream("data.txt").getChannel()) { // 准备缓冲区 ByteBuffer buffer = ByteBuffer.allocate(10); // 从 channel 读取数据,向 buffer 写入 channel.read(buffer); // 打印 buffer 的内容 buffer.flip(); // 切换到读模式 while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } } catch (IOException e) { e.printStackTrace(); } } }读Buffuer 读数据
读数据可以通过判断一下还有没有数据
import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class TestByteBuffer { public static void main(String[] args) { // 使用 FileChannel 从文件中读取数据到 ByteBuffer try (FileChannel channel = new FileInputStream("data.txt").getChannel()) { // 准备缓冲区 ByteBuffer buffer = ByteBuffer.allocate(10); while (true) { // 从 channel 读取数据,向 buffer 写入 int len = channel.read(buffer); if (len == -1) { // 没有内容了 break; } // 打印 buffer 的内容 buffer.flip(); // 切换至读模式 while (buffer.hasRemaining()) { // 是否还有剩余未读数据 byte b = buffer.get(); System.out.println((char) b); } buffer.clear(); // 清空缓冲区以准备下一次读取 } } catch (IOException e) { e.printStackTrace(); } } }
读写操作
import static cn.itcast.netty.c1.ByteBufferUtil.debugAll; public class TestByteBufferReadWrite { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(10); // 创建一个容量为10的ByteBuffer buffer.put((byte) 0x61); // 向buffer中放入字符'a' (ASCII码为0x61) debugAll(buffer); // 打印buffer的详细信息 buffer.put(new byte[]{0x62, 0x63, 0x64}); // 向buffer中放入字节数组,包含字符'b', 'c', 'd' debugAll(buffer); // 打印buffer的详细信息 System.out.println(buffer.get()); // 从buffer中读取一个字节并打印,这里会打印出'a' buffer.flip(); // 将buffer的模式从写模式切换到读模式 System.out.println(buffer.get()); // 再次从buffer中读取一个字节并打印,这里会打印出'b' debugAll(buffer); // 打印buffer的详细信息 buffer.compact(); // 清除buffer中的未读数据,已读数据之前的区域会被清空 debugAll(buffer); // 打印buffer的详细信息 buffer.put(new byte[]{0x65, 0x6F}); // 向buffer中放入字节数组,包含字符'e', 'o' debugAll(buffer); // 打印buffer的详细信息 } }
代码示例三 ,我们创建了一个 ByteBuffer
,并使用 while
循环不断从文件中读取数据到缓冲区。当 channel.read(buffer)
返回 -1 时,表示文件已经读取完毕
,我们跳出循环。接下来,我们通过循环将缓冲区中的数据逐个打印出来。在每次循环结束时,我们使用 buffer.clear()
方法清空缓冲区,
以便下次读取。如果在读取过程中发生任何 IOException
,我们会捕获异常并打印堆栈跟踪。
import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class TestByteBuffer { public static void main(String[] args) { // 使用 FileChannel 从文件中读取数据到 ByteBuffer try (FileChannel channel = new FileInputStream("data.txt").getChannel()) { // 准备缓冲区 ByteBuffer buffer = ByteBuffer.allocate(10); while (true) { // 从 channel 读取数据,向 buffer 写入 int len = channel.read(buffer); if (len == -1) { // 没有内容了 break; } // 打印 buffer 的内容 buffer.flip(); // 切换至读模式 while (buffer.hasRemaining()) { // 是否还有剩余未读数据 byte b = buffer.get(); System.out.println((char) b); } buffer.clear(); // 清空缓冲区以准备下一次读取 } } catch (IOException e) { e.printStackTrace(); } } }
标记上一次打印位置
public static void main(String[] args) { // 假设buffer已经被填充了数据,并且已经flip切换到读模式 System.out.println((char) buffer.get()); // 打印buffer中的第一个字符 System.out.println((char) buffer.get()); // 打印buffer中的第二个字符 buffer.mark(); // 在当前位置做一个标记 System.out.println((char) buffer.get()); // 打印buffer中的第三个字符 System.out.println((char) buffer.get()); // 打印buffer中的第四个字符 buffer.reset(); // 将position重置到之前标记的位置 System.out.println((char) buffer.get()); // 重新打印buffer中的第三个字符 System.out.println((char) buffer.get()); // 重新打印buffer中的第四个字符 // get(i)不会改变读索引的位置 System.out.println((char) buffer.get(3)); // 直接获取索引为3位置的字符,不改变position debugAll(buffer); // 打印buffer的详细信息 }
分读同写
import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.io.RandomAccessFile; import java.io.IOException; public class ReadFileWithRandomAccess { public static void main(String[] args) { try (RandomAccessFile file = new RandomAccessFile("helloworld/3parts.txt", "rw")) { FileChannel channel = file.getChannel(); // 分配三个ByteBuffer,用于存储从文件中读取的数据 ByteBuffer a = ByteBuffer.allocate(3); ByteBuffer b = ByteBuffer.allocate(3); ByteBuffer c = ByteBuffer.allocate(5); // 从文件中读取数据到这三个ByteBuffer中 channel.read(new ByteBuffer[]{a, b, c}); // 确保每个ByteBuffer都处于读模式 a.flip(); b.flip(); c.flip(); // 打印每个ByteBuffer的内容 debug(a); debug(b); debug(c); } catch (IOException e) { e.printStackTrace(); } } // 假设debug方法是用来打印ByteBuffer的内容 private static void debug(ByteBuffer buffer) { while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } System.out.println(); } }
上一次没处理到下一次处理的示例‘
public class ByteBufferSplit { public static void main(String[] args) { ByteBuffer source = ByteBuffer.allocate(32); source.put("Hello, world\n" + "I'm zhangsan\n" + "How are you?\n".getBytes()); split(source); source.put("What's your name?\n".getBytes()); split(source); } private static void split(ByteBuffer source) { source.flip(); while (source.hasRemaining()) { // 找到一条完整消息的结束符'\n' if (source.get(source.position()) == '\n') { int length = source.position() + 1 - source.position(); // 计算当前消息的长度 // 把这条完整消息存入新的ByteBuffer ByteBuffer target = ByteBuffer.allocate(length); // 从source读取,向target写入 for (int j = 0; j< length; j++) { target.put(source.get()); } target.flip(); // 确保target处于读模式 // 这里可以处理或打印target的内容 System.out.println(new String(target.array(), 0, target.limit())); source.position(source.position() + 1); // 移动source的位置到下一条消息的开始 } else { source.position(source.position() + 1); // 如果不是结束符,移动到下一个位置继续查找 } } } }
第二章,文件读写
import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.io.FileOutputStream; import java.io.IOException; public class ByteBufferWriteExample { public static void main(String[] args) { // 创建一个ByteBuffer并分配空间 ByteBuffer buffer = ByteBuffer.allocate(1024); // 向ByteBuffer中存入数据 buffer.put("This is some example text.\n".getBytes()); // 切换ByteBuffer到读模式,准备写入操作 buffer.flip(); // 获取FileChannel,准备写入文件 try (FileOutputStream fos = new FileOutputStream("output.txt"); FileChannel channel = fos.getChannel()) { // 当ByteBuffer中还有数据时,循环写入FileChannel while (buffer.hasRemaining()) { channel.write(buffer); } } catch (IOException e) { e.printStackTrace(); } } }
复制文件
import java.nio.channels.FileChannel; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileTransferExample { public static void main(String[] args) { // 定义源文件的路径 String from = "helloworld/data.txt"; // 定义目标文件的路径 String to = "helloworld/to.txt"; // 记录文件传输操作开始的时间 long start = System.nanoTime(); try ( // 创建读取源文件的FileChannel FileChannel fromChannel = new FileInputStream(from).getChannel(); // 创建写入目标文件的FileChannel FileChannel toChannel = new FileOutputStream(to).getChannel(); ) { // 使用transferTo方法将数据从源FileChannel传输到目标FileChannel fromChannel.transferTo(0, fromChannel.size(), toChannel); } catch (IOException e) { // 捕获并处理可能发生的IOException e.printStackTrace(); } finally { // 记录文件传输操作结束的时间 long end = System.nanoTime(); // 计算并打印文件传输操作所用的时间,单位为毫秒 System.out.println("transferTo 用时: " + (end - start) / 1_000_000.0 + " ms"); } } }
大文件读写
import java.nio.channels.FileChannel; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestFileChannelTransferTo { public static void main(String[] args) { try ( // 创建读取源文件的FileChannel FileChannel from = new FileInputStream("data.txt").getChannel(); // 创建写入目标文件的FileChannel FileChannel to = new FileOutputStream("to.txt").getChannel(); ) { // 获取源文件的大小 long size = from.size(); // left变量代表还剩余多少字节未传输 for (long left = size; left > 0; ) { // 使用transferTo方法传输剩余的字节,可能不会传输全部剩余字节,取决于操作系统的限制 left -= from.transferTo((size - left), Math.min(left, Integer.MAX_VALUE), to); } } catch (IOException e) { // 捕获并处理可能发生的IOException e.printStackTrace(); } } }
统计文件个数
import java.io.IOException; import java.nio.file.AtomicMoveNotSupportedException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.atomic.AtomicInteger; public class TestFilesWalkFileTree { public static void main(String[] args) throws IOException { AtomicInteger dirCount = new AtomicInteger(); AtomicInteger fileCount = new AtomicInteger(); // 遍历指定路径下的所有文件和目录 Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println("====> " + dir); dirCount.incrementAndGet(); // 增加目录计数 return super.preVisitDirectory(dir, attrs); } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println(file); fileCount.incrementAndGet(); // 增加文件计数 return super.visitFile(file, attrs); } }); // 打印目录和文件的总数 System.out.println("dir count: " + dirCount); System.out.println("file count: " + fileCount); } }
统计文件和文件夹个数,的示例二
import java.io.IOException; import java.nio.file.AtomicMoveNotSupportedException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.atomic.AtomicInteger; public class TestFilesWalkFileTree { public static void main(String[] args) throws IOException { AtomicInteger dirCount = new AtomicInteger(); AtomicInteger fileCount = new AtomicInteger(); // 遍历指定路径下的所有文件和目录 Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println("====> " + dir); dirCount.incrementAndGet(); // 增加目录计数 return super.preVisitDirectory(dir, attrs); } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println(file); fileCount.incrementAndGet(); // 增加文件计数 return super.visitFile(file, attrs); } }); // 打印目录和文件的总数 System.out.println("dir count: " + dirCount); System.out.println("file count: " + fileCount); } }统计文件个数
遍历子文件件和子文件夹
import java.io.IOException; import java.nio.file.AtomicMoveNotSupportedException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.atomic.AtomicInteger; public class TestFilesWalkFileTree { public static void main(String[] args) throws IOException { // 创建两个AtomicInteger对象来跟踪目录和文件的数量 AtomicInteger dirCount = new AtomicInteger(); AtomicInteger fileCount = new AtomicInteger(); // 使用Files.walkFileTree方法遍历指定路径下的所有文件和目录 Files.walkFileTree( Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), // 指定要遍历的路径 new SimpleFileVisitor<Path>() { // 提供一个自定义的SimpleFileVisitor来处理遍历过程中的每个文件和目录 @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println("====> " + dir); // 打印当前遍历到的目录 dirCount.incrementAndGet(); // 增加目录计数 return super.preVisitDirectory(dir, attrs); // 继续遍历 } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println(file); // 打印当前遍历到的文件 fileCount.incrementAndGet(); // 增加文件计数 return super.visitFile(file, attrs); // 继续遍历 } } ); // 打印目录和文件的总数 System.out.println("dir count: " + dirCount); System.out.println("file count: " + fileCount); } }
查找文件夹下面的jar 文件
import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.atomic.AtomicInteger; public class TestFilesWalkFileTree { public static void main(String[] args) throws IOException { AtomicInteger jarCount = new AtomicInteger(); Files.walkFileTree(Paths.get("C:\\Program Files\\Java\\jdk1.8.0_91"), new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (file.toString().endsWith(".jar")) { System.out.println(file); jarCount.incrementAndGet(); } return super.visitFile(file, attrs); } }); System.out.println("Jar count: " + jarCount); } }
删除文件
import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; public class TestFilesWalkFileTree { public static void main(String[] args) throws IOException { // 删除指定文件 try { Files.delete(Paths.get("D:\\Snipaste-1.16.2-x64-副本")); } catch (NoSuchFileException e) { System.err.println("文件不存在: " + e.getFile()); } // 遍历指定路径下的所有文件,并删除它们 Files.walkFileTree(Paths.get("O:\\snipaste-1.16.2-x64-副本"), new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println(file); // 打印文件路径 Files.delete(file); // 删除文件 return super.visitFile(file, attrs); } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { System.out.println("<==== 退出 " + dir); // 打印目录路径 Files.delete(dir); // 删除目录 return super.postVisitDirectory(dir, exc); } }); } }
复制文件夹,下所有文件,和文件夹
import java.io.IOException; import java.nio.file.*; public class TestFilesCopy { public static void main(String[] args) { String source = "C:\\Snipaste-1.16.2-x64"; String target = "C:\\Snipaste-1.16.2-x64aaa"; Files.walk(Paths.get(source)).forEach(path -> { try { String targetName = path.toString().replace(source, target); // 如果是目录 if (Files.isDirectory(path)) { Files.createDirectory(Paths.get(targetName)); } // 如果是普通文件 else if (Files.isRegularFile(path)) { Files.copy(path, Paths.get(targetName)); } } catch (IOException e) { e.printStackTrace(); } }); } }
标签:文件,java,NIO,buffer,读写,file,import,ByteBuffer,public From: https://www.cnblogs.com/ZzwWan/p/18253024