您的位置:首页 > 编程语言 > Java开发

Java学习笔记(IO_1)

2015-12-16 20:42 429 查看

17 IO

关于IO流,可参见: Java IO流学习总结

17.1 IO流

IO流用来处理设备之间的数据传输。Java对数据的操作是通过流的方式。

流按操作数据分为两种:字节流和字符流;

按流向分为:输入流,输出流。

字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。再对这个文字进行操作。简单说:字节流+编码表。

17.1.1 IO流常用基类

字节流的抽象基类:InputStream,OutputStream.

字符流的抽象基类:Reader,Writer.

P.S.

由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。

如:InputStream的子类FileInputStream。

如:Reader的子类FileReader。

[b]写[/b]

需求:将一些文字存储到硬盘一个文件中。

记住:如果要操作文字数据,建议优先考虑字符流。

而且要将数据从内存写到硬盘上,要使用字符流中的输出流:Writer。

硬盘的数据基本体现是文件,希望找到一个可以操作文件的Writer:FileWriter。

例1:

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo {

public static void main(String[] args) throws IOException {
//创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件
FileWriter fw = new FileWriter("F:\\javatest\\IOtest\\demo.txt");

fw.write("Gabriel1");
//刷新流对象中缓冲的数据,将数据刷至目的地中
fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部缓冲的数据,将数据刷到目的地中,
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会关闭流
fw.close();

}
}


例2:

import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {

public static void main(String[] args) {
FileWriter fw = null;
try {
fw =new FileWriter("F:\\javatest\\IOtest\\demo.txt");
fw.write("abc");
} catch (IOException e) {
System.out.println("catch:"+e.toString());
e.printStackTrace();
}finally{
try {
if(fw!=null)
fw.close();
} catch (IOException e) {
System.out.println("catch:"+e.toString());
}
}
}
}


将abc写入到demo.txt中。

例3:

public class FileWriterDemo {
public static void main(String[] args) {
try {
FileWriter fw = new FileWriter("F:\\javatest\\IOtest\\demo.txt",true);
fw.write("a");
fw.close();
} catch (IOException e) {
System.out.println("catch:"+e.toString());
e.printStackTrace();
}
}
}


将a写入到demo.txt中,并接着文字往后写,为“abca”。

[b]读[/b]

- 方式1:

第一种读取方式:使用read()方法读取文本文件数据。

例4:

import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo {

public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("F:\\javatest\\IOtest\\demo.txt");
//调用读取流对象的read方法,一次读一个字符,每次调用自动往下读
while(true){
int ch = fr.read();
if(ch==-1)
break;
System.out.println("ch:"+(char)ch);
}
fr.close();
}
}


运行结果:


- 方式2:

第二种读取方式:使用read(char[])方法读取文本文件数据。

例5:

public class FileReaderDemo {

public static void main(String[] args) throws IOException {
char[] buf = new char[2];
FileReader fr = new FileReader("F:\\javatest\\IOtest\\demo.txt");
int num = 0;
while((num=fr.read(buf))!=-1){
System.out.println("num:"+num+".."+new String(buf,0,num));
}
fr.close();
}
}


运行结果:


[b]拷贝[/b]

在D盘创建一个文件,用于存储C盘文件中的数据;

定义读取流和C盘文件关联;

通过不断的读写完成数据存储;

关闭资源。

方法一:

例6:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopeTest {

public static void main(String[] args) throws IOException {
copy_1();
}

public static void copy_1() throws IOException{
FileWriter fw = new FileWriter("D:\\RuntimeDemo_copy.txt");
FileReader fr = new FileReader("F:\\javatest\\Circle.java");

int ch = 0;
while((ch=fr.read())!=-1){
fw.write(ch);
}
fw.close();
fr.close();
}
}


方法二:

例7:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopeTest {

public static void main(String[] args) throws IOException {
copy_1();
}

public static void copy_1() throws IOException{
FileWriter fw = null;
FileReader fr = null;

fw = new FileWriter("D:\\RuntimeDemo_copy.txt");
fr = new FileReader("F:\\javatest\\BasicGeneric.java");

char[] ch = new char[1024];
int len = 0;
while((len=fr.read(ch))!=-1){
fw.write(ch,0,len);
}
fw.close();
fr.close();
}
}


[b]缓冲区[/b]

缓冲区的出现提高了对数据的读写效率。

对应类:

BufferedWriter

BufferedReader

P.S.

缓冲区要结合流才可以使用。

作用:在流的基础上对流的功能进行了增强。

例8:

import java.io.*;

public class BufferedReaderDemo {

public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("F:\\javatest\\BasicGeneric.java");

BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null){
System.out.println(line);
}
bufr.close();
}
}


例9:

import java.io.*;

public class CopeMp {

public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
copy_1();
long end = System.currentTimeMillis();

System.out.println((end-start)+"毫秒");
}

public static void copy_1() throws IOException{
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("C:/Users/Administrator/Desktop/[解读中国经济].林毅夫.扫描版(ED2000.COM).pdf"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("D:\\Demo_copy.pdf"));

int by = 0;
while((by=bufis.read())!=-1){
bufos.write(by);
}
bufos.close();
bufis.close();
}
}


