关于java8有字符串流吗的信息

博主:adminadmin 2022-12-14 19:51:07 70

本篇文章给大家谈谈java8有字符串流吗,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

JAVA中的字符流和字节流。字节流我能理解,就是系统内部对数据以二进制方式存储,那字符流什么意思?

字符流是为字符设计的,对字节流进行包装

因为一个字符有可能占用多个字节的

例如UTF-8编码下,对中文汉字的长度是变长的(2-4个字节),各种编码长度都不一样

那如果你用字节流读取的话,那你还要去一个个的转换,这中间就很多问题了

因此就有了字符流,帮你完成了一系列的字节转换...

纯手工的,请采纳哈.

Java字符流和字节流对文件操作的区别

Java字符流是处理字符(Char)对象用的,字节流是处理字节(Byte)对象用的。处理的目标对象不同,处理方法也就不一样了。

字符流处理的基本单位是字符(Java中的字符是16位的),输入流以Reader为基础,输出流以Writer为基础;

字节流的基本单位是字节(Java中的字节是8位的),输入流以 InputStream为基础,输出流以 OutputStream为基础;

字符流在输入时可以按字符读取,也可以按行读取,会去掉回车换行,常用于读取字符数据;

而字节流按字节读取,不作任何处理,常用于读取二进制数据。

Java中的字符在内部都是使用Unicode进行表示的,因此,要正确读取字符数据,需要知道字符的编码字符集,字符流提供编码字符集的指定,如果不指定使用系统默认的方式对字符数据进行编码转换,这个编码字符集不正确,会造成读进来的地字符出现乱码。

字节流虽然是读取二进制数据用的,但也可以读取字符文件,按字节进行处理,读进来之后可以根据编码字符集进行转换,也可以变成字符串。

Java中有几种类型的流

在Java.io包中还有许多其他的流,主要是为了提高性能和使用方便。C/C++只能提供字节流。Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的.

字符流和字节流是根据处理数据的不同来区分的。字节流按照8位传输,字节流是最基本的,所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。

1.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;

2. 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。

读文本的时候用字符流,例如txt文件。读非文本文件的时候用字节流,例如mp3。理论上任何文件都能够用字节流读取,但当读取的是文本数据时,为了能还原成文本你必须再经过一个转换的工序,相对来说字符流就省了这个麻烦,可以有方法直接读取。

字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节, 操作字节和字节数组。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!

1.字节流:继承于InputStream \ OutputStream。

OutputStream提供的方法:

void write(int b):写入一个字节的数据

void write(byte[] buffer):将数组buffer的数据写入流

void write(byte[] buffer,int offset,int len):从buffer[offset]开始,写入len个字节的数据

void flush():强制将buffer内的数据写入流

void close():关闭流

InputStream提供的方法:

int read():读出一个字节的数据,如果已达文件的末端,返回值为-1

int read(byte[] buffer):读出buffer大小的数据,返回值为实际所读出的字节数

int read(byte[] buffer,int offset,int len)

int available():返回流内可供读取的字节数目

long skip(long n):跳过n个字节的数据,返回值为实际所跳过的数据数

void close():关闭流

2.字符流,继承于InputStreamReader \ OutputStreamWriter。

字符流的类:1),BufferedReader是一种过滤器(filter)(extends FilterReader)。过滤

器用来将流的数据加以处理再输出。构造函数为:

BufferedReader(Reader in):生成一个缓冲的字符输入流,in为一个读取器

BufferedReader(Reader in,int size):生成一个缓冲的字符输入流,并指定缓冲区的大小为size

