主要内容

1.编码问题

2.File类的使用

3.RandomAccessFile的使用

4.I/O 输入输出流

编码问题:

1 importjava.io.UnsupportedEncodingException;2

3 public class编码问题 {4 public static voidmain(String[] args) {5 //我们项目的默认编码是GBK

6 String s = "测试 ABC";7 byte[] byte1 = s.getBytes();//转换成的字节序列用的是项目默认的编码gbk

8 for (byteb : byte1) {9 //1 byte = 8 位//toHexString这个函数是把字节(转换成了Int)以16进制的方式显示

10 System.out.print(Integer.toHexString(b & 0xff) + " ");//&11 //0xff是为了把前面的24个0去掉只留下后八位

12 }13

14 try{15 //也可以转换成指定的编码

16 byte[] bytes1 = s.getBytes("gbk");17 System.out.println(newString(bytes1));18 } catch(UnsupportedEncodingException e) {19 //TODO Auto-generated catch block

20 e.printStackTrace();21 }22 /**

23 * gbk编码: 中文占用两个字节,英文占用一个字节 utf-8编码:中文占用三个字节,英文占用一个字节24 * java是双字节编码,是utf-16be编码 utf-16be编码:中文占用两个字节,英文占用两个字节25 * 当你的字节序列是某种编码时,这个时候想把字节序列变成字符串,也需要用这种编码方式,否则会出现乱码26 */

27 try{28 byte[] byte2 = s.getBytes("utf-16be");29 String s2 = new String(byte2, "utf-16be");30 System.out.println(s2);31 } catch(UnsupportedEncodingException e) {32 //TODO Auto-generated catch block

33 e.printStackTrace();34 }35 /**

36 * 文本文件就是字节序列,可以是任意编码的字节序列37 * 如果我们在中文机器上直接创建文本文件,那么该文件只认识ANSI编码(例如直接在电脑中创建文本文件)38 */

39

40 /**

41 * byte转int的时候为什么非要先&0xff计算出来才是正确答案?42 * 首先,java中的二进制采用的是补码形式,并非原码或反码,这3个概念要搞清楚;43 * 其次,byte占8位,int占32位,将byte强制转换为int型时,如果没有做 &44 * 0xff运算,且byte对应的值为负数的话,就会对高位3个字节进行补位,这样就有可能出现补位误差的错误。45 * 举例来说,byte型的-1,其二进制(补码)为11111111(即0xff),转换成int型,值也应该为-1,但经过补位后,46 * 得到的二进制为11111111111111111111111111111111(即0xffffffff),这就不是-1了,对吧?47 * 而0xff默认是int型,所以,一个byte跟0xff相与,会先将那个byte转化成int型运算,这样,结果中的高位3个字节就总会被清0,48 * 于是结果就是我们想要的了~49 */

50

51 }52

53 }

View Code

File类的使用:

JAVA.io.File类用于表示文件(目录)

File类只用于表示文件( 目录)的信息(名称、大小等),不能用于文件内容的访问

File类的常用API:

1.创建File对象:File file=new File(String path);注意:File.seperater();获取系统分隔符,如:”\“.

2.boolean file.exists();是否存在.

3.file.mkdir();或者file.mkdirs();创建目录或多级目录。

4.file.isDirectory()或者file.isFile()判断是否是目录或者是否是文件。

5.file.delete();删除文件或目录。

6.file.createNewFile();创建新文件。

7.file.getName()获取文件名称或目录绝对路径。

8.file.getAbsolutePath()获取绝对路径。

9.file.getParent();获取父级绝对路径。

10.file.getSize();获取文件大小。

11.file.getFormat();获取文件格式名。

1 importjava.io.File;2 importjava.io.IOException;3

4 public classFileDemo {5

6 /**

7 *@paramargs8 */

9 public static voidmain(String[] args) {10 //了解构造函数的情况 查帮助ALT+/

11 File file = new File("E:\\javaio\\imooc");12 //判断文件/文件夹是否存在13 //System.out.println(file.exists());

14 if (!file.exists())15 file.mkdir(); //file.mkdirs()如果文件不存在,直接创建文件夹16 //mkdir创建的一级目录,如果需要创建多级目录可以使用mkdirs()

17 else

18 file.delete();19

20 //是否是一个目录 如果是目录返回true,如果不是目录or目录不存在返回的是false

21 System.out.println(file.isDirectory());22 //是否是一个文件

23 System.out.println(file.isFile());24

25 //File file2 = new File("e:\\javaio\\日记1.txt");

26 File file2 = new File("e:\\javaio", "日记1.txt");27 if (!file2.exists())28 try{29 file2.createNewFile();30 } catch(IOException e) {31 //TODO Auto-generated catch block

32 e.printStackTrace();33 }34 else

35 file2.delete();36 //常用的File对象的API

37 System.out.println(file);//file.toString()的内容

38 System.out.println(file.getAbsolutePath());39 System.out.println(file.getName());40 System.out.println(file2.getName());41 System.out.println(file.getParent());42 System.out.println(file2.getParent());43 System.out.println(file.getParentFile().getAbsolutePath());44 }45

46 }

FileDemo

遍历目录

1 importjava.io.File;2 importjava.io.IOException;3

4 //列出File的一些常用操作比如过滤,遍历等操作