例10:

import java.io.IOException;
import java.io.InputStream;

public class ReadInTest {

public static void main(String[] args) throws IOException {
InputStream in = System.in;
StringBuilder sb = new StringBuilder();

while(true){
int ch = in.read();
if(ch=='\r'){
continue;
}
if(ch=='\n'){
String s = sb.toString();
if("over".equals(s))
break;
System.out.println(s.toUpperCase());
sb.delete(0, sb.length());
}
else
sb.append((char)ch);
}
}
}


运行结果:将输入的字符串转成大写输出

[b]File类[/b]

创建

boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false;和输出流不一样,输出流对象一建立即创建文件,而且文件已经存在,会覆盖;

boolean mkdir():创建文件夹;

boolean mkdirs():创建多级文件夹。

删除

boolean delete():删除失败返回false;

void deleteOnExit():在程序退出时删除指定文件。

判断

boolean exists():文件是否存在。

isFile();

isDirectory();

isHidden();

isAbsolute()

获取

getName();

getPath();

getParent();

getAbsolutePath();

lastModified();

length();

例11:

import java.io.File;
import java.io.IOException;

public class FileDemo {
public static void main(String[] args) throws IOException {
method();
method_1();
method_2();
method_3();
}

public static void method() throws IOException{
File f = new File("a.txt");
write("create:"+f.createNewFile());
//write("delete:"+f.delete());
}

public static void method_1(){
File f = new File("FileDemo.java");
f.mkdir();
write("execute:"+f.canExecute());
}

public static void method_2(){
File f = new File("file.java");
//f.mkdir();
//判断文件对象是否是文件或者目的时,
//必须要先判断该文件对象封装的内容是否存在。
write(f.exists());
write("execute:"+f.isDirectory());
write("execute:"+f.isFile());
write(f.isAbsolute());
}

public static void method_3(){
File f = new File("b.java");
write("path:"+f.getPath());
write("absolutepath"+f.getAbsolutePath());
write("parent:"+f.getParent());//该方法绝对路径中的父目录,获得相对路径则返回null

}

public static void write(Object obj){
System.out.println(obj);
}
}


第二次运行结果:


例12:

import java.io.File;
import java.io.FilenameFilter;

public class FielDemo2 {

public static void main(String[] args) {
listRootsDemo();
listDemo();
File f = new File("E:/IELTS");
show(f,0);
}

public static void listDemo(){
File f = new File("d:\\software");

String[] names = f.list();
for(String name:names){
System.out.println(name);
}
}

public static void listRootsDemo(){
File[] files = File.listRoots();

for(File f:files){
System.out.println(f);
}
}

public static void show(File dir,int level){
System.out.println(getLevel(level)+dir.getName());
level++;
File[] files = dir.listFiles();
for(int x=0;x<files.length;x++){
if(files[x].isDirectory()){
show(files[x],level);//递归法
}
if(files[x].isFile())
System.out.println(getLevel(level)+files[x]);
}
}
public static String getLevel(int level){
StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int i=0;i<level;i++){
sb.insert(0, "   ");
}
return sb.toString();
}
}


运行结果:


例13(查询文件数量):

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CreatFileList {

public static void main(String[] args) throws IOException {
File dir =  new File("F:/javatest");
List<File> list = new ArrayList<File>();
fileToList(dir,list);

File file = new File(dir,"javalist.txt");
writeToFile(list,file.toString());
}

public static void fileToList(File dir,List<File> list){
File[] files = dir.listFiles();

for(File file:files){
if(file.isDirectory())
{
fileToList(file,list);
}
if(file.getName().endsWith(".java"))
list.add(file);
}
}
public static void writeToFile(List<File> list,String javaListFile) throws IOException{
BufferedWriter bufw = null;
try {
bufw =  new BufferedWriter(new FileWriter(javaListFile));
for(File f:list){
String path = f.getAbsolutePath();
bufw.write(path);
bufw.newLine();
bufw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bufw!=null){
bufw.close();
}
}
}
}


运行结果:将F:/javatest目录下所有的.java文件的地址打印到F:/javatest/javalist.txt中。

[b]Properties集合[/b]

Map

|–Hashtable

|–Properties

特点:

该集合中的键和值都是字符串类型。

集合中的数据可以保存到流中,或者从流中获取。

通常该集合用于操作以键值对形式存在的配置文件。

Properties集合的存和取。

例14:

import java.io.*;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {

public static void main(String[] args) throws IOException {
setAndGet();
method_1();
}

public static void method_1() throws IOException{
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
Properties prop = new Properties();
while((line=bufr.readLine())!=null){
if(line.startsWith("#"))
continue;
String[] arr = line.split("=");
prop.setProperty(arr[0], arr[1]);
}
bufr.close();
System.out.println(prop);
}
public static void setAndGet() throws IOException{
Properties prop = new Properties();

prop.setProperty("Gabriel","20");
prop.setProperty("Mary","12");
prop.setProperty("Lucy","11");
prop.setProperty("Gabriel", "5");
FileOutputStream fos = new FileOutputStream("info.txt");
prop.store(fos, "name+age");
fos.close();
Set<String> names = prop.stringPropertyNames();
for(String name:names){
String value = prop.getProperty(name);
System.out.println(name+" "+value);
}
}
}


