Java---IO加强(3)-IO流的操作规律

简介: Java---IO加强(3)-IO流的操作规律

一般写关于操作文件的读取的几个通用步骤!!!

1、明确源和目的。


源:InputStream Reader 一定是被读取的。

目的:OutputStream Writer 一定是被写入的。


2、处理的数据是否是纯文本的数据?


是:使用字符流。Reader Writer

否:使用字节流。 InputStream OutputStream


到这里,两个明确确定完,就可以确定出要使用哪个体系。接下来,就应该明确具体这个体系要使用哪个具体的对象。(看顶层)


3、明确数据所在的设备。


到这里,具体使用哪个对象就可以明确了。(用底层)


4、明确是否需要额外功能?


另外:如果数据有规律,并且源和目的都是file,需要随机访问时,可以使用RandomAccessFile工具类。


★ 明确数据所在的设备:

源设备:

键盘(System.in)

硬盘(FileXXX)FileReader FileInputStream

内存(数组)ByteArrayInputStream CharArrayReader StringReader

网络(Socket)

目的设备:

显示器(控制台System.out)

硬盘(FileXXX)FileWriter FileOutputStream

内存(数组)ByteArrayOutputStream CharArrayWriter StringWriter

网络(Socket)


★ 明确是否需要额外功能?

1) 是否需要高效?缓冲区Buffered (字符与字节各两个)。

2) 是否需要转换?转换流 InputStreamReader OutputStreamWriter

3) 是否操作基本数据类型? DataInputStream DataOutputStream

4) 是否操作对象(对象序列化)? ObjectInputStream ObjectOutputStream

5) 需要对多个源合并吗? SequenceInputStream

6) 需要保证数据的表现形式到目的地吗? PrintStream 或 PrintWriter


IO流的操作规律之设计方案练习需求1:复制一个文本文件。


1、明确源和目的。


源:InputStream Reader

目的:OutputStream Writer


2、处理的数据是否是纯文本的数据?


源:Reader

目的:Writer


3、明确数据所在的设备。


源:file(硬盘)

目的:file(硬盘)


4、明确是否需要额外功能?


BufferedReader bufr = new BufferedReader(new FileReader(“a.txt”));

BufferedWriter bufw = new BufferedWriter(new FileWriter(“b.txt”));


IO流的操作规律之设计方案练习需求2:复制一个图片文件。

1、明确源和目的。


源:InputStream Reader

目的:OutputStream Writer


2、处理的数据是否是纯文本的数据?


源:InputStream

目的:OutputStream


3、明确数据所在的设备。


源:file(硬盘) FileInputStream fin = new FileInputStream(“1.jpg”);

目的:file(硬盘) FileOutputStream fout = new FileOutputStrema(“2.jpg”);


4、明确是否需要额外功能?


BufferedInputStream bufin = new BufferedInputStream( fin );

BufferedOutputStream bufout = new BufferedOutputStream( fout );


IO流的操作规律之设计方案练习需求3:读取键盘录入,存储到一个文件中。

1、明确源和目的。


源:InputStream Reader

目的:OutputStream Writer


2、处理的数据是否是纯文本的数据?


源:Reader

目的:Writer


3、明确数据所在的设备。


源:键盘 InputStream in = System.in;

目的:硬盘 FileWriter fw = new FileWriter(“a.txt”);


4、明确是否需要额外功能?

(必须要将键盘录入的字节转成字符。

需要将字节–>字符的转换流。InputStreamReader

还想需要高效。)

InputStreamReader isr = new InputStreamReader(System.in);

FileWriter fw = new FileWriter(“a.txt”);

BufferedReader bufr = new BufferedReader( isr);

BufferedWriter bufw = new BufferedWriter( fw );


IO流的操作规律之设计方案练习需求4:读取一个文本文件,显示到显示器上。

1、明确源和目的。


源:InputStream Reader

目的:OutputStream Writer


2、处理的数据是否是纯文本的数据?


源:Reader

目的:Writer


3、明确数据所在的设备。


源:硬盘 FileReader fr = new FileReader(“a.txt”);

目的:显示器 OutputStream out = System.out;


4、明确是否需要额外功能?

(要将字符数据转换成字节输出。

输出转换流:OutputStreamWriter

还想需要高效。)


FileReader fr = new FileReader(“a.txt”);

OutputStreamWriter osw = new OutputStreamWriter(System.out);


BufferedReader bufr = new BufferedReader( fr);

BufferedWriter bufw = new BufferedWriter( osw );


IO流的操作规律之设计方案练习需求5:读取一个文本文件,将文本按照指定的编码表UTF-8写入到另一个文件中。


1、明确源和目的。


源:InputStream Reader

目的:OutputStream Writer


2、处理的数据是否是纯文本的数据?


源:Reader

目的:Writer


3、明确数据所在的设备。


源:硬盘 FileReader fr = new FileReader(“a.txt”);

目的:硬盘 FileOutputStream fout = new FileOutputStream(“b.txt”);


4、明确是否需要额外功能?

(假定输出时要为字符数据指定编码表。转换流中的参数需要字节流,因此用FileOutputStream。

转换流:OutputStreamWriter,还想需要高效。)


FileReader fr = new FileReader(“a.txt”);

OutputStreamWriter osw = new OutputStreamWriter(fout,”utf-8”);


BufferedReader bufr = new BufferedReader( fr);