5 public classFileUtils {6 /**

7 * 列出指定指定目录下(包括其子目录)的所有文件8 *9 *@paramdir10 *@throwsIOException11 */

12 public static void listDirectory(File dir) throwsIOException {13 if (!dir.exists()) {14 throw new IllegalArgumentException("目录:" + dir + "不存在");15 }16 if (!dir.isDirectory()) {17 throw new IllegalArgumentException(dir + "不是目录");18 }19

20 //String[] fileNames =21 //dir.list();//返回的是字符串数组,list()方法用于列出当前目录下的子目录和文件,直接子的名称,不包含子目录下的内容22 //for (String string : fileNames) {23 //System.out.println(dir+"\\"+string);24 //}25 //

26 //如果要遍历子目录下的内容就需要构造成File对象做递归操作,File提供了直接返回File对象的API

27 File[] files = dir.listFiles();//返回的是直接子目录(文件)的抽象

28 if (files != null && files.length > 0) {//确定存在子目录

29 for(File file : files) {30 if(file.isDirectory()) {31 //递归

32 listDirectory(file);33 } else{34 System.out.println(file);35 }36 }37 }38 }39 }

FileUtils

RandomAccessFile的使用

RandomAccessFile JAVA提供的对文件内容的访问,既可以读文件,也可以写文件。

RandomAccessFile支持随机访问文件,可以访问文件的任意位置

(1)JAVA文件模型

在硬盘上的文件是byte byte byte存储的,是数据的集合

(2)打开文件

有两种模式"rw"(读写) "r"(只读)

RandomAccessFile raf = new RandomeAccessFile(file,"rw")

文件指针,打开文件时指针在开头 pointer = 0;

(3) 写方法

raf.write(int)--->只写一个字节(后8位),同时指针指向下一个位置,准备再次写入

提供和很多方法能够一次读写一个基本类型的数据

(4)读方法

int b = raf.read()--->读一个字节

(5)文件读写完成以后一定要关闭(Oracle官方说明)

1 importjava.io.File;2 importjava.io.IOException;3 importjava.io.RandomAccessFile;4 importjava.util.Arrays;5

6 public classRafDemo {7

8 /**

9 *@paramargs10 */

11 public static void main(String[] args) throwsIOException {12 File demo = new File("demo");13 if (!demo.exists())14 demo.mkdir();15 File file = new File(demo, "raf.dat");16 if (!file.exists())17 file.createNewFile();18

19 RandomAccessFile raf = new RandomAccessFile(file, "rw");20 //指针的位置

21 System.out.println(raf.getFilePointer());22

23 raf.write('A');//只写了一个字节

24 System.out.println(raf.getFilePointer());25 raf.write('B');26

27 int i = 0x7fffffff;28 //用write方法每次只能写一个字节,如果要把i写进去就得写4次

29 raf.write(i >>> 24);//高8位

30 raf.write(i >>> 16);31 raf.write(i >>> 8);32 raf.write(i);33 System.out.println(raf.getFilePointer());34

35 //可以直接写一个int

36 raf.writeInt(i);37

38 String s = "中";39 byte[] gbk = s.getBytes("gbk");40 raf.write(gbk);41 System.out.println(raf.length());42

43 //读文件,必须把指针移到头部

44 raf.seek(0);45 //一次性读取,把文件中的内容都读到字节数组中

46 byte[] buf = new byte[(int) raf.length()];47 raf.read(buf);48

49 System.out.println(Arrays.toString(buf));50 for (byteb : buf) {51 System.out.println(Integer.toHexString(b & 0xff) + " ");52 }53 raf.close();54 }55

56 }

RafDemo

importjava.io.IOException;importjava.io.RandomAccessFile;public classRafReadDemo {/***@paramargs*/

public static void main(String[] args) throwsIOException {//TODO Auto-generated method stub

RandomAccessFile raf = new RandomAccessFile("demo/raf.dat", "r");

raf.seek(2);int i = 0;int b = raf.read();//读取到一个字节

System.out.println(raf.getFilePointer());

i= i | (b << 24);

b=raf.read();

i= i | (b << 16);

b=raf.read();

i= i | (b << 8);

b=raf.read();

i= i |b;

System.out.println(Integer.toHexString(i));

raf.seek(2);

i=raf.readInt();

System.out.println(Integer.toHexString(i));

raf.close();

}

}

RafReadDemo

序列化与基本类型序列化

1)将类型int 转换成byte或将其他数据类型转换成byte的过程叫序列化

数据---->n byte

2)反序列化

将n个byte 转换成一个数据的过程

nbyte ---> 数据

3)RandomAccessFile提供基本类型的读写方法,可以将基本类型数据

序列化到文件或者将文件内容反序列化为数据

1 importjava.io.File;2 importjava.io.IOException;3 importjava.io.RandomAccessFile;4 public classRandomAccessFileSeriaDemo {5

6 /**

7 *@paramargs8 */

9 public static void main(String[] args) throwsIOException {10 //TODO Auto-generated method stub

11 File demo = new File("demo1");12 if (!demo.exists())13 demo.mkdir();14 File file = new File(demo, "raf.dat");15 if (!file.exists())16 file.createNewFile();17 //打开文件,进行随机读写

18 RandomAccessFile raf = new RandomAccessFile(file, "rw");19 /*序列化*/

20 int i = 0x7ffffff;21 raf.write(i >>> 24);22 raf.write(i >>> 16);23 raf.write(i >>> 8);24 raf.write(i);25 System.out.println(raf.getFilePointer());26

27 /*反序列化*/

28 raf.seek(0);29 int b =raf.read();30 i = i | (b << 24);31 b =raf.read();32 i = i | (b << 16);33 b =raf.read();34 i = i | (b << 8);35 b =raf.read();36 i = i |b;37 System.out.println(Integer.toHexString(i));38 raf.close();39 }40 }41

