java.ByteArrayInputStream与ByteArrayOutputStream

问题描述

转载]转:关于java文件读写、字节流、字符流的一点新得一.转载网址:http://my.oschina.net/u/232879/blog/155440关于编码方式我们不讲,有兴趣自己去看,这里大概提一下。UTF-16采用等幅编码,即每个字符占2个字节。优点:简单;缺点:西文会膨胀到200%,冗余!而且字与字之间的疆界不好找,容易划分错误,没有考虑好前缀问题。这一点huffman编码做的很好。UTF-8为不等幅编码,有1到3个字节的不等长度。优点:由于采用了很好的前缀,不会出现字之间疆界不好找和划分错误的情况。缺点:中日韩等文字膨胀到150%,冗余。现在主要说一下字节流、字符流的区别,顾名思义字节流是以字节为单位读取数据的,而字符流是以字符为单位读取的。我们都知道java采用了两种I/O读写方式主要有两个超类系:一个是inputstream和outputstream字节流类系;另一个是Reader和Writer字符流类系。使用他们来读写文本文件时有些要注意的问题:1、使用inputstream类的子类读取的单位为字节,对于英语字母(只占一个字节)不受任何影响,而中文文字在unicode编码为两个字节(或者以上?),在读取中一个中文文字会被划分为两个(或多个)字节,因而受到影响。如果将读取到的字节保存在byte[]数组中,为了正确地处理字节到字符的转化应注意如下问题:对byte[]数组采用toString的方法转化为字符,会导致错误的分割方式生成字符,不能正确地显示字符;而采用String的构造函数String(byte[]b)可以正确的分割构造字符。(或者String(byte[]b,Charseta)带编码方式的构造函数,在知道要读入的文本的编码方式的情况下。)2、使用Reader类的子类读取的单位为字符,即中文、英文都为两个字节大小,故而都不受影响。如果将读取到的每一个字符保存到一个字符数组char[]a中问题又来了:(特别注意!!!)如对字符数组char[]使用toString()函数时同样会遇到错误的分隔,建议使用String类的构造函数String(char[]c)来构造正确的字符划分。当然有更简便的方法:如果你采用的读取函数是readline()当然不存在如上字符转换的问题(请注意在InputStream类系的子类中是不存在类似readline()这样的函数的,只有read()这样的函数)。StringBuffer就像一个动态数组一样,我可以保存任意长的char字符,需要时只需将他们读取出来就行了。在这里我们将读到的每一个byte转化为一个char保存在StringBuffer中,需要时将他们读出再转化为byte,此过程数据不会溢出,精度不会受到损失。另外好像对转义字符’’,String类的split(Stringa)函数出现了问题,这是怎么回事?java本身的bug吗?当一个带完整文件夹路径的文件名,传给File类的mkdir(StringFilePathAndName)函数时一定要小心,如果该文件名中包含的文件路径不存在(或者说还未被创建的)的话,直接用此函数创建文件是会出错的,你需要先一层层的创建好这些路径方可创建该路径下的文件。(创建路径和文件其实是一个函数,本质上也没有什么区别!^_^)下面是我写的测试程序,代码如下。importjava.io.BufferedInputStream;importjava.io.BufferedOutputStream;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;importjava.io.UnsupportedEncodingException;importjava.nio.CharBuffer;publicclassFileReaderWriter{publicFileReaderWriter(){}publicStringreader(Stringfullpath)throwsFileNotFoundException//用readline的方式读取文件内容{try{Stringcontent="";Filefile=newFile(fullpath);if(file.exists()){System.out.println("FILE:"+fullpath+"EXIST,NowIwillreadit!");FileReaderfr=newFileReader(file);BufferedReaderbr=newBufferedReader(fr);try{System.out.println("-----------Nowiscontentoffile(Reading):----------");intn=0;for(;;){n++;Stringtemp=br.readLine();System.out.println("Line"+n+":");System.out.println(temp);content+=temp;if(temp==null){System.out.println("----------OVER---------");br.close();break;}}}catch(IOExceptionex){ex.printStackTrace();}}else{System.out.println("FILE:"+fullpath+"isNotEXIST"+"nowIwilldonothingbutexit");}returncontent;}catch(FileNotFoundExceptionex){ex.printStackTrace();}returnnull;}publicvoidwriter(Stringfullpath,Stringcontent){Filef=newFile(fullpath);if(!f.exists()){System.out.println("Fileisnotexist!NowIwillcreateit!");createfile(fullpath);//f.mkdir();//带有目录时这样创建是不行的}FileWriterfw;try{fw=newFileWriter(f);BufferedWriterbw=newBufferedWriter(fw);System.out.println("IamWritingNow!");bw.write(content);bw.close();System.out.println("-----------WritingContent:---------");System.out.println(content);System.out.println("------------WritingComplete!-------------");}catch(IOExceptionex){ex.printStackTrace();}}publicstaticvoidmain(String[]args){FileReaderWriterfrw=newFileReaderWriter();//做一下各种文件路径的测试^_^//Stringpath="info.txt";//Stringpath2="stream.txt";//Stringpath="d:try1/12info.txt";//Stringpath2="d:try21/2/3stream.txt";//Stringpath2="4/2/3stream.txt";Stringpath="12info.txt";Stringpath2="1/2/stream.txt";Stringtest="";Stringtext1="Hello,MynameisGuiZhiPengn";Stringtext2="我的名字是桂志鹏n";Stringtext3="IcomeFromChina!NowI'mStudyinginWuHanUniversityofHuBeiProvince.n";Stringtext4="我来自中国,现在湖北省的武汉大学读书";test=text1+text2+text3+text4;frw.writer(path,test);try{frw.reader(path);}catch(FileNotFoundExceptionex){ex.printStackTrace();}frw.outputstream(path2,test);frw.inputstream(path2);//frw.inputstream("LoginEndpoint.wsdl");}publicStringreaderbycharacter(Stringfullpath)throwsIOException//试图通过一个字节一个字节(或者一个字符一个字符)的读取方式读出流后恢复字符编码,{Stringcontent="";Filef=newFile(fullpath);FileReaderfr;intin;try{fr=newFileReader(f);BufferedReaderbr=newBufferedReader(fr);StringBuffersb=newStringBuffer();//byte[]save=newbyte[1000];//char[]save=newchar[1000];intnum=0;do{in=br.read();if(in!=-1){byteb=(byte)in;//强制转化会出现问题(有中文时,将char转化为byte损失位数,将使中文显示有问题)charc=(char)in;sb.append(c);System.out.println(c);System.out.println(b);System.out.println((char)b);//save[num++]=b;num++;}}while(in!=-1);br.close();System.out.println("NUM:"+num);System.out.println("CHARNum:"+sb.length());//content=newString(save);content=sb.toString();//content=newString(t);//content=t.toString();System.out.println(content);writer("test.txt",content);}catch(FileNotFoundExceptionex){ex.printStackTrace();}returncontent;}publicStringinputstream(Stringfullpath){Filef=newFile(fullpath);intinbyte=0;Stringcontent="";StringBuffersb=newStringBuffer();intnum=0;try{FileInputStreamfin=newFileInputStream(f);BufferedInputStreambin=newBufferedInputStream(fin);do{try{inbyte=bin.read();}catch(IOExceptionex){ex.printStackTrace();}if(inbyte!=-1){sb.append((char)inbyte);//System.out.println((char)inbyte);num++;}}while(inbyte!=-1);try{bin.close();}catch(IOExceptionex){ex.printStackTrace();}System.out.println("Num:"+num);byte[]save=newbyte[num];for(inti=0;i{save[i]=(byte)sb.charAt(i);}content=newString(save);System.out.println(content);System.out.println("Readingstreamsuccess!");}catch(FileNotFoundExceptionex){ex.printStackTrace();}returncontent;}publicvoidoutputstream(Stringfullpath,Stringcontent){Filef=newFile(fullpath);if(!f.exists()){System.out.println("Fileisnotexist!NowIwillcreateit!");createfile(fullpath);//f.mkdir();//fullpath中带有目录时这样创建方式是不行的}intinbyte=0;try{FileOutputStreamfout=newFileOutputStream(f);BufferedOutputStreambout=newBufferedOutputStream(fout);try{bout.write(content.getBytes());}catch(IOExceptionex){ex.printStackTrace();}try{bout.close();}catch(IOExceptionex){ex.printStackTrace();}System.out.println("WritingStreamSuccess!");}catch(FileNotFoundExceptionex){ex.printStackTrace();}}publicvoidcreatefile(Stringfullpath){System.out.println("---------InCreateFileFouction---------");String[]paths=null;Stringpropath=null;Filef;inti;if(fullpath.indexOf("")!=-1){System.out.println("?????");//paths=fullpath.split("");此函数执行有问题:java.util.regex.PatternSyntaxException:Unexpectedinternalerrornearindex1fullpath=fullpath.replace('','/');}if(fullpath.indexOf("/")!=-1){System.out.println("!!!!!");paths=fullpath.split("/");}//if(paths[0].indexOf(":")!=-1)if(paths!=null){for(i=0;i{if(propath!=null)propath=propath+"/"+paths[i];elsepropath=paths[0];f=newFile(propath);if(!f.exists())f.mkdir();}}else{f=newFile(fullpath);}}}后记:一位朋友对我的文章给出了很好的答案^_^顶了,谢谢当操作的对象不需要关心编码问题时应该使用InputStream/OutputStream系列的类。例如读取二进制文件(EXE等)。当需要关心编码问题时应该使用Reader/Writer系列的类。String.split()的参数是正则表达式。所以想以分割字符串的话应该这样:str.("");二.简单的代码分析PrintWriterclassMySendCommondThreadextendsThread{privateStringcommond;publicMySendCommondThread(Stringcommond){this.commond=commond;}publicvoidrun(){//实例化Sockettry{Socketsocket=newSocket(serverUrl,serverPort);PrintWriterout=newPrintWriter(socket.getOutputStream());out.println(commond);out.flush();}catch(UnknownHostExceptione){}catch(IOExceptione){}}}1.android手册publicPrintWriter(OutputStreamout)ConstructsanewPrintWriterwithoutasitstargetstream.Bydefault,thenewprintwriterdoesnotautomaticallyflushitscontentstothetargetstreamwhenanewlineisencountered.Parametersoutthetargetoutputstream2.分析这里使用的是PrintWriter的out构造函数,这个构造函数的唯一参数是OutputStream,在这个实例中是sockt.getOutPutStream(),即将字符流写入到socket的输出流中。然后在PrintWriter实例化对象out中,调用了println(Stringstr)方法即out.println(commond),也就是实现将commond换行显示出来。在使用out的构造函数中,由于不能像publicPrintWriter(OutputStreamout,booleanautoFlush)一样将缓冲区的数据挤出,因此需要用到out.flush()方法将缓冲区的数据手动挤出。