public class IOStreamDemo {

public void samples() throws IOException { //1. 这是从键盘读入一行数据,返回的是一个字符串

BufferedReader stdin =new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter a line:");

System.out.println(stdin.readLine());

//2. 这是从文件中逐行读入数据

BufferedReader in = new BufferedReader(new FileReader("IOStreamDemo.java"));

String s, s2 = new String();

while((s = in.readLine())!= null)

s2 += s + "\n";

in.close();

//3. 这是从一个字符串中逐个读入字节

StringReader in1 = new StringReader(s2);

int c;

while((c = in1.read()) != -1)

System.out.print((char)c);

//4. 这是将一个字符串写入文件

try {

BufferedReader in2 = new BufferedReader(new StringReader(s2));

PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

int lineCount = 1;

while((s = in2.readLine()) != null )

out1.println(lineCount++ + ": " + s);

out1.close();

} catch(EOFException e) {

System.err.println("End of stream");

}

} }

对于上面的例子,需要说明的有以下几点:

1. InputStreamReader是InputStream和Reader之间的桥梁,由于System.in是字节流,需要用它来包装之后变为字符流供给BufferedReader使用。

3. PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

这句话体现了Java输入输出系统的一个特点,为了达到某个目的,需要包装好几层。首先,输出目的地是文件IODemo.out,所以最内层包装的是FileWriter,建立一个输出文件流,接下来,我们希望这个流是缓冲的,所以用BufferedWriter来包装它以达到目的,最后,我们需要格式化输出结果,于是将PrintWriter包在最外层。

Java流有着另一个重要的用途,那就是利用对象流对对象进行序列化。

在一个程序运行的时候,其中的变量数据是保存在内存中的,一旦程序结束这些数据将不会被保存,一种解决的办法是将数据写入文件,而Java中提供了一种机制,它可以将程序中的对象写入文件,之后再从文件中把对象读出来重新建立。这就是所谓的对象序列化。Java中引入它主要是为了RMI(Remote

Method Invocation)和Java Bean所用,不过在平时应用中,它也是很有用的一种技术。

java8中的字符串的用法

1.

首先String不属于8种基本数据类型,String是一个对象。

因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

2.

new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;

3.

String str=”kvill”;

String

str=new String (“kvill”);的区别:

在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。

常量池(constant

pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。

看例1:

String

s0=”kvill”;

String

s1=”kvill”;

String

s2=”kv” + “ill”;

System.out.println(

s0==s1 );

System.out.println(

s0==s2 );

结果为:

true

true

首先,我们要知道Java会确保一个字符串常量只有一个拷贝。

因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中

”kvill”的一个引用。

所以我们得出s0==s1==s2;

用new

String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

看例2:

String

s0=”kvill”;

String

s1=new String(”kvill”);

String

s2=”kv” + new String(“ill”);

System.out.println(

s0==s1 );

System.out.println(

s0==s2 );

System.out.println(

s1==s2 );

结果为:

false

false

false

例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new

String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。

4.

String.intern():

再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了

例3:

String

s0= “kvill”;

String

s1=new String(”kvill”);

String

s2=new String(“kvill”);

System.out.println(

s0==s1 );

System.out.println(

“**********” );

s1.intern();

s2=s2.intern();

//把常量池中“kvill”的引用赋给s2

System.out.println(

s0==s1);

System.out.println(

s0==s1.intern() );

System.out.println(

s0==s2 );

结果为:

false

**********

false

//虽然执行了s1.intern(),但它的返回值没有赋给s1

true

//说明s1.intern()返回的是常量池中”kvill”的引用

true

最后我再破除一个错误的理解:

有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的

String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:

看例4:

String

s1=new String("kvill");

String

s2=s1.intern();

System.out.println(

s1==s1.intern() );

System.out.println(

s1+" "+s2 );

System.out.println(

s2==s1.intern() );

结果:

false

kvill

kvill

true

在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。

s1==s1.intern()为false说明原来的“kvill”仍然存在;

s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。

5.

关于equals()和==:

这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

6.

关于String是不可变的

这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String

str=”kv”+”ill”+” “+”ans”;

就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和”

“ 生成 ”kvill “存在内存中,最后又和生成了”kvill

ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。

java8有字符串流吗的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、java8有字符串流吗的信息别忘了在本站进行查找喔。

The End

发布于:2022-12-14,除非注明,否则均为首码项目网原创文章,转载请注明出处。