42 RandomAccessFileSeriaDemo

RandomAccessFileSeriaDemo

I/O 输入输出流

流的定义:

流就是程序和设备之间嫁接起来的一根用于数据传输的管道,这个管道上有很多按钮,不同的按钮可以实现不同的功能。

这根用于数据传输的管道就是流,流就是一根管道

输入时,程序在源(文件,网络,内存)上打开一个流,然后如图一个一个顺序读。写也一样。

流的分类和使用:

四大基本抽象流,文件流,缓冲流,转换流,数据流,Print流,Object流。

JAVA.io 包中定义了多个流类型(类或抽象类)来实现输入/输出功能;可以从不同角度对其进行分类:

*按数据流的方向不用可以分为输入流和输出流

*按处理数据单位不同可以分为字节流和字符流

*按照功能不同可以分为节点流和处理流

JAVA中所提供的的所有流类型位于包JAVA.io内,都分别继承自以下四种抽象流类型:

节点流与处理流:

节点流可以从一个特定的数据源(节点)读取数据(如:文件,内存)

处理流是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

节点流也叫原始流,处理流也叫包裹流。

流与类的关系:

如果一个类是用作设备和程序之间的数据传输,则这个类有一个新的名字叫做流

流一定是类,但类不一定是流

四大基本流的介绍

输入流,输出流,字节流,字符流

InputStream和OutputStream读写数据的单位是一个字节

Reader和Writer读写数据的单位是一个字符

在JAVA中一个字符占两个字节

InputStream,OutputStream,Reader,Writer都是抽象类,或者说都是抽象流,通常我们使用的都是它们的子类,凡是以Stream结尾的都是字节流。

InputStream 流中的常用方法:

OutputStream 流中的常用方法:

Reader 流中的常用方法:

Writer 流中的常用方法:

文件流

文件流包括:

FileInputStream FileOutputStream --字节流

FileReader FileWriter --字符流

实例:读取一个文件的内容并将其输出到显示器上,并统计读取的字节个数

1 /*

2 利用FileReader流来读取一个文件中的数据,并在显示器上输出!3 */

4

5 import java.io.*;6

7 public classTestFileReader {8 public static voidmain(String[] args) {9 FileReader fr = null;10

11 try{12 fr = new FileReader("C:\\Documents and Settings\\others\\桌面\\java\\TestFileReader.java");13 int cnt = 0;14 intch;15

16 while (-1 != (ch = fr.read())) //20行

17 {18 System.out.print((char) ch); //System.out.print(int ch);19 //这是在显示器上输出ch的整数值,所以必须的进行类型转化,我们需要输出的是ch所代表的整数对应的字符

20 ++cnt;21 }22

23 System.out.printf("总共从TestFileReader.java文件中读取了%d个字符", cnt);24 } catch(FileNotFoundException e) {25 System.out.println("找不到文件!");26 System.exit(-1);27 } catch(IOException e) {28 System.out.println("文件读取失败!");29 System.exit(-1);30 }31 }32 }

View Code

FileInputStream的使用

FileReader的使用

字节流与字符流的区别:

FileInputStream 和FileOutputStream 可以完成所有格式文件的复制

FileReader和FileWriter只可以完成文本文件的复制,却无法完成其他格式文件的复制

因为字节是不需要解码和编码的,将字节转化为字符才存在解码和编码的问题

字节流可以从所有格式的设备中读写数据,但字符流只能从文本格式的设备中读写数据

实例:编程实现文件的复制

1 /*

2 利用FileInputStream 和 FileOutputStream 可以完成所有格式文件的赋值3 因为字节是不需要解码和编码的,将字节转化为字符才存在解码的问题4 本程序完成了音频文件的复制5 */

6

7 import java.io.*;8

9 public classTestFileInputStreamOutputStreamCopy {10 public static voidmain(String[] args) {11 FileInputStream fi = null;12 FileOutputStream fo = null;13

14 try{15 fi = new FileInputStream("E:\\综艺\\歌曲\\卡农.mp3");16 fo = new FileOutputStream("d:/share/Output.txt"); //使用播放器可正常播放该文件

17 intch;18

19 while (-1 != (ch =fi.read())) {20 fo.write(ch);21 }22 } catch(FileNotFoundException e) {23 System.out.println("文件没有找到!");24 System.exit(-1);25 } catch(IOException e) {26 System.out.println("文件读写错误!");27 System.exit(-1);28 } finally{29 try{30 if (null !=fi) {31 fi.close();32 fi = null;33 }34 if (null !=fo) {35 fo.close();36 fo = null;37 }38 } catch(Exception e) {39 e.printStackTrace();40 System.exit(-1);41 }42 }43

44 System.out.println("文件复制成功!");45 }46 }

