流类

Java的流式输入/输出是建立在四个抽象类的基础上的:InputStream、OutputStream、Reader、Writer。它们用来创建具体的流式子类。尽管程序通过具体子类执行输入/输出操作,但顶层类定义了所有流类的基本通用功能。

InputStream和OutputStream为字节流设计,Reader和Writer为字符流设计,字节流和字符流形成分离的层次结构。一般来说,处理字符或字符串使用字符流类,处理字节或二进制对象使用字节流

操作文件流时,不管是字符流还是字节流,都可以按照以下方式进行:

1、使用File类找到一个对象

2、通过File类的对象去实例化字节流或字符流的子类

3、进行字节(字符)的读、写操作

4、关闭文件流

OutputStream(字节输出流)

OutputStream是定义了Java流式字节输入模式的抽象类。该类的所有方法返回一个void值并且在出错的情况下引发一个IOException,OutputStream提供的抽象方法有:

方    法 作    用
void close() 关闭输入流,关闭后的写操作会引发IOException
flush() 刷新此输入流并强制写出所有缓冲的输出字节
write(byte[] b) 向输入流写入单个字节,注意参数是一个int型,它允许设计者不必把参数转换成字节型就可以调用write()方法
write(byte[] b, int off, int len) 以b[off]为起点,向文件写入字节数组b中len个字节
write(int b) 向一个输出流写一个完整的字节数组

FileOutputStream(文件字节输出流)

FileOutpuStream应该是Java中最常见的字节输出流了,它创建一个可向文件写入字节的类OutputStream,它常用的构造方法如下:

1、FileOutputStream(String name)

2、FileOutputStream(File file)

3、FileOutputStream(File file, boolean append)

前两个构造方法类似,前者输入文件的绝对路径,后者输入File的实例对象,和RandomAccessFile一样,推荐后者。第三个构造方法有一点不同,append如果设置为true,文件则以搜索路径模式打开。FileOutputStream的创建不依赖于文件是否存在,在创建对象时,FileOutputSStream会在打开输出文件之前就创建它。这种情况下如果试图打开一个只读文件,会引发IOException。FileOutputStream,写一个例子,现在我的D盘路径下并没有"stream.txt"这个文件:

public static void main(String[] args) throws Exception
{
File file = new File("D:/stream.txt");
OutputStream out = new FileOutputStream(file);;
byte b0[] = "abcdefghijklmnopqrstuvwxyz".getBytes(); //操作字节流,要转换成字节
out.write(b0);
out.close();
}

此时打开"stream.txt":

看到D盘下多了"stream.txt",且文件中的内容和我们写入的一致,同样这个例子也证明了FileOutputStream并不依赖指定路径下的文件是否存在。那如果指定路径下本来就有文件,那么写将会覆盖而不是追加,很好证明:

public static void main(String[] args) throws Exception
{
File file = new File("D:/stream.txt");
OutputStream out = new FileOutputStream(file);;
byte b0[] = "abcdefghijklmnopqrstuvwxyz".getBytes(); //操作字节流,要转换成字节
out.write(b0);
out.close();
}

此时再打开"stream.txt":

"stream.txt"中的内容变掉了,证明了结论。

InputStream(字节输入流)

InputStream是定义了Java流式字节输入模式的抽象类。该类所有方法在出错的时候都会引发一个IOException,InputStream提供的抽象方法有:

方    法 作    用
int available() 返回当前可读的字节数
void close() 关闭此输入流并释放与该流关联的所有系统资源,关闭之后再读取会产生IOException
int mark(int readlimit) 在输入流中放置一个标记,该流在读取N个Bytes字节前都保持有效
boolean markSupported() 如果调用的流支持mark()/reset()就返回true
int read() 如果下一个字节可读取则返回一个整形,遇到文件尾时返回-1
int read(byte b[]) 试图读取buffer.length个字节到buffer中,并返回实际成功读取的字节数,遇到文件尾则返回-1
int read(byte b[], int off, int len) 将输入流中最多len个数组直接读入byte数组,off表示数组b中写入数据的初始偏移量。注意,三个read方法,在输入数据可用、检测到流末尾或者抛出异常前,此方法将一直阻塞
void reset() 重新设置输入指针到先前设置的标记处
long skip(long n) 跳过和丢弃此输入流中数据的n个字节

FileInputStream(文件字节输入流)

FileInputStream应该是Java中最常见的字节输入流了,它创建一个能从文件读取字节的InputStream类,它的两个常用构造方法如下:

1、FileInputStream(String name)

2、FileInputStream(File file)

和FileOutputStream差不多,推荐后者的用法。FileInputStream,同样写一个例子,操作的是上面D盘下生成的"stream.txt":

public static void main(String[] args) throws Exception
{
File file = new File("D:/stream.txt");
InputStream in = new FileInputStream(file);
byte b1[] = new byte[(int)file.length()];
int i = 0;
i = in.read(b1);
System.out.println(i);
System.out.println(new String(b1, 0, i));
}