时间: 2024-11-10 00:15:19

java.ByteArrayInputStream与ByteArrayOutputStream的相关文章

Java IO流学习总结六:ByteArrayInputStream、ByteArrayOutputStream

Java IO流学习总结六:ByteArrayInputStream.ByteArrayOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54946762 本文出自[赵彦军的博客] 类的继承关系 InputStream |__ ByteArrayInputStream OutputStream |__ ByteArrayOutputStream ByteArrayInputStream 可以将字节数组转化为

Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重复读取配置文件的方法_java

ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区,然后利用ByteArrayOutputStream和ByteArrayInputStream的实例向数组中写入或读出byte型数据.在网络传输中我们往往要传输很多变量,我们可以利用ByteArrayOutputStream把所有的变量收集到一起,然后一次性把数据发送出去.具体用法如下: ByteArrayOutputStream:    可以捕获内存缓冲区的数据,转换成字节数组. ByteA

Java IO--内存操作流ByteArrayInputStream/ByteArrayOutputStream

ByteArrayInputStream和ByteArrayOutputStream 此时操作的时候,应该以内存为操作点. 利用其完成一个大小写转换的程序: import java.io.* ; public class ByteArrayDemo01{ public static void main(String args[]){ String str = "HELLOWORLD" ; // 定义一个字符串,全部由大写字母组成 ByteArrayInputStream bis = n

【转】Java I/O流概念分析整理

转载地址:http://blog.csdn.net/yuebinghaoyuan/article/details/7388059  Java中的流,可以从不同的角度进行分类. 按照数据流的方向不同可以分为:输入流和输出流. 按照处理数据单位不同可以分为:字节流和字符流. 按照实现功能不同可以分为:节点流和处理流. 输出流: 输入流: 因此输入和输出都是从程序的角度来说的. 字节流:一次读入或读出是8位二进制. 字符流:一次读入或读出是16位二进制. 字节流和字符流的原理是相同的,只不过处理的单位

Java中文问题及最优解决方法

解决|问题|中文 1.中文问题的来源 计算机最初的操作系统支持的编码是单字节的字符编码,于是,在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理.随着计算机的发展,为了适应世界其它民族的语言(当然包括我们的汉字),人们提出了UNICODE编码,它采用双字节编码,兼容英文字符和其它民族的双字节字符编码,所以,目前,大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持

java中文解决大全(下)

解决|中文 4.中文问题的分类及其建议最优解决办法     了解以上JAVA处理文件的原理之后,我们就可以提出了一套建议最优的解决汉字问题的办法.    我们的目标是:我们在中文系统中编辑的含有中文字符串或进行中文处理的JAVA源程序经编译后可以移值到任何其它的操作系统中正确运行,或拿到其它操作系统中编译后能正确运行,能正确地传递中文和英文参数,能正确地和数据库交流中英文字符串.    我们的具体思路是:在JAVA程序转码的入口和出口及JAVA程序同用户有输入输出转换的地方限制编码方法使之正确即

第四讲 Java的例外处理和I/O流

[课前思考] 1. 什么是例外?Java中有哪两种例外处理机制? 2. 字节流和字符流的基类各是什么? 3. 什么是对象的串行化?对象串行化的作用是什么? 难点: 1.如何使用Java中两种例外处理机制,抛弃例外和声明抛弃例外的区别与联系. 2.处理字符流时,其构造方法的参数是一个字节流. 3.对象串行化的概念.4.1 什么是例外 4.1.2 例外处理机制 抛弃(throw)例外: 在Java程序的执行过程中,如果出现了异常事件,就会生成一个例外对象.生成的例外对象将传递给Java运行时系统,这

Java面试笔试题大汇总(最全+详细答案)

声明:有人说, 有些面试题很变态,个人认为其实是因为我们基础不扎实或者没有深入.本篇文章来自一位很资深的前辈对于最近java面试题目所做的总结归纳,有170道题目 ,知识面很广 ,而且这位前辈对于每个题都自己测试给出了答案 ,如果你对某个题有疑问或者不明白,可以电脑端登录把题目复制下来然后发表评论,大家一起探讨,也可以电脑端登录后关注我给我发私信,我们一起进步! 以下内容来自这位前辈 2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅读了以后发现里面的很多题

【转】Java知识点集锦(1~40)

1. 面向对象的特征有哪些方面? 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么. 继承:继承是从已有类得到继承信息创建新类的过程.提供继承信息的类被称为父类(超类.基类):得到继承信息的类被称为子类(派生类).继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段(如果不能理解请阅读阎宏博士的<Java与模式>或<设计模式精解>中关于桥梁模式的部分). 封装