TestFileInputStreamOutputStreamCopy

1 /*

2 本程序证明了 FileReader 和 FileWriter 只可以完成文本文件的复制,3 却无法完成音频格式文件的复制4 */

5

6 import java.io.*;7

8 public classTestFileReaderWriterCopy {9 public static voidmain(String[] args) {10 FileReader fi = null;11 FileWriter fo = null;12

13 try{14 fi = new FileReader("E:\\综艺\\歌曲\\卡农.mp3");15 fo = new FileWriter("d:/share/Output.txt"); //Output.txt使用播放器打开失败!16 //本程序证明了FileWriter 和17 //FileReader18 //无法完成音频文件的复制,实际上FileWriter19 //和 FileReader20 //只能完成文本文件的复制

21 intch;22

23 while (-1 != (ch =fi.read())) {24 fo.write(ch);25 }26 } catch(FileNotFoundException e) {27 System.out.println("文件没有找到!");28 System.exit(-1);29 } catch(IOException e) {30 System.out.println("文件读写错误!");31 System.exit(-1);32 } finally{33 try{34 if (null !=fi) {35 fi.close();36 fi = null;37 }38 if (null !=fo) {39 fo.close();40 fo = null;41 }42 } catch(Exception e) {43 e.printStackTrace();44 System.exit(-1);45 }46 }47

48 System.out.println("文件复制成功!");49 }50 }

TestFileReaderWriterCopy

缓冲流

缓冲流就是带有缓冲区的输入输出流

缓冲流可以显著的减少我们对IO访问的次数,保护我们的硬盘

缓冲流本事就是处理流(包裹流),缓冲流必须得依附于节点流(原始流)

处理流包裹在原始节点流上的流,相当于包裹在管道上的管道

缓冲流要"套接"在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。JAVA提供了四种缓冲流,其常用的构造方法为:

BufferedOutputStream 和 BufferedInputStream

BufferedOutputStream :带有缓冲的输出流,允许一次向硬盘写入多个字节的数据。

BufferedInputStream:带缓冲的输入流,允许一次向程序中读入多个字节的数据。

BufferedOutputStream 和 BufferedInputStream都是包裹流,必须依附于OutputStream和InputStream

例子:利用BufferedOutputStream 和 BufferedInputStream 完成大容量文件的复制,这远比单纯利用FileInputStream和FileOutputStream要快的多

1 /*

2 利用BufferedOutputStream 和 BufferedInputStream完成大容量文件的复制3 这远比单纯利用 FileInputStream 和 FileOutputStream 要快得多4

5 BufferedOutputStream 和 BufferedInputStream 都是包裹流,必须的依附于6 InputStream 和 OutputStream7 */

8

9 import java.io.*;10

11 public classTestBufferedInputStreamOutputStreamCopy {12 public static voidmain(String[] args) {13 BufferedOutputStream bos = null;14 BufferedInputStream bis = null;15

16 try{17 bos = new BufferedOutputStream(new FileOutputStream("e:/OutputView.txt")); //bos18 //输出流有个默认的缓冲区,大小为32个字节

19

20 bis = new BufferedInputStream(new FileInputStream("c:\\[高清在线www.66ys.cn]海底总动员DVD中英字幕.rmvb")); //bis21 //输入流有个默认的缓冲区,大小为32个字节

22 byte[] buf = new byte[1024];23 int len = bis.read(buf, 0, 1024); //一定要注意,这不是从buf中读数据,而是从bis所关联到的D:\\综艺\\电影\\猫和老鼠\\CD4.rmvb文件中读取数据,并将读取的数据写入bis自己的默认缓冲区中,然后再将缓冲区的内容写入buf数组中,每次最多向buf数组中写入1024个字节,返回实际写入buf数组的字节个数,如果读到了文件的末尾,无法再向buf数组中写入数据,则返回-1

24 while (-1 !=len) {25 bos.write(buf, 0, len); //不是写入buf数组,而是将buf数组中下标从0开始的到len-1为止的所有数据写入bos所关联到的"d:/share/OutputView.txt"文件中

26 len = bis.read(buf); //bis.read(buf); 等价于 bis.read(buf, 0,27 //buf.length);

28 }29 bos.flush();30 bis.close();31 bos.close();32 } catch(FileNotFoundException e) {33 System.out.println("没有找到文件!");34 System.exit(-1);35 } catch(IOException e) {36 System.out.println("文件读写错误!");37 System.exit(-1);38 }39

40 System.out.println("文件复制成功!");41 }42 }

TestBufferedInputStreamOutputStreamCopy

1 /*

2 本程序读写速度要慢于 "TestBufferedInputStreamOutputStreamCopy.java" 程序3 即:4 利用BufferedOutputStream 和 BufferedInputStream完成大容量文件的复制5 这远比单纯利用 FileInputStream 和 FileOutputStream 要快得多6

7 BufferedOutputStream 和 BufferedInputStream 都是包裹流,必须的依附于8 OutputStream 和 OutputStream9 */

10

11 import java.io.*;12

