1、程序可以处理的数据来源除了文件还有哪些?对不同的数据来源共同的操作是什么?
- 网络和控制台
- 对不同的数据来源共同操作同时包含“读”与“写”两个基本操作
2、将对不同数据源中数据的读写抽象为对流的读写,有什么好处?
- 带来的扩展性更强,通过相对应的操作接口,就可以实现输入输出操作,不用关心底层框架的实现
- 流的处理效率更高
3、二进制文件与文本文件有什么区别?字节流与字符流之间有什么关系?为什么有的文本文件打开会乱码?怎么解决?
文本文件:储存的是字符串
定义:由单一特定编码的字符组成,如 UTF-8 编码,内容容易统一展示和阅读。(由于文本文件存在编码,所以,它也可以被看做是存储在磁盘上的长字符串,如一个 txt 格式的文本文件)
二进制文件:储存的是字节码
定义:直接由比特0和比特1组成,没有统一的字符编码,文件内部数据的组织格式与文件用途有关。(由于没有统一的字符编码,只能当做字节流,而不能看做是字符串)
两者最主要的区别在于是否有统一的字符编码。
文本文件编码基于字符定长,译码容易;二进制文件编码是变长的,所以它灵活,存储利用率要高些,译码难一些(不同的二进制文件格式,有不同的译码方式)。
字节流在操作时本身不会用到缓冲区(内存),是在文件本身直接操作的;而字符流在操作时使用了缓冲区,通过缓冲区再操作文件
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class TestOutputStream
{
public static void main(String[] args) throws Exception //异常直接抛出,不处理
{
File f = new File("d:" + File.separator + "d:/test.txt"); //File.separaor是文件路径分隔符
OutputStream out = new FileOutputStream(f);//通过子类实例化父类对象,OutputStream是抽象类
String str = "Hello World!!!";//准备一个字符串
byte b[] = str.getBytes();//将字符串转为byte数组
out.write(b);//将byte数组的内容输出
//此时并没有用out.clase()关闭输出流
}
}
可以在d盘根目录看到test.txt文件,打开发现即使此时没有关闭字节流操作,但是文件中也依然存在了输出的内容,证明字节流是直接操作文件本身的。而下面继续使用字符流完成,再观察效果,在这里我们先把test.txt文件删除。
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;
public class TestWriter
{
public static void main(String[] args) throws Exception //异常直接抛出,不处理
{
File f = new File("d:" + File.separator + "d:/test.txt"); //File.separaor是文件路径分隔符
Writer out = new FileWriter(f);//通过子类实例化父类对象,Writer是抽象类
String str = "Hello World!!!";//准备一个字符串
out.write(str);
//此时依旧没有用out.clase()关闭输出流
}
}
此时依然可以在d盘根目录看到test.txt文件,不过打开发现里面是空的,并没有显示“Hello World”;
4、字符与字节之间的关系是什么?尝试使用Visual Studio Code的Hex Editor插件打开一个文本文件。在文本文件中输入"123abc中文"。观察:一个英文字符占几个字节,一个中文字符占用几个字节。在Java程序中,使用字节流怎么将这个文件中的数据正确读取并组装起来。
首先不同编码,所占字节数不同。
1,ASCII码:一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字度节的空间。
2,UTF-8编码:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。中文标点占三个字节,英文标点占一个字节
3,Unicode编码:一个英文等于两个字节,一个中文(含繁体)等于两个字节。中文标点占两个字节,英文标点占两个字节
5、有一个stus数组,里面有若干Student对象(String name, int age, boolean gender, double score)。要将这些对象高效率地存储到文件中,需要使用哪些流?使用二进制流与使用字符流将这个数组存储到文件有何不同?使用二进制流与使用字符流从文件中读取并组装成对象有何不同?
- FileOutputStream 数据写入流
- BufferedOutputStream 使用缓冲流
- ObjectOutputStream 将整个对象写入数据
- 存储所占内存大小不同,还有就是解析译码文件效率不同
二进制流是指流动的是二进制数字序列,若流中有字符,则用一个字节的二进制ASCII码表示,若是数字,则用一个字节的二进制数表示。在流入流出时,对’\n’符号不进行变换,举个栗子:
比如2001这个数字,在文本流中的二进制ASCII码表示为‘2’‘0’‘0’‘1’即50 48 48 49共占用4个字节。而在二进制流中表示的是00000111 11010001用十六进制是07D1。只占2个字节。
6、使用什么类可以对文件进行随机存取?读写的单位是什么?为什么不是字符呢?
- RandomAccessFile类
RandomAccessFile类,不属于流,但具有读写文件数据的功能,可以随机从文件的任何位置开始执行读写数据的操作
RandomAccessFile类可以将文件以指定的操作权限(如只读,只写等)的方式打开,具体使用哪种权限取决于创建它所采用的构造方法
通过两种构造方法创建RandomAccessFile对象,需要接受两个参数:第一个参数指定关联的文件,第二个参数mode指定访问文件的模式(文件的权限) - 读写的单位是字节
- RandomAccessFile继承自DataOutput,DataInput,Closeable,其内部接口方法读写的单位都是字节,所以其类下的读写的单元与其父类一样,也是字节。