java 基础之 I/O流 其三 (文本输入输出)
2017-08-07 20:42
393 查看
文本输入输出
上一小节讲了字节的使用,但是使用字节的操作不适合我们在日常中对文件的文本进行使用和理解,所以这节讲讲字符流的操作。保存数据时,我们可以选择文本格式PrintWrite 或 二进制格式DataOutputStream。
一 . 文本格式保存:在存储文本字符串时,需要考虑字符编码。理由如下:
编码格式 | 内容 | 编码 |
---|---|---|
UTF-16 | “1234” | 00 31 00 32 00 33 00 34 |
IOS 8859-1 | “1234” | 31 32 33 34 |
InputStreamReader 类 将包含字节的输入流 换成可以产生 Unicode 码元的读入器
InputStreamReader in = new InputStreamReader(new fFileInputStream("changeTom.dat"),"ISO8859-1");
OutputStreamReader 类 将选定字符编码方式,将unicode字符流转成字节流
1. 输出文本 - - PrintWriter 类
PrintWriter out = new PrintWriter("changeTom.dat"); //等同于 PrintWriter out = new PrintWriter(new FileWrite("changeTom.dat"),true); //后面的true是启用冲刷机制,只要println被调用,就会被送到目的地;(默认情况是关闭,要等到关闭流才会送到目的地) String name = "nihao"; out.print("asd"); out.print(name); //最终会转换成字节并写入changeTom.dat 文件中
2. 输入文本 - - BufferedReader 和 Scanner
(BufferedReader 1.5 之前 而1.6之后 可以使用 Scanner )
BufferedReader :要和 输入源组合起来
(补充:这里BufferedReader 具有缓冲的功能 。之所以要使用缓冲,是因为在操作读写的时候,程序一边读一边写是非常伤硬盘,速度也不快,而建立缓冲区可以先读取固定长度的内容,放到内存,再从内存写到硬盘。)
//从文件输入 try(BufferedReader bufin = new BufferedReader( new InputStreamReader(new FileInputStream("emplyes.dat"),"UTF-8"))) { String line ; while((line = bufin.readLine())!=null){ System.out.println(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //从控制台输入 BufferedReader bufin = new BufferedReader(new InputStreamReader(System.in))
Scanner 的使用方式
Scanner in = new Scanner(System.in); String str = in.next(); // 输入整型 int a = in.nextInt(); System.out.println(str); System.out.println(a);
Scanner 和 BufferedReader 两哥们的区别
BufferReader 只能读取字符类型,识别基本类型
Scanner 是用正则表达式处理过了的,所以可以识别基本类型
3. 输入文本和输出文本组合使用
//控制台输入 try(BufferedReader bufin = new BufferedReader( new InputStreamReader(System.in)); PrintWriter out = new PrintWriter( new FileOutputStream("emplyes.dat"))) { String line ; line = bufin.readLine(); System.out.println(line); out.println(line); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
二、二进制数据读写 继承于字节流 DataOutputStream 和 DataInputStream
使用的方式和其他流无益,这里只贴出代码
try(BufferedReader bufin = new BufferedReader( new InputStreamReader(System.in)); //使用二进制流输出到文件 DataOutputStream out = new DataOutputStream( new FileOutputStream("emplyes.dat"))) { String line ; line = bufin.readLine(); System.out.println(line); //输出缓冲区读入的字节流 out.writeBytes(line); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
三、随机访问文件 RandomAccessFile : 实现了DataOutput 和 DataInput 接口
特性:
强大的地方:可以在文件中的任何位置查找或者写入数据
对于磁盘的文件都是随机访问的,而从网络来的数据流却不是
当有文件被 RandomAccessFile 打开时,这个文件不会被删除 通过
RandomAccessFile的第二个构造参数进行读写控制
“r” :只读 。如果试图对该RandomAccessFile指定的文件执行写入方法则会抛出IOException “rw” :读写 。如果文件不存在,会尝试创建文件 “rwd” :读写 。有rw功能,还要求对文件的内容的每个更新都要同步到存储设备上。这对确保在系统崩溃时不会丢失重要信息特别有用。 “rws”:读写。有rwd 的功能,还要求对元数据的每个更新都要同步到存储设备上。
RandomAccessFile 主要方法
getFilePointer() 返回文件记录指针的当前位置
seek(long pos) 将文件记录指针定位到pos的位置
由于实现了 DataOutput 和 DataInput 接口,所以读写操作和这两个接口无异 下面是实现的代码
读取
//RandomAccessFile 读取 try(RandomAccessFile raf = new RandomAccessFile("emplyes.dat","r")){ //获取RandomAccessFile对象文件指针的位置,初始位置是0 System.out.println("RandomAccessFile文件指针的初始位置:"+raf.getFilePointer()); //移动指针 raf.seek(3);//移动文件指针位置 byte[] buff = new byte[1024]; int le = 0; while((le = raf.read(buff))!=-1){ System.out.println(new String(buff,0,le)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
写入
这里很
b149
简单,只需要移动指针,再写入数据就行
//写出文件 try(RandomAccessFile raf = new RandomAccessFile("emplyes.dat","rw")){ //移动指针到文件最后 raf.seek(raf.length()); raf.write("这是追加在文件最后的内容".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
读写,
在文件中间插入数据的操作
try(RandomAccessFile raf = new RandomAccessFile("emplyes.dat","rw")){ //建立一个临时的文件 File tmp=File.createTempFile("tmp", null); //退出时删除该文件 tmp.deleteOnExit(); try(FileInputStream fis = new FileInputStream(tmp); FileOutputStream fos = new FileOutputStream(tmp)){ //移动指针 raf.seek(4); byte[] buff = new byte[1024]; int hasRead = 0 ; while((hasRead = raf.read(buff))>0){ //读到的内容放到临时文件中 fos.write(buff,0,hasRead); } //指针再返回原来的地方 raf.seek(4); raf.write("这是在读写操作中插入的数据".getBytes()); //将临时文件的内容插回去 while((hasRead = fis.read(buff))>0){ raf.write(buff,0,hasRead); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
可以使用
RandomAccessFile这个类,来实现一个多线程断点下载的功能
相关文章推荐
- 黑马程序员——Java基础---I/O流(下[字符流])
- java基础——I/O流
- Java基础: 基本输入输出
- Java基础之IO流,按指定行号范围读取文本文件内容,带行业、带缓冲
- Java基础_I/O流
- JavaSE入门学习46:文件传输基础之I/O流(五)(Java序列化)
- 【Java基础】异常处理与输入输出流
- java 基础知识之I/O流 其一(概览)
- java基础——输入输出流
- Java_基础—将文本反转
- Java:I/O流基础知识
- Java基础之(三十五)输入输出<一>
- Java基础:第十七讲 基本输入输出
- java基础知识之输入输出
- 零java基础搞定微信Server_6:微信公众号的文本消息处理
- Java基础(3):文件输入输出
- java基础的综合应用(类的应用,文本拷贝,IO流,数组,集合,文件文件夹的创建)
- 黑马程序员------java基础----I/O流(一)
- Java:I/O流基础知识详解
- java基础---I/O流--字节流(2)