13 public classTestBufferedInputStreamOutputStreamCopy_2 {14 public static voidmain(String[] args) {15 FileOutputStream bos = null;16 FileInputStream bis = null;17

18 try{19 bos = new FileOutputStream("e:/OutputView.txt");20 bis = new FileInputStream("c:\\[高清在线www.66ys.cn]海底总动员DVD中英字幕.rmvb");21

22 byte[] buf = new byte[1024];23 int len = bis.read(buf, 0, 1024);24 while (-1 !=len) {25 bos.write(buf, 0, len);26 len =bis.read(buf);27 }28 bos.flush();29 bis.close();30 bos.close();31 } catch(FileNotFoundException e) {32 System.out.println("没有找到文件!");33 System.exit(-1);34 } catch(IOException e) {35 System.out.println("文件读写错误!");36 System.exit(-1);37 }38

39 System.out.println("文件复制成功!");40 }41 }

TestBufferedInputStreamOutputStreamCopy_2

一定要注意,bis.read(buf,0,1024);这不是从buf中读数据,而是从bis所关联到的“D:\\综艺\\电影\\猫和老鼠\\CD4.rmvb”文件中读取数据,并将读取的数据写入bis自己的默认缓冲区中,然后再将缓冲区的内容写入buf数组中,每次最多向buf数组中写入1024个字节,返回实际写入buf数组的字节个数,如果读到了文件的末尾,无法再向buf数组中写入数据,则返回-1

BufferedInputStream流中有public int read(byte[] b)方法用来把从当前流关联到的设备中读取出来的数据存入一个byte数组中

BufferedOutputStream 流中有public int write(byte[] b)方法用来把byte数组中的数据输出来当前流所关联到的设备中

如果我们希望用BufferedInputStream 和 BufferedOutputStream 完成“将一个设备中的数据导入另一个设备中”,我们就应该定义一个临时的byte类型的数据,用这个临时数组作为输入流和输出流进行交互的中转枢纽。

BufferedReader 和 BufferedWriter

实例:利用BufferedReader 和 BufferedWriter完成文本文件的复制

1 /*

2 利用 BufferedReader 和 BufferedWriter 完成文本文件的复制3 */

4 import java.io.*;5

6 public classTestBufferedReaderWriterCopy {7 public static voidmain(String[] args) {8 BufferedReader br = null;9 BufferedWriter bw = null;10

11 try{12 br = newBufferedReader(13 new FileReader("C:\\Documents and Settings\\others\\桌面\\java\\TestBufferedReaderWriterCopy.java"));14 bw = new BufferedWriter(new FileWriter("d:/share/Writer.txt"));15 String str = null;16

17 while (null != (str = br.readLine())) //br.readLine()读取一行字符,但会将读取的换行符自动丢弃,即返回的String对象中并不包括换行符

18 {19 bw.write(str);20 bw.newLine(); //写入一个换行符 这行不能省

21 }22 bw.flush();23 } catch(FileNotFoundException e) {24 e.printStackTrace();25 System.exit(-1);26 } catch(IOException e) {27 e.printStackTrace();28 System.exit(-1);29 } finally{30 try{31 bw.close();32 br.close();33 } catch(IOException e) {34 e.printStackTrace();35 System.exit(-1);36 }37 }38 }39 }

TestBufferedReaderWriterCopy

数据流DataInputStream DataOutputStream

DataInputStream能够以一种与机器无关的方式,直接从底层字节输入流读取JAVA基本类型和String类型的数据。常用方法包括:

DataInputStream 是包裹流,必须依附于InputStream

DataOutputStream能够以一种机器无关的方式,直接将JAVA基本类型和String类型数据写出到其他的字节输出流。常用方法包括:

DataOutputStream 是包裹流,它必须依附于OutputStream

数据流实例:

编程实现将long类型数据写入byte数组,然后再从byte数组中吧该数据读出来{

*这是Socket编程中经常要完成的功能。

*因为网络编程中经常要把数据存入byte数组中,然后把byte数组打包成数据包(DatagramPacket),再把数据包经过网络传输到目的机,目的机再从byte数组中把原数值型数据还原回来。

}

本程序要使用到:

DataInputStream

DataOutputStream

ByteArrayInputStream

ByteArrayOutputStream

1 /*

2 功能:把一个long类型的数据写入byte数组中,然后再从byte数组中读取出3 这个long类型的数据4

5 因为网络编程中经常要把数值型数据存入byte数组中然后打包成6 DatagramPacket经过网络传输到目的机,目的机再从byte数组中7 把原数值型数据还原回来8

9 目的: ByteArrayOutputStream DataOutputStream ByteInputStream DataInputStream 流的使用10 记住: DataOutputStream流中的writeLong(long n)是把n变量在内存11 中的二进制代码写入该流所连接到的设备中12

13 注意:查API文档得知:14 构造 ByteArrayOutputStream 对象时不需要也不能指定缓冲数组,因为缓冲数组默认已经内置好了15 构造 ByteArrayInputStream 对象时必须的指定缓冲数组是谁!16 */

17

18 import java.io.*;19

20 public classTestByteArrayOutputStream121 {22 public static void main(String args[]) throwsException23 {24 long n = 9876543210L;25 ByteArrayOutputStream baos = new ByteArrayOutputStream(); //9行 API:"public ByteArrayOutputStream(): 创建一个新的 byte 数组输出流。缓冲区的容量最初是 32 字节,如有必要可增加其大小。 "26 //9行代码一旦执行完毕,意味着两点: 1、在内存中生成了一个大小为32个字节的byte数组 2、有一根叫做baos的管道已链接到了该byte数组中,并且可以通过这个管道向该byte数组中写入数据27 //虽然此时可以通过baos向baos所连接到的在内存中分配好的byte数组中写入数据,但是ByteArrayOutputStream流并没有提供可以直接把long类型数据直接写入ByteArrayOutputStream流所连接到的byte数组中的方法, 简单说我们没法通过baos向baos所连接到的byte数组中写入long类型的数据, 查API文档可以发现: ByteArrayOutputStream流中并没有类似writeLong()这样的方法,但是DataOutputStream流中却有writeLong() writeFloat()等方法

28 DataOutputStream dos = newDataOutputStream(baos);29

30 dos.writeLong(n); //把n变量所代表的10000L在内存中的二进制代码写入dos所依附的baos管道所连接到的内存中的大小为32字节的byte数组中,由运行结果来看,这是二进制写入,既不是把10000L转化为字符'1' '0' '0' '0' '0'写入byte数组中,而是把10000L在内存中的总共8个字节的二进制代码写入byte数组中

31

32 dos.flush();33 byte[] buf = baos.toByteArray(); //DataOutputStream 流中并没有toByteArray()方法,但是ByteArrayOutputStream 流中却有toByteArray()方法, 所以不可以把baos 改为dos,否则编译时会出错! ByteArrayOutputStream流中toByteArray()方法的含义,摘自API“创建一个新分配的 byte 数组。其大小是此输出流的当前大小,并且缓冲区的有效内容已复制到该数组中”34

35 //利用ByteArrayInputStream 和 DataInputStream 可以从byte数组中得到原long类型的数值10000L

36 ByteArrayInputStream bais = newByteArrayInputStream(buf);37 DataInputStream dis = newDataInputStream(bais);38 long l =dis.readLong();39

40 System.out.println("l = " +l);41 dos.close();42 }43 }44 /*

45 在JDK 1.6中的运行结果是:46 ----------------47 l = 987654321048 ----------------49 */

TestByteArrayOutputStream1

1 /*

2 功能:3 将long类型数据写入byte数组,然后在从byte数组中把该数据读出来4 */

5

6 import java.io.*;7

8 public classTestByteArrayOutputStream29 {10 public static void main(String[] args) throwsException11 {12 long n = 1234567;13 ByteArrayOutputStream baos = newByteArrayOutputStream();14 DataOutputStream dos = newDataOutputStream(baos);15 dos.writeLong(n);16

17 byte[] buf =baos.toByteArray();18 ByteArrayInputStream bis = newByteArrayInputStream(buf);19 DataInputStream dis = newDataInputStream(bis);20 long n2 =dis.readLong();21 System.out.println("n2 = " +n2);22

23 dos.close();24 dis.close();25 }26 }

TestByteArrayOutputStream2

转换流:OutputStreamWriter InputStreamReader

OutputStreamWriter 流是把OutputStream流 转化成Writer流的流

InputStreamReader 流是把InputStream流转化为Reader

OutputStreamWriter 和 InputStreamReader都是包裹流

实例:如何将键盘输入的字符组成字符串直接赋给String对象。

1 /*

2 如何将键盘输入的字符组成字符串直接赋给String 对象3

4 预备知识:5 --------------------------------6 Reader FileReader InputStream FileInputStream BufferedInputStream7 流中都没有 readLine 方法8 DataInputStream 流中有 readLine方法,但已经 被标记为过时9 BufferedReader 流中有readLine方法,并且该方法是可以正确被使用的10 --------------------------------11 */

12

13 import java.io.*;14

15 public classTestStringInput16 {17 public static voidmain(String[] args)18 {19 String str = null;20 BufferedReader br = new BufferedReader ( //21行

21 newInputStreamReader(System.in)22 ); //23行 查API:从21行到23行的代码是不会抛出任何异常的

23

24 try

25 {26 str = br.readLine(); //会抛出IOException异常

27 }28 catch(IOException e)29 {30 e.printStackTrace();31 System.exit(-1);32 }33

34 System.out.println("str = " +str);35 try

36 {37 br.close(); //会抛出IOException异常

38 }39 catch(IOException e)40 {41 e.printStackTrace();42 System.exit(-1);43 }44 }45 }46 /*

47 在JDK 1.6中的运行结果是:48 --------------------------------49 sadd行政村123Asd?asd撒旦50 str = sadd行政村123Asd?asd撒旦51 --------------------------------52 */

TestStringInput

readLine()与回车符的问题:

Print流  PrintWriter PrintStream

Print 流只有输出,没有输入

分类:

PrintWriter输入字符

PrintStream输出字符

PrintWriter在OutputStream基础之上提供了增强的功能,既可以方便地输出各种类型数据(而不仅限于byte型)的格式化表示形式。

PrintStream重载了print和println方法,用于各种不同类型数据的格式化输出。

格式化输出是指将一个数据用其字符串格式输出。

DataOutputStream 中的 WriteXXX(data)方法是把data在内存中的二进制数据写入文件

PrintStream 中的println(data)是该数据格式化后的字符串写入文件

1 /*

2 DataOutputStream 中的 writeXXX(data)方法3 与4 PrintStream 中的 println(data)的区别5

6 总结:7 DataOutputStream 中的 writeXXX(data)方法是把data在内存中的二进制数据写入文件8 PrintStream 中的 println(data)写出的是该数据的格式化后的字符串9 */

