本文目录一览:
- 1、Java中IO与NIO的区别和使用场景
- 2、JAVA高手请进!求一个JAVA程序:将一个文件中的内容复制到另一个文件中。
- 3、JAVA程序中怎么把信息存到文件中
- 4、利用java.nio的FileChannel能够实现按行读取文件吗?(解决了)
- 5、介绍一下Java NIO,NIO读取文件都有哪些方法
Java中IO与NIO的区别和使用场景
在java2以前,传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大。java5以后使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数量线程的线程池,甚至一个线程来为任意数量的连接服务。由于线程数量小于连接数量,所以每个线程进行IO操作时就不能阻塞,如果阻塞的话,有些连接就得不到处理,NIO提供了这种非阻塞的能力。
NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式。
反应器(Reactor):用于事件多路分离和分派的体系结构模式
通常的,对一个文件描述符指定的文件或设备, 有两种工作方式: 阻塞 与非阻塞 。所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止。而对于非阻塞状态, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待 。-javanio上传文件
一种常用做法是:每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。-javanio上传文件
另一种较高效的做法是:服务器端保存一个Socket连接列表,然后对这个列表进行轮询,如果发现某个Socket端口上有数据可读时(读就绪),则调用该socket连接的相应读操作;如果发现某个 Socket端口上有数据可写时(写就绪),则调用该socket连接的相应写操作;如果某个端口的Socket连接已经中断,则调用相应的析构方法关闭该端口。这样能充分利用服务器资源,效率得到了很大提高。-javanio上传文件
传统的阻塞式IO,每个连接必须要开一个线程来处理,并且没处理完线程不能退出。
非阻塞式IO,由于基于反应器模式,用于事件多路分离和分派的体系结构模式,所以可以利用线程池来处理。事件来了就处理,处理完了就把线程归还。而传统阻塞方式不能使用线程池来处理,假设当前有10000个连接,非阻塞方式可能用1000个线程的线程池就搞定了,而传统阻塞方式就需要开10000个来处理。如果连接数较多将会出现资源不足的情况。非阻塞的核心优势就在这里。-javanio上传文件
为什么会这样,下面就对他们做进一步细致具体的分析:
首先,我们来分析传统阻塞式IO的瓶颈在哪里。在连接数不多的情况下,传统IO编写容易方便使用。但是随着连接数的增多,问题传统IO就不行了。因为前面说过,传统IO处理每个连接都要消耗一个线程,而程序的效率当线程数不多时是随着线程数的增加而增加,但是到一定的数量之后,是随着线程数的增加而减少。这里我们得出结论,传统阻塞式IO的瓶颈在于不能处理过多的连接。-javanio上传文件
然后,非阻塞式IO的出现的目的就是为了解决这个瓶颈。而非阻塞式IO是怎么实现的呢?非阻塞IO处理连接的线程数和连接数没有联系,也就是说处理 10000个连接非阻塞IO不需要10000个线程,你可以用1000个也可以用2000个线程来处理。因为非阻塞IO处理连接是异步的。当某个链接发送请求到服务器,服务器把这个连接请求当作一个请求"事件",并把这个"事件"分配给相应的函数处理。我们可以把这个处理函数放到线程中去执行,执行完就把线程归还。这样一个线程就可以异步的处理多个事件。而阻塞式IO的线程的大部分时间都浪费在等待请求上了。-javanio上传文件
所谓阻塞式IO流,就是指在从数据流当中读写数据的的时候,阻塞当前线程,直到IO流可以
重新使用为止,你也可以使用流的avaliableBytes()函数看看当前流当中有多少字节可以读取,这样
就不会再阻塞了。
JAVA高手请进!求一个JAVA程序:将一个文件中的内容复制到另一个文件中。
最简单的io流问题,不用什么高手,
我给你写个方法,参数是2个字符串,第一个写原文件的全路径,第二个写目标文件的全路进。 你试试吧
public void copy(String fromFilePath, String toFilePath) {
try {
FileInputStream fis = new FileInputStream(fromFilePath);
FileOutputStream fos = new FileOutputStream(toFilePath);
byte[] b = new byte[100];
try {
while (fis.read(b) != (-1)) {
fos.write(b);
}
if (fis != null) {
fis.close();
fis = null;
}
if (fos != null) {
fos.flush();
fos.close();
fos = null;
}
} catch (IOException e) {
System.out.println("io异常");
}
} catch (FileNotFoundException e) {
System.out.println("源文件不存在");
}
public static void main(String[] args) {
//自己把路径补齐,别忘了!!!!!!!!!!!!!!!!
String fromFilePath=" "; // 源文件的全路径。 比方"d://myphoto//nihao.mp3"
String toFilePath=" "; //目标文件的全路劲。 如果不存在会自动建立,如存在则在文件尾继续添加
new CopyTest().copy(fromFilePath, toFilePath);
}
}
JAVA程序中怎么把信息存到文件中
这个问题就是涉及到标准输入输出IO的问题啊。我给你写一个程序你想看看!
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
public class Test{
public static void main(String[] args) throws Exception {
//创建2个文件
File file1 = new File("D://test1.txt");
File file2 = new File("d://test2.txt");
file1.createNewFile();
file2.createNewFile();
//从键盘输入的字符写入test1.txt
FileWriter fout = new FileWriter(file1);
String str=null;
System.out.println("Please input a String:");
BufferedReader fin = new BufferedReader(new InputStreamReader(System.in));
str = fin.readLine();
System.out.println(str);
fout.write(str,0,str.length());
fout.flush();
fout.close();
fin.close();
//复制文件test1.txt的内容到test2.txt
//为了让你明白通道所以我这里用了2种读写入文件的方法
new Exam2().copy("D://test1.txt", "d://test2.txt");
}
/**
* 复制文件封装类
* @param url1
* @param url2
* @throws Exception
*/
public void copy(String url1, String url2) throws Exception {
FileInputStream input = new FileInputStream(url1);
FileChannel filechannel = input.getChannel();
FileOutputStream output = new FileOutputStream(url2);
FileChannel filechannel2 = output.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024 * 8);
while (filechannel.read(buf) != -1) {
buf.flip();
filechannel2.write(buf);
buf.clear();
}
input.close();
filechannel.close();
output.close();
filechannel2.close();
}
}
您的进步是我最大的动力,如果你觉得我回答的合理的话,请给我多加分。谢谢,如果不明白的话,请给我留言。大家相互学习啊! 加油!
利用java.nio的FileChannel能够实现按行读取文件吗?(解决了)
利用java.nio的FileChannel能够实现按行读取文件:
具体思路是:设置两个缓冲区,一大一小,大的缓冲区为每次读取的量,小的缓冲区存放每行的数据(确保大小可存放文本中最长的那行)。读取的时候判断是不是换行符13,是的话则返回一行数据,不是的话继续读取,直到读完文件。-javanio上传文件
实现方法:
FileChannel fc=raf.getChannel();
//一次读取文件,读取的字节缓存数
ByteBuffer fbb=ByteBuffer.allocate(1024*5);
fc.read(fbb);
fbb.flip();
//每行缓存的字节 根据你的实际需求
ByteBuffer bb=ByteBuffer.allocate(500);
//判断是否读完文件
public boolean hasNext() throws IOException {
if(EOF)return false;
if(fbb.position()==fbb.limit()){//判断当前位置是否到了缓冲区的限制
if(readByte()==0) return false;
}
while(true){
if(fbb.position()==fbb.limit()){
if(readByte()==0) break;
}
byte a=fbb.get();
if(a==13){
if(fbb.position()==fbb.limit()){
if(readByte()==0) break;
}
return true;
}else{
if (bb.position() bb.limit()) {
bb.put(a);
}else {
if(readByte()==0) break;
}
}
}
return true;
}
介绍一下Java NIO,NIO读取文件都有哪些方法
NIO也就是New I/O,是一组扩展Java IO操作的API集, 于Java 1.4起被引入,Java 7中NIO又提供了一些新的文件系统API,叫NIO2.
NIO2提供两种主要的文件读取方法:
使用buffer和channel类
使用Path 和 File 类
NIO读取文件有以下三种方式:
1. 旧的NIO方式,使用BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class WithoutNIOExample
{
public static void main(String[] args)
{
BufferedReader br = null;
String sCurrentLine = null;
try
{
br = new BufferedReader(
new FileReader("test.txt"));
while ((sCurrentLine = br.readLine()) != null)
{
System.out.println(sCurrentLine);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)
br.close();
} catch (IOException ex)
{
ex.printStackTrace();
}
}
}
}
2. 使用buffer读取小文件
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ReadFileWithFileSizeBuffer
{
public static void main(String args[])
{
try
{
RandomAccessFile aFile = new RandomAccessFile(
"test.txt","r");
FileChannel inChannel = aFile.getChannel();
long fileSize = inChannel.size();
ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
inChannel.read(buffer);
buffer.rewind();
buffer.flip();
for (int i = 0; i fileSize; i++)
{
System.out.print((char) buffer.get());
}
inChannel.close();
aFile.close();
}
catch (IOException exc)
{
System.out.println(exc);
System.exit(1);
}
}
}
3. 分块读取大文件
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ReadFileWithFixedSizeBuffer
{
public static void main(String[] args) throws IOException
{
RandomAccessFile aFile = new RandomAccessFile
("test.txt", "r");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(inChannel.read(buffer) 0)
{
buffer.flip();
for (int i = 0; i buffer.limit(); i++)
{
System.out.print((char) buffer.get());
}
buffer.clear(); // do something with the data and clear/compact it.
}
inChannel.close();
aFile.close();
}
}
4. 使用MappedByteBuffer读取文件
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class ReadFileWithMappedByteBuffer
{
public static void main(String[] args) throws IOException
{
RandomAccessFile aFile = new RandomAccessFile
("test.txt", "r");
FileChannel inChannel = aFile.getChannel();
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
buffer.load();?
for (int i = 0; i buffer.limit(); i++)
{
System.out.print((char) buffer.get());
}
buffer.clear(); // do something with the data and clear/compact it.
inChannel.close();
aFile.close();
}
}