运行结果为:

20
Hello World!!!

要区分清楚,OutputStream的作用是将内容由Java内存输出到文件中、InputStream是将内容由文件输入到Java内存中。read(byte b[])方法之前讲明了,表示"试图读取buffer.length个字节到buffer中,并返回实际读取的字节数",返回的是实际字节的大小。不要误以为"Hello World!!!"是14个字符即28个字节,字节流底层是以byte为单位的,因此文件里面只有14个字节罢了,至于返回的是20,还是因为"字节对齐"的问题。

这里没有演示skip方法,因为比较简单,skip多少无非少读几个字节罢了,skip(3),那么读出的就是"lo World!!!",可以自己尝试一下。

Java IO3:字节流的更多相关文章

  1. Java中字节流和字符流的比较(转)

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操 ...

  2. java中字节流和字符流的区别

    流分类: 1.Java的字节流   InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先.2.Java的字符流  Reader是所有读取字符串输入流的祖先,而 ...

  3. java中字节流与字符流的区别

    字节流 在I/O类库中,java.io.InputStream和java.io.OutputStream分别表示字节输入流和字节输出流,它们都是抽象类,不能实例化,数据流中的最小单位是字节,所以叫做字 ...

  4. JAVA IO 字节流与字符流

    文章出自:听云博客 题主将以三个章节的篇幅来讲解JAVA IO的内容 . 第一节JAVA IO包的框架体系和源码分析,第二节,序列化反序列化和IO的设计模块,第三节异步IO. 本文是第一节.     ...

  5. Java IO3:字符流

    字符流 字节流提供了处理任何类型输入/输出操作的功能(对于计算机而言,一切都是0 和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,一个Unicode字符占用2个字节,而 ...

  6. OpenJDK 阅读源代码 Java 实现字节流输入类

    Java 的输入输出总是给人一种非常混乱的感觉.要想把这个问题搞清楚.必须对各种与输入输出相关的类之间的关系有所了解. 仅仅有你了解了他们之间的关系.知道设计这个类的目的是什么.才干更从容的使用他们. ...

  7. java使用字节流和字符流实现文件复制

    大家在Java开发中都会遇到文件复制的文件,众所周知,需要通过文件输入输出流实现. 那究竟该怎么做那,话不多说,直接上代码: 一,使用字节流复制文件 public class FileByteCopy ...

  8. Java 的字节流文件读取(一)

    上篇文章我们介绍了抽象化磁盘文件的 File 类型,它仅仅用于抽象化描述一个磁盘文件或目录,却不具备访问和修改一个文件内容的能力. Java 的 IO 流就是用于读写文件内容的一种设计,它能完成将磁盘 ...

  9. Java 的字节流文件读取(二)

    接着上篇文章,我们继续来学习 Java 中的字节流操作. 装饰者缓冲流 BufferedInput/OutputStream 装饰者流其实是基于一种设计模式「装饰者模式」而实现的一种文件 IO 流,而 ...

随机推荐

  1. c#输出、输入

    //输出 Console.WriteLine("这是一行文字");  自动回车的. Console.Write("Hello world");  不带回车的. ...

  2. .net中从GridView中导出数据到excel(详细)

    1,创建数据源 找到要导出的GridView中的数据. 2,重写VerifyRenderingInServerForm方法. public override void VerifyRenderingI ...

  3. PhoneGap--001 入门 安装

    PhoneGap 百度百科 PhoneGap 中文网 3.0 安装使用 今天也配置好phonegap3.0 android开发环境了,操作系统是win7,就楼主文章做些补充. 我是按phonegap官 ...

  4. 关于MYSQL四种引擎

    你能用的数据库引擎取决于mysql在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另外两种类型INNO ...

  5. css3之文本新属性

                                                     

  6. 前端js 判断输入的必须是数字,判断金钱

    //输入的必须是数字 $(".xzjl").on("keyup", ".num", function () { var v = $(this ...

  7. sql sever获取数据库还原时间语句

    --只获取数据库名称和最后的还原时间 SELECT sdb.Name AS DatabaseName , ), ), '-') AS LastBackUpTime FROM sys.sysdataba ...

  8. Java中的继承与静态static等的执行先后顺序

    package extend; public class X { Y y=new Y(); static{  System.out.println("tttt"); } X(){  ...

  9. 用sql语句清除日志

    DUMP TRANSACTION [数据库] WITH NO_LOGBACKUP LOG [数据库] WITH NO_LOGDBCC SHRINKDATABASE([数据库])

  10. Java实现四则运算,使用堆栈,检查语法

    突然发闲想试一试自己实现算术的四则运算,支持加减乘除和括号.正负号:支持语法检查:思路很常规,利用两个堆栈,一个压操作符,一个压操作数,念头冒出来之后,立马动手:然后本以为很容易的一个实现,却存在各种 ...