10

11 import java.io.*;12

13 public classTestPrintStream_114 {15 public static void main(String[] args) throwsException16 {17 DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:/share/kk.txt"));18 dos.writeLong(12345); //实际写入文件的是00 00 00 00 00 00 30 39

19 dos.close();20 System.out.printf("%#X\n", 12345);21

22 PrintStream ps = new PrintStream(new FileOutputStream("d:/share/kk2.txt"), true);23 ps.println(12345); //实际写入文件的是'1' '2' '3' '4' '5'

24 ps.close();25 }26 }

TestPrintStream_1

PrintWriter 提供了PrintStream的所有打印方法, 其方法也从不抛出IOException。

与PrintStream的区别:

标准输入输出的重定向:

实例:编程实现将键盘输入的数据输入A文件中,如果输入有误,则把出错信息输出到B文件

1 import java.io.*;2

3 public classTestSetSystemOut {4 public static voidmain(String[] args) {5 PrintStream ps_out = null;6

7 try{8 ps_out = new PrintStream(new FileOutputStream("d:/share/ww.txt"));9 System.setOut(ps_out); //将System.out的值重新设置为ps_out,即System.out不在关联到显示器,而是关联到"d:/share/ww.txt"文件

10 System.out.println(12); //这实际上是把12输出到了System.out所关联的d:/share/ww.txt中

11 System.out.println(55.5); //同上

12 } catch(Exception e) {13 e.printStackTrace();14 } finally{15 try{16 ps_out.close();17 } catch(Exception e) {18 e.printStackTrace();19 }20

21 }22 }23 }

TestSetSystemOut

1 /*

2 功能: 将键盘输入的数据输入A文件中,如果输入有误,3 则把出错信息输出到B文件中4

5 标准输入输出流的重定向6 */

7

8 import java.io.*;9 import java.util.*;10

11 public classTestSetOutErr {12 public static voidmain(String[] args) {13 PrintStream psOut = null;14 PrintStream psError = null;15 Scanner sc = null;16

17 try{18 psOut = new PrintStream("d:/Out.txt");19 psError = new PrintStream("d:/error.txt");20 sc = newScanner(System.in);21 intnum;22 System.setOut(psOut);23 System.setErr(psError);24

25 while (true) {26 num =sc.nextInt();27 System.out.println(num);28 }29 } catch(Exception e) {30 System.err.println("出错的信息是:"); //不可以写成System.out.println("出错的信息是:");

31 e.printStackTrace(); //e.printStackTrace(); 默认是输出到System.err所关联的设备中

32 }33 }34 }

TestSetOutErr

对象的序列化 ObjectOutputStream ObjectInputStream

所谓序列化是指:把一个Object对象直接转化为字节流,然后把这个字节流直接写入本地硬盘或网络中

序列化流(ObjectOutputStream)----writeObject

反序列化流(ObjectInputStream)---readObject

如果想把某个对象序列化,则必须实现Serializable接口

transient关键字用用它修饰变量后该变量不会进行jvm默认的序列化

当我们要把一个对象在网络上传输转化成字节序列,我们有些变量没必要使用,放在网络上传输会浪费资源,这个时候我们就会用transient关键字

transient修饰的属性我们可以自己完成序列化

transient关键字在有些情况下可以提高性能

实例:

1 import java.io.*;2

3 public classTestObjectIO4 {5 public static voidmain(String[] args)6 {7 ObjectOutputStream oos = null;8 ObjectInputStream ois = null;9 Student ss = new Student("zhansan", 1000, 88.8f); //注意88.8f不能改为88.8

10 Student ss2 = null;11

12 try

13 {14 FileOutputStream fos = new FileOutputStream("d:/share/java/ObjectOut.txt");15 oos = newObjectOutputStream(fos);16 oos.writeObject(ss);17

18 ois = new ObjectInputStream(new FileInputStream("d:/share/java/ObjectOut.txt"));19 ss2 = (Student)ois.readObject(); //(Student)不能省 ois.readObject();如果ois中的某个成员是transient,则该成员是不会被读取的,因为该成员不会被保存,何来读取之说?!

20

21 System.out.println("ss2.sname = " +ss2.sname);22 System.out.println("ss2.sid = " +ss2.sid);23 System.out.println("ss2.sscore = " +ss2.sscore);24 }25 catch(FileNotFoundException e)26 {27 System.out.println("文件没有找到!");28 System.exit(-1);29 }30 catch(Exception e)31 {32 e.printStackTrace();33 System.exit(-1);34 }35 finally

36 {37 try

38 {39 oos.close();40 ois.close();41 }42 catch(Exception e)43 {44 e.printStackTrace();45 System.exit(-1);46 }47 }48 }49 }50

51 class Student implements Serializable //如果将implements Serializable 注释掉,则程序编译时就会报错

52 {53 public String sname = null;54 public int sid = 0;55 transient public float sscore = 0; //表示sscore成员不能被序列化,所谓不能被序列化就是指:“该成员调用ObjectOutputStream 的writeOnbject()时不会被保存,调用ObjectInputStream的readObject()方法时不会被读取”

56

57 public Student(String name, int id, floatscore)58 {59 this.sname =name;60 this.sid =id;61 this.sscore =score;62 }63 }