运行结果:


例15:

计数器:获取一个应用程序的运行次数,超过5次则提醒已使用超限。

import java.io.*;
import java.util.Properties;

public class RunCount {

public static void main(String[] args) throws IOException {
Properties prop = new Properties();
File file =  new File("count.ini");
if(!file.exists())
file.createNewFile();

FileInputStream fis = new FileInputStream(file);
prop.load(fis);

int count = 0;
String value = prop.getProperty("time");

if(value!=null){
count = Integer.parseInt(value);
if(count>=5){
System.out.println("使用次数超限");
return;
}
}
count++;
prop.setProperty("time", count+"");

FileOutputStream fos = new FileOutputStream(file);
prop.store(fos, "count");

fos.close();
fis.close();
}
}


[b]打印流[/b]

PrintWriter与PrintStream:可以直接操作输入流和文件。

PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

与其他输出流不同,PrintStream永远不会抛出IOException。

PrintStream打印的所有字符都使用平台的默认字符编码转换为字节。

在需要写入字符而不是写入字节的情况下,应该使用PrintWriter类。

PrintStream:

提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式

它不抛IOException

构造函数,接收三种类型的值:

字符串路径

File对象

字节输出流

PrintWriter:字符打印流

构造函数参数:

字符串路径

File对象

字节输出流

字符输出流

例16:

import java.io.*;

public class PrintStreamDemo {

public static void main(String[] args) throws IOException {
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));

PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);

String line = null;

while((line=bufr.readLine())!=null){
if("over".equals(line)){
break;
}
out.println(line.toUpperCase());
}
out.close();
bufr.close();
}
}


序列流

SequenceInputStream:对多个流进行合并。

例17:

import java.io.*;
import java.util.Enumeration;
import java.util.Vector;

public class SequenceDemo {

public static void main(String[] args) throws IOException {
Vector<FileInputStream> v = new Vector<FileInputStream>();

v.add(new FileInputStream("F:\\JavaProject\\TestIO\\1.txt"));
v.add(new FileInputStream("F:\\JavaProject\\TestIO\\2.txt"));
v.add(new FileInputStream("F:\\JavaProject\\TestIO\\3.txt"));

Enumeration<FileInputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);

FileOutputStream fos = new FileOutputStream("F:\\JavaProject\\TestIO\\4.txt");

byte[] buf = new byte[1024];

int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}


例18:合并与分割文件:

import java.io.*;
import java.util.*;

public class SplitFile {

public static void main(String[] args) throws IOException {
splitFile();
merge();
}

public static void merge() throws IOException{//合并文件
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
//将碎片文件和流对象添加并存储在集合中
for(int x=1;x<=3;x++){
al.add(new FileInputStream("F:\\JavaProject\\TestIO\\"+x+".part"));
}

final Iterator<FileInputStream> it = al.iterator();

//多个流合并为序列流
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
public boolean hasMoreElements(){
return it.hasNext();
}
public FileInputStream nextElement() {
return it.next();
}
};//匿名类
SequenceInputStream sis = new SequenceInputStream(en);

FileOutputStream fos =  new FileOutputStream("F:\\JavaProject\\TestIO\\0.bmp");
byte[] buf = new byte[1024];
int len  = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf, 0, len);
}
fos.close();
sis.close();

}

public static void splitFile() throws IOException{ //分割文件
FileInputStream fis = new FileInputStream("F:\\JavaProject\\TestIO\\1.jpg");
FileOutputStream fos = null;

byte[] buf = new byte[1024*20];

int len = 0;
int count = 1;
while((len=fis.read(buf))!=-1){
fos = new FileOutputStream("F:\\JavaProject\\TestIO\\"+(count++)+".part");
fos.write(buf, 0, len);
fos.close();
}
fis.close();
}
}


[b]管道流[/b]

PipedInputStream和PipedOutputStream:输入输出可以直接进行连接,通过结合线程使用。

例19:

import java.io.*;

public class PipedStreamDemo {
public static void main(String[] args) throws IOException {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);

Read r = new Read(in);
Write w = new Write(out);

new Thread(r).start();
new Thread(w).start();
}
}

class Read implements Runnable{
private PipedInputStream in;
Read(PipedInputStream in){
this.in = in;
}
public void run() {
try {
byte[] buf = new byte[1024];
int len = in.read(buf);
String s = new String(buf,0,len);
System.out.println(s);
in.close();
} catch (IOException e) {
throw new RuntimeException("管道读取失败");
}
}
}

class Write implements Runnable{
private PipedOutputStream out;
Write(PipedOutputStream out){
this.out=out;
}
public void run() {
try {
Thread.sleep(2000);
out.write("piped".getBytes());
out.close();
} catch (Exception e) {
throw new RuntimeException("管道输出流失败");
}
}
}


运行结果:piped
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: