一枚c/c++程序员java探索-io

File类

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

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. 文件读写完成以后一定要关闭
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
File demo = new File("test");
if(!demo.exists()) {
demo.mkdir();
}
File file = new File(demo,"test");
if(!file.exists()) {
file.createNewFile();
}
//打开文件,进行随机读写
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
/*序列化*/
int i = 0x7ffffff;
accessFile.write(i >> 24);
accessFile.write(i >> 16);
accessFile.write(i >> 8);
accessFile.write(i);
System.out.println(raf.getFilePointer());
/*反序列化*/
accessFile.seek(0);
int b = accessFile.read();
i = i | (b << 24);
b = accessFile.read();
i = i | (b << 16);
b = accessFile.read();
i = i | (b << 8);
b = accessFile.read();
i = i | b;
System.out.println(Integer.toHexString(i));
accessFile.close();

RandomAccessFile提供基本类型的读写方法,可以将基本类型数据序列化到文件或者将文件内容反序列化为数据

字节流

InputStream、OutputStream

InputStream抽象了应用程序读取数据的方式
OutputStream抽象了应用程序写出数据的方式 
EOF = End   读到-1就读到结尾

输入流基本方法

int b = in.read();读取一个字节无符号填充到int低八位.-1是 EOF
in.read(byte[] buf)
in.read(byte[] buf,int start,int size)

输出流基本方法

out.write(int b) 写出一个byte到流,b的低8位
out.write(byte[] buf)将buf字节数组都写入到流
out.write(byte[] buf,int start,int size)

FileInputStream

具体实现了在文件上读取数据

FileOutputStream

实现了向文件中写出byte数据的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* 读取指定文件内容,按照16进制输出到控制台
* 并且每输出10个byte换行
* @param fileName
* 单字节读取不适合大文件,大文件效率很低
*/
public static void printHex(String fileName)throws IOException{
//把文件作为字节流进行读操作
FileInputStream in = new FileInputStream(fileName);
int b ;
int i = 1;
while((b = in.read())!=-1){
if(b <= 0xf){
//单位数前面补0
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+" ");
if(i++%10==0){
System.out.println();
}
}
in.close();
}
/**
* 批量读取,对大文件而言效率高,也是我们最常用的读文件的方式
* @param fileName
* @throws IOException
*/
public static void printHexByByteArray(String fileName)throws IOExceptio){
FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[8 * 1024];
/*从in中批量读取字节,放入到buf这个字节数组中,
* 从第0个位置开始放,最多放buf.length个
* 返回的是读到的字节的个数
*/
/*int bytes = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
int j = 1;
for(int i = 0; i < bytes;i++){
System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
if(j++%10==0){
System.out.println();
}
}*/
int bytes = 0;
int j = 1;
while((bytes = in.read(buf,0,buf.length))!=-1){
for(int i = 0 ; i < bytes;i++){
System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
if(j++%10==0){
System.out.println();
}
}
}
in.close();
}

DataOutputStream/DataInputStream

对"流"功能的扩展,可以更加方面的读取int,long,字符等类型数据
DataOutputStream
writeInt()/writeDouble()/writeUTF()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//
DataInputStream dis = new DataInputStream(
new FileInputStream(file));
int i = dis.readInt();
System.out.println(i);
i = dis.readInt();
System.out.println(i);
long l = dis.readLong();
System.out.println(l);
double d = dis.readDouble();
System.out.println(d);
String s = dis.readUTF();
System.out.println(s);
dis.close();
//
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(file));
dos.writeInt(10);
dos.writeInt(-10);
dos.writeLong(10l);
dos.writeDouble(10.5);
//采用utf-8编码写出
dos.writeUTF("中国");
//采用utf-16be编码写出
dos.writeChars("中国");
dos.close();

BufferedInputStream/BufferedOutputStream

这两个流类位IO提供了带缓冲区的操作,一般打开文件进行写入
或读取操作时,都会加上缓冲,这种流模式提高了IO的性能
从应用程序中把输入放入文件,相当于将一缸水倒入到另一个缸中:
FileOutputStream: write()方法相当于一滴一滴地把水“转移”过去
DataOutputStream: writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去
BufferedOutputStream: write方法更方便,相当于一飘一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了

字符流

编码问题

java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文件是byte byte byte …的数据序列
文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结果

字符流(Reader Writer)

操作的是文本文本文件
字符的处理,一次处理一个字符
字符的底层任然是基本的字节序列
字符流的基本实现
InputStreamReader 完成byte流解析为char流,按照编码解析
OutputStreamWriter 提供char流到byte流,按照编码处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FileInputStream in = new FileInputStream("e:\\javaio\\utf8.txt");
InputStreamReader isr = new InputStreamReader(in,"utf-8");//默认项目的编码,操作的时候,要写文件本身的编码格式
FileOutputStream out = new FileOutputStream("e:\\javaio\\utf81.txt");
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
/*int c ;
while((c = isr.read())!=-1){
System.out.print((char)c);
}*/
char[] buffer = new char[8*1024];
int c;
/*批量读取,放入buffer这个字符数组,从第0个位置开始放置,最多放buffer.length个
返回的是读到的字符的个数
*/
while(( c = isr.read(buffer,0,buffer.length))!=-1){
String s = new String(buffer,0,c);
System.out.print(s);
osw.write(buffer,0,c);
osw.flush();
}
isr.close();
osw.close();

FileReader/FileWriter

字符流的过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//对文件进行读写操作
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("e:\\javaio\\test1.txt")));
/*BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("e:\\javaio\\test2.txt")));*/
PrintWriter pw = new PrintWriter("e:\\javaio\\test2.txt");
//PrintWriter pw1 = new PrintWriter(outputStream,boolean autoFlush);
String line ;
while((line = br.readLine())!=null){
System.out.println(line);//一次读一行,并不能识别换行
/*bw.write(line);
//单独写出换行操作
bw.newLine();//换行操作
bw.flush();*/
pw.println(line);
pw.flush();
}
br.close();
//bw.close();
pw.close();

BufferedReader

readLine 一次读一行

BufferedWriter

写一行

JasonThink wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!