『壹』 JAVA中的Scanner类与IO流那些有什么区别
publicclassTest{
publicstaticvoidmain(String[]args){
Scannersc=newScanner(System.in);
inti=sc.nextInt();
System.out.println(i);
}
}
从上面可以看到,Scanner类似一个容器,将输入流放进去,然后通过nextXXX(),就可以通过特定的输入流中获取到数据,这个输入流不仅可以是控制台输入System.in,也可以是文件流如下:
Scannersc=newScanner(newFile("myNumbers"));
while(sc.hasNextLong()){
longaLong=sc.nextLong();
}
『贰』 java的io流包装数据为什么用byte类型数组。
因为计算机处理数据的单位就是字节。所以,当我们处理磁盘文件和内存数据的时候,就正好选择和计算机处理数据单位等大的数据类型来存储数据。而且,我们调用的类库中的API也都是使用这样类型的参数。所以,我们就必须在编写程序的时候使用byte类型的数组。
『叁』 java io流的典型使用方式有几种
Java中IO流分成两大类,
一种是输入流,所有的输入流都直接或间接继承自InputStream抽象类,输入流作为数据的来源,我们可以通过输入流的read方法读取字节数据;
另一种是输出流,所有的输出流都直接或间接继承自OutputStream抽象类,输出流接收数据,可以通过write方法写入字节数据。
Java的IO流类中,大部分的输入流和输出流都是成对存在的,即如果存在XXXInputStream,那么就存在XXXOutputStream,反之亦然。SequenceInputStream和StringBufferInputStream是特例,没有对应的SequenceOutputStream类和StringBufferOutputStream类,许多IO操作都可能会抛出IOException异常,比如read、write、close操作。
以下是Java的IO流中常见的输入流,由于每个输入流都有其对应的输出流,所以此处就不再列出输出流的继承结构图。
1、ByteArrayInputStream & ByteArrayOutputStream:
ByteArrayInputStream构造函数中需要传入一个byte数组作为数据源,当执行read操作时,就会从该数组中读取数据,正如其名,是一种基于字节数组实现的一种简单输入流,显而易见的是,如果在构造函数中传入了null作为字节数据,那么在执行read操作时就会出现NullPointerException异常,但是在构造函数初始化阶段不会抛出异常;与之相对应的是ByteArrayOutputStream,其内部也有一个字节数组用于存储write操作时写入的数据,在构造函数中可以传入一个size指定其内部的byte数组的大小,如果不指定,那么默认它会将byte数组初始化为32字节,当持续通过write向ByteArrayOutputStream中写入数据时,如果其内部的byte数组的剩余空间不能够存储需要写入的数据,那么那么它会通过调用内部的ensureCapacity
方法对其内部维护的byte数组进行扩容以存储所有要写入的数据,所以不必担心其内部的byte数组太小导致的IndexOutOfBoundsException之类的异常。
2、FileInputStream & FileOutputStream
FileInputStream 能够将文件作为数据源,读取文件中的流,通过File对象或文件路径等初始化,在其构造函数中,如果传入的File对象(或与其相对应的文件路径所表示的File对象)不存在或是一个目录而不是文件或者由于其他原因无法打开读取数据,都会导致在初始化阶段导致抛出FileNotFoundException异常;与FileInputStream 相对应的是FileOutputStream,可以通过FileOutputStream向文件中写入数据,也需要通过File对象或文件路径对其初始化,如同FileInputStream ,如果传入的File对象(或与其相对应的文件路径所表示的File对象)是一个目录而不是文件或者由于其他原因无法创建该文件写入数据,都会导致在初始化阶段抛出FileNotFoundException异常。
3、PipedInputStream & PipedOutputStream
PipedInputStream和PipedOutputStream一般是结合使用的,这两个类用于在两个线程间进行管道通信,一般在一个线程中执行PipedOutputStream 的write操作,而在另一个线程中执行PipedInputStream的read操作。可以在构造函数中传入相关的流将PipedInputStream 和PipedOutputStream 绑定起来,也可以通过二者的connect方法将二者绑定起来,一旦二者进进行了绑定,那么PipedInputStream的read方法就会自动读取PipedOutputStream写入的数据。PipedInputStream的read操作是阻塞式的,当执行PipedOutputStream的write操作时,PipedInputStream会在另一个线程中自动读取PipedOutputStream写入的内容,如果PipedOutputStream一直没有执行write操作写入数据,那么PipedInputStream的read方法会一直阻塞PipedInputStream的read方法所运行的线程直至读到数据。单独使用PipedInputStream或单独使用PipedOutputStream时没有任何意义的,必须将二者通过connect方法(或在构造函数中传入对应的流)进行连接绑定,如果单独使用其中的某一个类,就会触发IOException: Pipe Not Connected.
4、ObjectInputStream & ObjectOutputStream
ObjectOutputStream具有一系列writeXXX方法,在其构造函数中可以掺入一个OutputStream,可以方便的向指定的输出流中写入基本类型数据以及String,比如writeBoolean、writeChar、writeInt、writeLong、writeFloat、writeDouble、writeCharts、writeUTF等,除此之外,ObjectOutputStream还具有writeObject方法。writeObject方法中传入的类型必须实现了Serializable接口,从而在执行writeObject操作时将对象进行序列化成流,并将其写入指定的输出流中。与ObjectOutputStream相对应的是ObjectInputStream,ObjectInputStream有与OutputStream中的writeXXX系列方法完全对应的readXXX系列方法,专门用于读取OutputStream通过writeXXX写入的数据。
5、SequenceInputStream
SequenceInputStream 主要是将两个(或多个)InputStream在逻辑上合并为一个InputStream,比如在构造函数中传入两个InputStream,分别为in1和in2,那么SequenceInputStream在读取操作时会先读取in1,如果in1读取完毕,就会接着读取in2。在我们理解了SequenceInputStream 的作用是将两个输入流合并为一个输入流之后,我们就能理解为什么不存在对应的SequenceOutputStream 类了,因为将一个输出流拆分为多个输出流是没有意义的。
6、StringBufferInputStream
StringBufferInputStream允许通过在构造函数中传入字符串以读取字节,在读取时内部主要调用了String的charAt方法。与SequenceInputStream类似,StringBufferInputStream也没有对应的OutputStream,即不存在StringBufferOutputStream类。Java没有设计StringBufferOutputStream类的理由也很简单,我们假设StringBufferOutputStream存在,那么StringBufferOutputStream应该是内部通过执行write操作写入数据更新其内部的String对象,比如有可能是通过StringBuilder来实现,但是这样做毫无意义,因为一旦我们String的构造函数中可以直接传入字节数组构建字符串,简单明了,所以设计StringBufferOutputStream就没有太大的必要了。StringBufferInputStream这个类本身存在一点问题,它不能很好地将字符数组转换为字节数组,所以该类被Java标记为废弃的(Deprecated),其官方推荐使用StringReader作为代替。
7、FilterInputStream & FilterOutputStream
FilterInputStream包含了其他的输入流,说具体点就是在其构造函数中需要传入一个InputStream并将其保存在其名为in的字段中,FilterInputStream只是简单的覆盖了所有的方法,之所说是简单覆盖是因为在每个覆盖函数中,它只是调用内部的保存在in字段中的InputStream所对应的方法,比如在其覆盖read方法时,内部只是简单调用了in.read()方法。FilterInputStream的子类可以进一步覆盖某些方法以保持接口不变的情况下实现某一特性(比如其子类有的可以通过使用缓存优化读取的效率)或者提供一些其他额外的实用方法。所以在使用时FilterInputStream可以让传入的InputStream具有一些额外的特性,即对构造函数传入的InputStream进行了一层包裹,使用了典型的装饰着模式,如果只看FilterInputStream本身这一个类的话,则该类自己本身意义不大,因为其只是通过内部的字段in简单覆写某些方法。但是如果将FilterInputStream 和其子类结合起来使用话,那么就很有用了。比如FilterInputStream 有两个子类BufferedInputStream和DataInputStream,这两个类在下面还会详细介绍。BufferedInputStream对read操作做了优化,每次读操作时都读取一大块数据,然后将其放入内部维护的一个字节数组缓冲区中。当外面调用BufferedInputStream的read方法时,首先去该缓冲区中读取数据,这样就避免了频繁的实际的读操作,BufferedInputStream对外没有暴露额外的其他方法,但是其内部的read方法已经经过优化了,所以在执行读操作的时候效率更高。DataInputStream与ObjectInputStream有点类似,可以通过一些readXXX方法读取基本类型的数据,这是非常有用的一些方法。
8、BufferedInputStream & BufferedOutputStream
如上面所介绍的那样,在BufferedInputStream的构造函数中需要传入一个InputStream, BufferedInputStream内部有一个字节数组缓冲区,每次执行read操作的时候就从这buf中读取数据,从buf中读取数据没有多大的开销。如果buf中已经没有了要读取的数据,那么就去执行其内部绑定的InputStream的read方法,而且是一次性读取很大一块数据,以便填充满buf缓冲区。缓冲区buf的默认大小是8192字节,也就是8K,在构造函数中我们也可以自己传入一个size指定缓冲区的大小。由于我们在执行BufferedInputStream的read操作的时候,很多时候都是从缓冲区中读取的数据,这样就大大减少了实际执行其指定的InputStream的read操作的次数,也就提高了读取的效率。与BufferedInputStream 相对的是BufferedOutputStream。在BufferedOutputStream的构造函数中我们需要传入一个OutputStream,这样就将BufferedOutputStream与该OutputStream绑定在了一起。BufferedOutputStream内部有一个字节缓冲区buf,在执行write操作时,将要写入的数据先一起缓存在一起,将其存入字节缓冲区buf中,buf是有限定大小的,默认的大小是8192字节,即8KB,当然也可以在构造函数中传入size指定buf的大小。该buf只要被指定了大小之后就不会自动扩容,所以其是有限定大小的,既然有限定大小,就会有被填充完的时刻,当buf被填充完毕的时候会调用BufferedOutputStream的flushBuffer方法,该方法会通过调用其绑定的OutputStream的write方法将buf中的数据进行实际的写入操作并将buf的指向归零(可以看做是将buf中的数据清空)。如果想让缓存区buf中的数据理解真的被写入OutputStream中,可以调用flush方法,flush方法内部会调用flushBuffer方法。由于buf的存在,会大大减少实际执行OutputStream的write操作的次数,优化了写的效率。
『肆』 java判断是不是基本类型,基本类型与对应的包装类
byte short int long float double char boolean
区别很大,基本类型很特殊,内部用指针操作,包装类就是一般的类
『伍』 java i/o各种封装类 总结
常用的文件读写的类java.io.BufferedReader;
java.io.BufferedWriter;
java.io.File;
java.io.FileReader;
java.io.FileWriter;
一个简单的实例:File file = new File("H:\\test.txt"); // 实例一个File对象,参数为文件路径 // 判断file对象是否是目录 if (!file.isDirectory()) { FileReader fr = new FileReader(file); // 通过file对象实例一个文件读取器
BufferedReader br = new BufferedReader(fr); // 该对象可以对文件进行读取操作
FileWriter fw = new FileWriter("H:\\newtest.txt"); // 实例化一个文件写入对象,参数为新文件名
BufferedWriter bw = new BufferedWriter(fw);
String strLine1 = br.readLine(); // 从文件中读取一行1
String strLine2 = br.readLine(); // 从文件中读取一行2
bw.write(strLine1); // 将strLine1写入到新文件中
bw.newLine(); // 换行
bw.write(strLine2); // 再写入一行 // 最后别忘了关闭这些读写对象,记得从下往上的顺序关闭,即从最下层对象开始关
bw.close();
fw.close();
br.close();
fr.close(); // 调用这个可删除文件
file.delete(); }
『陆』 java io流中装饰器和过滤器的区别
楼主应该是领会了java io的精神的。在我以前学java的时候,与节点流相对的叫做包装流。
分类的依据就是节点流是直接操作IO节点如ByteArray, File, Socket等等,所以相应的InputStream/OutputStream就是节点流。
包装流是在java IO 管道机制中用来处理节点流的其他流对象,像各种Reader, Writer, Printer等等。他们的作用是在节点流基本功能至上提供扩展的功能,就像你说的对象、图片、字符串等的对应特殊操作。
java IO中还有另一种分类就是:字节流与字符流。字节流顾名思义就是直接操作byte二进制数据;字符流则直接操作文本数据。例如:ByteArrayInputStream, ObjectOutputStream等是字节流;BufferedReader, OutputStreamWriter等等是字符流。注意这个分类与上面节点流/包装流的分类不是互斥的,只是两种不同的分类体系。节点流通常都是字节流;而一个流对象可以既是包装流又是字符流,比如刚才说的OutputStreamWriter。
其实流的各种分类只不过是使我们更方便的理解IO包中类或对象的组织方式而已。不一定非要死抠字面。
B.T.W.
楼主所说的装饰器应该与IO中使用频繁的Decorator模式有关。而过滤器可能只是包装流的不同说法。当然也不排除你的资料里它可能是有特指的,比如文件操作中的FileFilter等等。
回答也有点长,请耐心看完,好吗?
『柒』 Java中有哪些常见的包装流,包装流的作用是什么
包装流:
1 有几类,一类主要以过滤器流为主
如BufferedInputStream,BufferedOuputStream
DataInputStream,DataOutputStream
CheckedOutputStream
CipherOutputStream
DataOutputStream
DeflaterOutputStream
DigestOutputStream
PrintStream
。。。。
2 对象流、管道流、扫描器等其他流
3 包装流,故名思义,目的是为了增强某种流的功能,如OutputStream,只负责输出字节,字节数组,关闭等简单的原始字节操作。为了使其在输出过程中具备更多的功能,如可以输出数字,布尔值,整数,小数,对象,UTF字符串等,则可以使用DataOutputStream完成各种数据的输出转换,并且将转换后的数据传递给被包装得原始OutputStream流,如FileOutputStream
3 包装流有个特点,必须有原始的具体的IO对象,不等独立使用,如ObjectOutputStream,ObjectIputStream,都必须要有具体的输出流对象FileOutputStream,SockeObjectOutputStream,因为包装流本省不能真正完成输入或者输出过程,必须使用可以完成输入、输出流对象作为动作的真正执行者,包装流不过简化了调用者在输入、输出过程中的一些数据处理和特殊要求。
由于流系统比较复杂,可以从FileOutputStream流开始来学习
『捌』 java IO流,哪些是节点流,哪些是过滤流。
IO不是字节流跟字符流吗?
根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流
『玖』 java基本类型和包装类的区别
int 是基本类型,直接存数值
Integer是类,产生对象时用一个引用指向这个对象
Java把内存划分成两种:一种是栈内存,另一种是堆内存
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配
而实际的对象是在存储堆内存中
即
int i = 5;//直接在栈中分配空间
Integer i = new Integr(5);//对象是在堆内存中,而i(引用变量)是在栈内存中
在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理.
因为在堆中分配空间所需的时间远大于从栈中分配存储空间,所以JAVA速度比C 慢
当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的外覆类了。Java中每种基本类型都有相应的外覆类。
int 和 Integer 的区别
java 提供两种不同的类型:引用类型(或者封装类型,Warpper)和原始类型(或内置类型,Primitive)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。