每次看javaIO的时候就很烦躁,一是因为太繁琐了,看到这么多类,又是字节流又是字符流的,二是我做javaEE开发的时候用的实在不多,过两天就忘了。
流又分为输入流和输出流:这个是以内存为参照的,如果是向内存存入的就是输入流,从内存流出就是输出流。
java的IO分为字符流和字节流,字节输入流每次都是从文件或者内存中的读取都是以字节为单位的,在abstract类InputStream中有一个abstract的read方法
/**
Reads the next byte of data from the input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the stream
* has been reached, the value <code>-1</code> is returned
*/
public abstract int read() throws IOException;//这个方法的的用法是返回一个int类型的,虽然是int但是0~255那么只有一个字节的大小
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
//以上方法是将读取的字节存储到一个字节数组中
public int read(byte b[], int off, int len) throws IOException
在这个类中读取字节的主要方法是一个abstract的,我以为会在子类中得到源码,打开FileInputStream后发现是一个native方法
public native int read() throws IOException;
//那么java在底层调用了C++写的代码了
所以我们看不到他的具体实现是什么,不过可以知道的是在读取文件的时候还负责了游标的后移等的操作
在javaIO字节输入流中这个方法是核心,再来看一下DataInputStream,它是能够从文件或者内存中读取入int,char,short,long之类的数据的,字节输出流每次读取的都是字节,那么它是怎么读取返回数据的呢?
public final int readInt() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
//这上面是一个读取int类型的数据方法,仔细看会发现它实际上每次读取了四个字节,将第一个字节左移三个字节长度,
//第二个字节左移两个字节长度,第三个字节左移一个字节长度,然后将他们相加起来就得到了一个int
很相像的还有
public final char readChar() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (char)((ch1 << 8) + (ch2 << 0));
}
//在这里值得注意的是判断条件ch1 | ch2) < 0
//为什么这么判断呢?是因为读取的是字节那么范围在0~255,这样两者或运算应该是正数,而出现负数只有一种可能那就是读到文件结尾不够了,返回了-1
public final int readUnsignedShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
我一直不清楚的是在字节输入输出流中的布尔类型的数据是这么存储的,看了源码发现是这样的
在DataOutPutStream类中
/**
* Writes a <code>boolean</code> to the underlying output stream as
* a 1-byte value. The value <code>true</code> is written out as the
* value <code>(byte)1</code>; the value <code>false</code> is
* written out as the value <code>(byte)0</code>. If no exception is
* thrown, the counter <code>written</code> is incremented by
* <code>1</code>.
*
* @param v a <code>boolean</code> value to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeBoolean(boolean v) throws IOException {
out.write(v ? 1 : 0);
incCount(1);
}
//就是说java将boolean存储成了一个byte大小的数据
在DataInputStream类中读取boolean是这样的
public final boolean readBoolean() throws IOException {
int ch = in.read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
再来看看对象字节流,我们甚至可以使用字节的方式将对象写入文件中,当然该对象的类必须实现了Serializable接口,当我们需要再恢复这个对象的时候,系统不需要再调用构造器来执行初始化。当然了恢复出来的对象与原对象还是不同的对象,除了他们在堆中的地址之外具有其他一样的属性。
package com.gengu.input;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.gengu.assist.Book;
/**
* 这个类测试对象字节输入流
* */
public class TestObjectInput {
public static Object objectInput(String filename) throws IOException, ClassNotFoundException{
FileInputStream fin = new FileInputStream("F://新建文件夹 (2)/TestIO/src/com/gengu/input/test.txt");
ObjectInputStream oin = new ObjectInputStream(fin);
Object object = oin.readObject();
fin.close();
oin.close();
return object;
}
//向文件中写入对象
public static void objectOutput(String filename,Object obj) throws IOException{
FileOutputStream fout = new FileOutputStream(filename,false);
ObjectOutputStream oout = new ObjectOutputStream(fout);
oout.writeObject(obj);
oout.close();
fout.close();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Book book = new Book();
TestObjectInput.objectOutput("F://新建文件夹 (2)/TestIO/src/com/gengu/input/test.txt", book);
Book book1 = (Book) TestObjectInput.objectInput("F://新建文件夹 (2)/TestIO/src/com/gengu/input/test.txt");
System.out.println(book1.getClass()==book.getClass());
}
}
分享到:
相关推荐
Java IO是Java编程语言中用于输入/输出操作的重要部分,它提供了一系列的类和方法来处理数据的读写,文件的创建、删除以及流的管理等。以下是对标题和描述中涉及的知识点的详细说明: 1. **文件对象的生成**: 在...
java学习笔记1(java io/nio)设计模式
Java IO流是Java编程语言中处理输入...通过深入学习和理解IO流,开发者可以更好地掌握数据的读取、写入和传输,提升程序的效率和功能。同时,熟悉相关工具和配置文件的使用也能帮助开发者在实际项目中更加得心应手。
### Java IO流学习笔记 #### 异常处理与IO流操作 在进行Java IO流的学习过程中,异常处理是非常重要的一个方面。本节将详细介绍如何在Java中处理异常,并结合具体的IO流操作进行说明。 #### 一、异常处理 在Java...
本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...
"Java入门第二季学习笔记"可能深入到更复杂的主题,如异常处理、集合框架、IO流和线程。异常处理是Java中处理错误的重要机制,使得程序更加健壮。集合框架包括ArrayList、LinkedList、HashSet、HashMap等数据结构,...
【Java学习笔记Markdown版】是针对Java初学者和进阶者的一份详尽教程,以Markdown格式编写,便于阅读和整理。Markdown是一种轻量级的标记语言,它允许用户使用易读易写的纯文本格式编写文档,然后转换成结构化的HTML...
Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现为Oracle公司的一部分)于1995年发布。...Java学习笔记涵盖了这些核心知识点,通过深入学习和实践,你可以逐步掌握Java编程,并应用于实际项目开发中。
### Java IO流学习笔记 #### 一、IO流的四大抽象类 - **InputStream/OutputStream**:字节的输入输出流的抽象类。 - 数据单位:字节(8比特,范围0-255) - **Reader/Writer**:字符的输入输出流的抽象类。 - ...
"Java学习笔记——良葛格"是一份专为初学者设计的教程资料,由良葛格精心编写,旨在帮助读者掌握JDK5.0版本的Java基础知识。JDK(Java Development Kit)是Java开发的核心工具集,包含了编译器、调试器和运行环境等...
Java开发学习笔记主要针对的是初学者,旨在帮助他们掌握Java编程的基础知识。下面将详细讲解Java开发中的核心概念和步骤。 一、Java环境变量设置 在开始Java编程之前,我们需要安装Java Development Kit (JDK)并...
java基础:IO流学习笔记
"IO-黑马程序员Java学习笔记"这个压缩包包含了关于Java IO的详细教程,可以帮助我们深入理解这个关键领域。下面将根据提供的文件名来解析可能包含的知识点。 1. **IO.md**: 这个文件很可能是Markdown格式的学习...
"Java超强学习笔记"显然是一份全面且深入的Java学习资料,由一位极具洞察力和组织能力的作者精心编纂。这份笔记可能包含了从基础知识到高级特性的全方位讲解,旨在帮助学习者构建坚实的Java编程基础,并提升他们的...
### Java学习笔记-IO篇 #### 一、流的基本概念及分类 在Java中,**流**(Stream)是用于处理或传输数据的一种方式。它将数据视为一系列连续的字节序列或者字符序列进行处理。根据不同的标准,流可以分为多种类型:...