TestObjectIO

分析ArrayList源码中序列化和反序列化的问题

ArrayList的底层虽然是一个数组,但是这个数组不一定放满,没有放满的数组元素是不需要进行序列化的,我们必须自己完成序列化,把有效元素一个一个自己完成序列化 ,反序列化也一样,所以ArrayList源码中的序列化和反序列化的作用就是把ArrayList中的有效元素进行序列化 无效元素不进行序列化,可以提高性能。

对ArrayList的源码有个初步的了解,能够进行序列化的优化问题

序列化中 子类和父类构造函数的调用问题

当一个子类的父类实现了序列化接口,子类可以直接进行序列化 ,子类序列化时会递归调用父类的构造方法。

对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,那么其父类的构造方法会被调用

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

java 字符流read函数,JAVA中文件的读写 I/O 输入输出流相关推荐

  1. java 播放器开发 dat_dat格式用什么播放器 JAVA中文件的读写 I/O 输入输出流(3)

    OutputStreamWriter 和InputStreamReader都是包裹流 实例:如何将键盘输入的字符组成字符串直接赋给String对象. readLine()与回车符的问题: Print流 ...

  2. java实现文件导出到dat功能_dat转换什么格式的 JAVA中文件的读写 I/O 输入输出流(3)...

    InputStreamReader 流是把InputStream流转化为Reader OutputStreamWriter 和InputStreamReader都是包裹流 实例:如何将键盘输入的字符组 ...

  3. java写入dat文件_dat格式用什么播放器 如何在JAVA中进行文件的读写 I/O 输入输出流...

    3.RandomAccessFile的使用 4.I/O 输入输出流 1.创建File对象:File file=new File(String path);注意:File.seperater();获取系 ...

  4. java字符流和字节流写入读取文件

    FileOutputStream类使用字节流操作文件,文件每次读取/写入以字节为单位 import java.io.*;public class FileByte{public static void ...

  5. java 字符流读取_Java 字符流读写文件

    据说,java读写文件要写很多,贼麻烦,不像c艹,几行代码就搞定.只能抄抄模板拿来用了. 输入输出流分字节流和字符流.先看看字符流的操作,字节转化为字符也可读写. 一.写入文件 1.FileWrite ...

  6. 黑马程序员——Java字符流、字节流IO流

    黑马程序员--Java字符流.字节流Io流 ---------------------- <a href="http://www.itheima.com"target=&qu ...

  7. JAVA字符流与字符集编码

    http://elf8848.iteye.com/blog/271742 问题: 当用JAVA字符流向硬盘写一个a.txt文件时,默认情况下a.txt 会使用什么字符集编码? 分析: "字符 ...

  8. java字符流和字节流的区别_java字符流与字节流的区别是什么

    java中字符流与字节流的区别: 1.字节流操作的基本单元为字节:字符流操作的基本单元为Unicode码元. 2.字节流默认不使用缓冲区:字符流使用缓冲区. 3.字节流通常用于处理二进制数据,实际上它 ...

  9. java字符流字节流场景_【120期】Java IO:字节流、字符流、缓冲流

    IO流是Java中的一个重要构成部分,也是我们经常打交道的.这篇关于Java IO的博文干货满满,堪称全网前三(请轻喷!) 下面几个问题(问题还会继续补充),如果你能对答如流,那么恭喜你,IO知识掌握 ...

最新文章

  1. Java中的实现马赛克效果以及灰度效果----整张图片
  2. GBDT指标重要性计算
  3. 从本地上传到hdfs上出现异常
  4. 策略模式和工厂模式的区别_设计模式之工厂模式-工厂方法模式
  5. 使用Api分析器与Windows兼容包来编写智能的跨平台.NET Core应用
  6. MySQL 优化 —— EXPLAIN 执行计划详解
  7. git 代码回滚_git代码版本管理(1)——git版本回滚
  8. Recommended Django Project Layout
  9. 基于SSH开发在线问卷调查系统
  10. jsp实现登录验证码
  11. Linux通过域名查ip
  12. [工具(前端)] 后台管理模板
  13. 参加第五届“软件杯”记录
  14. 中美视觉谈标志设计分类
  15. pycharm中出现这个文件图标左上角出现这个问号怎么解决
  16. windows无人值守文件的制作_autounattend.xml
  17. 收楼了心情忐忑不安,该花钱请验房师来验房吗?找一个验房师需要多少钱,验房标准价格是多少,验房师现场验收出二百多个问题值不值
  18. react手脚架安装
  19. 文本数据扩增时,哪些单词(不)应该被选择?
  20. 用Python自动化操作Excel制作报表,真的是太方便啦!!!

热门文章

  1. 机器人视觉系统包括哪些关键技术?
  2. 用Tableau制作雷达图
  3. 讲述30岁处男的悲惨经历
  4. npm yarn pnpm命令
  5. 不动点求数列通项原理_不动点求数列通项的原理是什么?
  6. deepdive中文关系提取
  7. Eplan绘图软件:西门子SINAMICS部件
  8. 软件设计原则:高内聚低耦合
  9. 2021年胡润境外资本投资中国50强排行榜:18%的企业从事金融服务行业,美国投资上榜企业最多(附年榜TOP50详单)
  10. PC端微信浏览器模拟器