BufferedWriter bufw = new BufferedWriter( osw );


常见的编码表


ASCII:美国标准信息交换码。

用一个字节的7位可以表示。

ISO8859-1:拉丁码表。欧洲码表

用一个字节的8位表示。

GB2312:中国的中文编码表。

GBK:中国的中文编码表升级,融合了更多的中文文字符号。

Unicode:国际标准码,融合了多种文字。

所有文字都用两个字节来表示,Java语言使用的就是unicode

UTF-8:一种变长的unicode码的实现方式,由1~4个字节表示。


★转换流的编码应用


可以将字符以指定编码格式存储。

可以对文本数据指定编码格式来解读。

指定编码表的动作由构造函数完成。


★字符编码


编码:字符串字节数组

解码:字节数组字符串


Unicode和UTF-8的关系


★ Unicode


世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。

Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。


★ UTF-8


UTF-8是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。UTF-8是Unicode的实现方式之一。


★ UTF-8的编码格式

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。


UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

   Unicode符号范围      |    UTF-8编码方式 
        (十六进制)             |      (二进制) 
-------------------------------+---------------------------------- 
0000 0000-0000 007F  |  0xxxxxxx 
0000 0080-0000 07FF  |  110xxxxx 10xxxxxx 
0000 0800-0000 FFFF  |  1110xxxx 10xxxxxx 10xxxxxx 
0001 0000-0010 FFFF  |  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
package unicode;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
 * 
 * @author 陈浩翔
 *
 * @version 1.0  2016-4-28
 */
public class StringEncoding {
    public static void main(String[] args) throws IOException {
        //先演示正常的编码解码-----编码表和解码表必须一致,否则会乱码。----还有个前提,码表中必须要有你给的相应字符
        //只有gb2312,gbk和utf-8三个码表中才有中文,因此对我们来讲,只有用这3个表编码,才能处理中文
        String str = "湖南城市";
        byte buf[] = str.getBytes("utf-8");//编码---编码表是utf-8
        //printBytes( buf );
        String s = new String(buf,"gbk");//解码---解码表是gbk
        System.out.println(s);
        //※编码编错必挂,解码解错可以补救!
        //编码编错必挂
        /*
        String str = "湖南城市";
        byte buf[] = str.getBytes("iso8859-1");//编码---编错码了,必挂----因为iso8859-1这个码表中根本就没有中文,因此编出来的码肯定是错的
        printBytes( buf );
        */
        //解码解错可以补救!----中文乱码解决技术
        demo();
    }
    private static void demo() throws IOException {
        //应用场景: 浏览器中网页(中文数据,字节数组的形式buf[]) --io-->  server (Tomcat,iso8859-1) 
        //--->Tomcat会把我们的buf[]用iso8859-1解码成字符串str(其实是用错码表的解码结果),然后把str通过传参传递到我们写的程序(servlet)中来
        //因此,我们程序中拿到的str是乱码,由此我们需要把 str恢复成真实的中文数据----该过程就叫中文乱码解决
        //1浏览器
        String str1 = "湖南城院";
        byte buf1[] = str1.getBytes();//用系统默认的编码---GBK或UTF-8
        //2Tomcat
        String str2 = new String(buf1,"iso8859-1");//解错码
        System.out.println("Tomcat解码后的数据:"+str2);
        Tomcat把str2通过传参传给MyServlet
        //3MyServlet---解决乱码
        byte buf2[] = str2.getBytes("iso8859-1");//反查---编码
        String str = new String(buf2);//用系统默认的码表解码
        System.out.println("MyServlet解决筹码之后:"+str);
    }
    private static void printBytes(byte[] buf) {
        for(byte b: buf){
            System.out.print(b+" ");
        }
        System.out.println();
    }
}

//看看大部分汉字在UTF-8中的占有的字节数

package unicode;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
 * 
 * @author 陈浩翔
 *
 * @version 1.0  2016-4-28
 */
public class UnicodeDemo1 {
    public static void main(String[] args) throws IOException {
        String str = "湖南城市";
        byte buf[] = str.getBytes("utf-8");
        printBytes( buf );
    }
    private static void printBytes(byte[] buf) {
        for(byte b: buf){
            System.out.print(b+" ");
        }
        System.out.println();
    }
}

输出结果:

-26 -71 -106 -27 -115 -105 -27 -97 -114 -27 -72 -126
目录
相关文章
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
3月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
20天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
13天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
2月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
28 2
|
2月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
2月前
|
Java
"揭秘Java IO三大模式:BIO、NIO、AIO背后的秘密!为何AIO成为高并发时代的宠儿,你的选择对了吗?"
【8月更文挑战第19天】在Java的IO编程中,BIO、NIO与AIO代表了三种不同的IO处理机制。BIO采用同步阻塞模型,每个连接需单独线程处理,适用于连接少且稳定的场景。NIO引入了非阻塞性质,利用Channel、Buffer与Selector实现多路复用,提升了效率与吞吐量。AIO则是真正的异步IO,在JDK 7中引入,通过回调或Future机制在IO操作完成后通知应用,适合高并发场景。选择合适的模型对构建高效网络应用至关重要。
39 2
|
2月前
|
Java Android开发
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
152 1
|
2月前
|
存储 缓存 Java
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
15 Java IO流(File类+IO流+字节流+字符流+字节编码)
44 3
下一篇
无影云桌面