Java笔记-输入输出流

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java笔记-输入输出流相关的知识,希望对你有一定的参考价值。


所有的合适都是两个人的相互迁就和改变,没有天生合适的两个人,两个人朝着相同的方向努力,就是最好的爱情。


输入、输出流

技术分享

技术分享

什么是“流”。直观地讲,流就像水一样,不存在大小问题,也避免了完整性问题。非流的数据传输,比如你下载一张图片,需要整幅图片下载完之后才能使用,而流则不同,就像水,你取一杯也可以用,取一桶也可以用。所以说,流是一种数据传输的模式。

输入流和输出流,差别在于出和入,是相对于“使用程序”这个参照物而言的。如果数据的流向是程序至设备,我们称为输出流,反之我们称为输入流。服务器端的输出流对应就是接受客户端的输入流

输出流和输入流,二者没有必然的联系,都是流,差别是方向不同,也就是说,程序可以只有输入流而没有输出流,或者只有输出流而没有输入流。

输入流

程序在运行期间,可能需要从外部的存储媒介或其他程序中读入所需要的数据,这就是需要使用输入流对象。

技术分享

输出流

程序在使用数据后,可能需要将处理的结果写入到永久的存储媒介中或传送给其他的应用程序,这就需要输出流对象。

技术分享

File 类

File构造方法

File(String filename);
File(String directoryPath,String filename);
File(File f,String filename);

filename是文件名字,directoryPath是文件的路径,f是指定成一个目录的文件。是用那个File(String filename )创建文件时,该文件被认为与当前应用程序在同一个目录。

File属性

    public String getName() 返回文件名或目录名
    public boolean exists() 判断文件或目录是否存在
    public boolean isFile() 判断是文件还是目录 
    public boolean isDirectory() 判断是文件还是目录
    public boolean isHidden() 判断文件是否是隐藏文件
    public boolean canRead() 判断文件是否可读
    public boolean canWrite() 判断文件是否可写
    public String getPath() 返回文件或目录的路径
    public String getAbsolutePath() 返回文件的绝对路径
    public long length() 获取文件的长度 
    public String getParent() 获取文件的父目录
    public long lastModified() 获取文件的最后修改的时间(时间是从1970年午夜至文件最后修改时刻的毫秒数)

    File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:
    public String[ ] list () 将目录中所有文件名保存在字符串数组中返回。 
    public boolean renameTo( File newFile );    重命名文件
    public boolean createNewFile();  创建文件
    public void delete();   删除文件
    public boolean mkdir(); 创建目录

文件路径问题

1、java中“\”是转义字符,“\”表示的是一个”\”,以此类推,“\\”表示两个”\”;“\\\\”表示的是四个”\”。
2、“/ ”一个时表示除号,
3、“//”两个时表示单行注释。
4、在字符串中“/”和“\”也代表是路径。

File f = new File("D:\\eclipse\\workspace\\File\\src\\com\\file","Main2.java");
File f = new File("D:/eclipse/workspace/File/src/com/file","Main2.java");

示例

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

public class Main2 {
    public static void main(String[] args) {
        File f = new File("D:\\eclipse\\workspace\\File\\src\\com\\file","Main2.java");
        //File f = new File("D:/eclipse/workspace/File/src/com/file","Main2.java");
        System.out.println(f.getName() + "是可读的吗:" + f.canRead());
        System.out.println(f.getName() + "的长度:" + f.length());
        System.out.println(f.getName() + "的绝对路径:" + f.getAbsolutePath());
        System.out.println("文件父目录字符串 "+f.getParent());// 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。  
        System.out.println("该分区大小"+f.getTotalSpace()/(1024*1024*1024)+"G"); //返回由此抽象路径名表示的文件或目录的名称。  
        File file = new File("new.txt");
        System.out.println("在当前目录下创建新文件" + file.getName());
        if (!file.exists()) {
            try {
                file.createNewFile();
                System.out.println("创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
Main2.java是可读的吗:true
Main2.java的长度:1045
Main2.java的绝对路径:D:\eclipse\workspace\File\src\com\file\Main2.java
文件父目录字符串 D:\eclipse\workspace\File\src\com\file
该分区大小800G
在当前目录下创建新文件new.txt

目录

创建目录

public boolean mkdir() 创建目录,如果创建成功则返回true,否则返回false(如果目录存在则返回false

列出目录中的文件

如果File对象是一个目录,下面的方法将会列出目录下的文件和子目录。

public String[] list() 字符串形式返回目录下的全部文件

public File[] listFiles() 用File对象形式返回目录下的全部文件

有时需要列出目录下指定类型的文件,如.java,.txt等扩展名的文件。

public String [] list(FileNameFilter obj) 字符串形式放回目录下指定类型的所有文件

public File [] listFiles(FileNameFilter obj) File对象形式放回目录下指定类型的所有文件

FilenameFilter是一个接口

public boolean accept(File dir,String name); 

参数obj不断回调接口方法accept(File dir,String name),该方法中的参数dir为调用list的当前目录,参数name被实例化目录的一个文件名,当接口方法返回true时,list方法就将名字为name的文件存到数组中。

技术分享

示例

import java.io.File;

public class Main3 {
    public static void main(String[] args) {

        File dir = new File("D:\\javafile");// 查询的目录

        FileAccept fileAccept = new FileAccept();
        fileAccept.setExtendname("java");
        String fileName[] = dir.list(fileAccept);
        System.out.println("-----字符串返回.java后缀--------");
        for (String name : fileName) {
            System.out.println(name);
        }
        System.out.println("------字符串返回所有--------");
        String fileName2[] = dir.list();
        for (String name : fileName2) {
            System.out.println(name);
        }
        System.out.println("------File对象返回所有-------");
        File[] fileName3 = dir.listFiles();
        for (File name : fileName3) {
            System.out.println(name);
        }
    }
}
-----字符串返回.java后缀--------
ReturnTest.java
StudentTest.java
SwitchTest.java
Test.java
Testjiujiuchengfabiao.java
ThisDemo.java
Wolf.java
------字符串返回所有--------
Animal.class
Creature.class
Person.class
ReturnTest.class
ReturnTest.java
shuzhu
Student.class
StudentTest.class
StudentTest.java
SwitchTest.java
Test.class
Test.java
Testjiujiuchengfabiao.class
Testjiujiuchengfabiao.java
TestOverWrite
TestSuperThis
TestYichang
ThisDemo.class
ThisDemo.java
Wolf.class
Wolf.java
空白文档.txt
------File对象返回所有-------
D:\javafile\Animal.class
D:\javafile\Creature.class
D:\javafile\Person.class
D:\javafile\ReturnTest.class
D:\javafile\ReturnTest.java
D:\javafile\shuzhu
D:\javafile\Student.class
D:\javafile\StudentTest.class
D:\javafile\StudentTest.java
D:\javafile\SwitchTest.java
D:\javafile\Test.class
D:\javafile\Test.java
D:\javafile\Testjiujiuchengfabiao.class
D:\javafile\Testjiujiuchengfabiao.java
D:\javafile\TestOverWrite
D:\javafile\TestSuperThis
D:\javafile\TestYichang
D:\javafile\ThisDemo.class
D:\javafile\ThisDemo.java
D:\javafile\Wolf.class
D:\javafile\Wolf.java
D:\javafile\空白文档.txt

文件的删除和创建

File file = new File("D:\\javafile","须木一瓜.txt");
        /*try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        file.delete();
        System.out.println(file.exists());

运行可执行文件

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

public class Runexe {
    public static void main(String[] args) {
        try {
            Runtime ce = Runtime.getRuntime();
            File file = new File("c:/windows", "Notepad.exe");
            ce.exec(file.getAbsolutePath());
            file = new File("C:\\Program Files\\Internet Explorer","IEXPLORE www.baidu.com");
            ce.exec(file.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字节流和字符流

流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:

字节流:数据流中最小的数据单元是字节
字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

在java中,字节流读取的最小单位是一个字节(1byte=8bit),而字符流一次可以读取一个字符(1char = 2byte = 16bit)。
按照ANSI编码标准,标点符号、数字、大小写字母都占一个字节,汉字占2个字节。按照UNICODE标准所有字符都占2个字节。

InputStream类与OutputStream类

Java把InputStream抽象类的子类创建的流对象称作字节输入流,OutputStream抽象类的子类创建的流对象称作字节输出流。

IntputStreamread()方法以字节为单位顺序地读取源中的数据,只要不关闭流,每次调用read方法就顺序的读取源中的其余内容,直到源的末尾或输入流被关闭。

InputStream类的方法:

int read() 输入流调用该方法从源中读取单个字节的数据,该方法返回字节值(0~255之间的一个整数),如果未读出就返回-1
void close() 关闭输入流
int read(byte b[]) 从源中视图读取b.length个字节到b中,返回实际读取的字节数目。到达末尾则返回-1

OutStream流以字节为单位顺序的写文件,只要不关闭文件流,每次调用write方法就会顺序地向目的地写入内容,知道流被关闭。

OutputStream类的方法:

void write() 向输出流中写入单个字节
void write(byte b[]) 向输出流写入一个字节数组
void close() 关闭输出流

更多方法

Reader类与Writer类

Java把Reader抽象类的子类创建的流对象称作字符输入流,Writer抽象类的子类创建的流对象称作字符输出流。

Reader类提供的read方法以字符为单位顺序地读取源中的数据,只要不关闭流,每次调用read方法就书怒的读取源中的其余内容,直到源的末尾或输入流被关闭。

Reader类方法:

int read() 从源中读取一个字符,返回一个整数(0~65535之间的一个整数,Unicode字符值),如果未读出字符就返回-1int read(char b[]) 从源中读取b.length个字符到字符数组中b中,返回实际读取的字符数目,到达末尾则返回-1。

void close() 关闭输入流

OutStream流溢字符为单位顺序的写文件,只要不关闭流,每次调用write方法就顺序地向目的地写入内容,直到流被关闭。

Writer类方法:

void write(int n) 向输入流写入一个字符。
void write(byte []) 向输入流写入一个字符数组。
void close() 关闭输出流

关闭流

  流都提供了关闭方法close(),尽管程序结束时会自动关闭所有打开的流,但是当程序使用完流后,显示地关闭任何打开的流仍是一个良好的习惯,如果没有关闭那些被打开的流,那么就可能不允许另一个程序操作那些流所用的资源。另外,需要注意的是,在操作系统把程序写的到输出流上的那些字节保存到磁盘上之前,有时被存放在内存缓冲区中,通过调用close()方法,可以保证操作系统把流缓冲区的内容写到目的地,即关闭输出流可以把该流所用的缓冲区的内容冲洗掉(通常冲洗到磁盘文件上)。

文件字节流

InputStream专门提供了读写文件的子类:FileInputStreamFileOutStream

文件字节输入流

FileInputStream构造方法:

FileInputStream (String name);
FileInputStream (File file);

参数namefile指定的文件称作输入流的源,输入流通过调用read方法读取源中的数据。
FileInputStream 输入流打开一个到达的文件的输入流(源就是这个文件,输入流指向这个文件)

示例

import java.io.*;

public class FileStream3 {
    public static void main(String[] args) throws Exception {
        int n = -1;
        byte[] a = new byte[1000];//[100]or[1024]就是每次读取的最大字节数
        File file = new File("FileStream2.java");// 默认目录下要有文件
        //File file = new File("D:\\eclipse\\workspace\\IO\\src\\com\\file\\FileStream2.java");

        FileInputStream in = new FileInputStream(file);
        while((n=in.read(a,0,1000))!=-1){
            String s = new String(a,0,n);
            System.out.println(s);
        }
        in.close(); 
    }
}
//结果把 FileStream2.java内容输出了

文件字节输出流

FileOutputStream构造方法

FileOutputStream(String name)
FileOutputStream(File file)

示例

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
 * 文件字节输入流
 * @author Peng
 *
 */
public class Fileoutputstream {
    public static void main(String[] args) {
        byte[] a ="江西理工 2016级新生报到".getBytes();
        byte[] b = "军训快乐".getBytes();
        try {
            FileOutputStream out = new FileOutputStream("happy.txt");
            out.write(a);
            System.out.println(b.length);
            out.write(b, 0, b.length);//out.write(b,4,4) 快乐
            out.close();

            /*读取数据部分
            File file = new File("happy.txt");
            if(file.exists()){
                FileInputStream in = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int n =-1;
                while((n=in.read(buffer))!=-1){
                    System.out.println(new String(buffer,0,n));
                }
                in.close();
            }*/
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}
8
江西理工 2016级新生报到军训快乐

字节流综合示例

示例1

import java.io.*;

public class FileStream {
    public static void main(String[] args) throws Exception {
        FileOutputStream out = new FileOutputStream("hello.txt");//在目录下新建hello.txt
        out.write("http://blog.csdn.net/peng_hong_fu/article/details/52605935".getBytes()); // 把字符串转化为字节数组并写入到流中
        out.close();

        File f = new File("hello.txt");
        FileInputStream in = new FileInputStream(f);
        byte[] buf = new byte[1024];
        int len = in.read(buf); // 读取内容到字节数组buf中
        System.out.println("len:"+len);
        System.out.println(new String(buf, 0, len)); // String构造函数把字节数组转化为字符串
        in.close();
    }
}
len:58
http://blog.csdn.net/peng_hong_fu/article/details/52605935

文件字符流

字节流不能很好的操作Unicode字符,一个汉字在文件中占有2个字节,如果使用字节流,读取不当会出现”乱码”现象

 FileReader(String filename); FileReader(File filename) 
 FileWriter(String filename); FileWriter(File filename)

示例1

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

public class FileReaderWriter {
    public static void main(String[] args) {
        try {
            String content = "轻轻的我走了,正如我轻轻的来...000";
            File f = new File("ourang.txt");
            char[] a = content.toCharArray();
            FileWriter out = new FileWriter(f);
            out.write(a, 0, a.length);
            out.close();

            FileReader in = new FileReader(f);
            StringBuffer buffer = new StringBuffer();
            char[] tom = new char[10];
            int n = -1;
            while ((n = in.read(tom, 0, 10)) != -1) {
                String temp = new String(tom, 0, n);
                buffer.append(temp);
            }
            in.close();
            System.out.println(new String("内容:" + buffer));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
内容:轻轻的我走了,正如我轻轻的来...000

示例2

import java.io.*;

public class FileStream2 {
    public static void main(String[] args) throws Exception {
        FileWriter out = new FileWriter("hello2.txt");
        out.write("一句珍重!"); // 在此可以直接写入字符串,不用转化为字节数组
        out.close();

        char[] buf = new char[1024]; // 字符数组
        FileReader in = new FileReader("hello2.txt");
        int len = in.read(buf); // 此时的read方法可以读取一个字符或几个字符,len代表实际读取到的字符的个数。
        System.out.println("len:" + len);
        System.out.println(new String(buf, 0, 1024)); // String构造函数把字符数组转化为字符串。
        in.close();
    }
}
len:5
一句珍重!

缓存流

BufferedReader类和BufferedWriter类创建的对象称作缓冲输入、输出流,二者增强了读写文件的能力,提供了读取文件一行的方法。

BufferedReader流和BufferedWriter流,二者的源和目的地都必须是字符输入流和字符输出流
BufferedReader类和BufferedWriter类的构造方法

BufferedReader (Reader in)
BufferedWriter (Writer out)

BufferedReader 流读取文本行,readLine()

    FileReader inOne = new FileReader("Student.txt");
    BufferedReader inTwo = new BufferedReader(inOne);
    ....
    String strLine = inTwo.readLine();
    ..
    outTwo.newLine();// 写入回行符

示例

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * BufferedReader and BufferedWriter
 * @author Peng
 */
public class BufferRW {
    public static void main(String[] args) {
        File file = new File("Studen.txt");
        String[] content = { "商品列表:", "电视机,2993元/台", "洗衣机,3444元/台", "冰箱,8444元/台" };
        try {
            FileWriter outOne = new FileWriter(file);
            BufferedWriter outTwo = new BufferedWriter(outOne);
            for (String str : content) {
                outTwo.write(str);
                outTwo.newLine();// 写入回行符
            }
            outTwo.close();// 注意关闭顺序 先把缓存流关闭
            outOne.close();

            // read
            FileReader inOne = new FileReader(file);
            BufferedReader inTwo = new BufferedReader(inOne);
            String s = null;
            while ((s = inTwo.readLine()) != null) {
                System.out.println(s);
            }
            inTwo.close();
            inOne.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
商品列表:
电视机,2993元/台
洗衣机,3444元/台
冰箱,8444元/台

随机流

既可以读文件也可以写文件的流,RandomAccessFile 类创建的流称作随机流。

RandomAccessFile 构造方法:

RandomAccessFile(String name,String mode) 参数name 文件名,mode r(只读)或rw(可读写)

RandomAccessFile(File file,String mode) 

方法

seek(long a) 定位RandomAccessFile 流的读写位置,a确认读写位置距离文件开头的字节个数。

getFilePointer() 获取流的当前读写位置。
readInt()  读取一个int的值
readLine() 读取一个文本行
.
.

示例

import java.io.IOException;
import java.io.RandomAccessFile;

public class MyRandomAccessFile {
    public static void main(String[] args) {
        RandomAccessFile inAndOut = null;
        int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        System.out.println(data.length);
        try {
            inAndOut = new RandomAccessFile("tom.dat", "rw");
            for (int i = 0; i < data.length; i++) {
                inAndOut.writeInt(data[i]);
            }

            //read
            for (long i = data.length - 1; i >= 0; i--) {// 一个int型数据占4个字节,inAndOut从文件的低36个字节出开始读取
                inAndOut.seek(i * 4); // 每隔4个字符往前读取一个整数
                System.out.printf("\t%d", inAndOut.readInt());
            }
            inAndOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
10
    10  9   8   7   6   5   4   3   2   1

非ASCII字符乱码

RandomAccessFile 流的readLine()方法在读取非ASCII字符的文件时(如汉字的文件)会出现”乱码”现象,可以有下面的操作

    //读取
    String str = in.readLine();

    //用"iso-8859-1"重新编码
    byte [] b =str.getBytes("iso-8859-1");

    //使用默认编码,或指定编码把字节数组转化成字符串
    String str2 = new String(b);
    //String str2 = new String(b,"GB2312");

示例

import java.io.IOException;
import java.io.RandomAccessFile;

public class MyRandomAccessFile乱码 {
    public static void main(String[] args) {
        RandomAccessFile in = null;
        int data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        System.out.println(data.length);
        try {
            in = new RandomAccessFile("D:\\eclipse\\workspace\\IO\\src\\com"
                    + "\\file\\随机流\\MyRandomAccessFile.java", "rw");//绝对路径 指定目录下文件
            long length = in.length();
            long position = 0;
            in.seek(position);
            while(position<length){
                String str = in.readLine();
                byte [] b =str.getBytes("iso-8859-1");
                String str2 = new String(b);
                position = in.getFilePointer();
                //System.out.println(str);
                System.out.println(str2);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出str时乱码

....
    for (long i = data.length - 1; i >= 0; i--) {// ????int????????4??×???,inAndOut??????????36??×?????????????
    inAndOut.seek(i * 4); // ????4??×?·??ù?°????????????
    ...

数组流

流的源和目标是计算机内存

字节数组输入流 ByteArrayInputStream 和字节数组输出流 ByteArrayOutputStream

对应字符数组流 CharArrayReaderCharArrayWriter

数据流

允许程序按着机器无关的风格读取Java原始数据。

DateInputStreamDateOutputStream 数据输入流和数据输出流

示例


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class PasswordTest {
    public static void main(String[] args) {
        String sourceString = "Kimi一路走好";
        EncryptAndDecrypt person = new EncryptAndDecrypt();
        System.out.println("输入密码加密:" + sourceString);
        Scanner scanner = new Scanner(System.in);
        String password = scanner.nextLine();
        String secret = person.encrypt(sourceString, password);
        File file = new File("secret.txt");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            DataOutputStream outData = new DataOutputStream(fos);
            outData.writeUTF(secret);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("密文:" + secret);
        // 解密
        System.out.println("输入解密密码:");
        password = scanner.nextLine();
        try {
            FileInputStream fis = new FileInputStream(file);
            DataInputStream inData = new DataInputStream(fis);
            String str = inData.readUTF();
            String mingwen = person.decrypt(str, password);
            System.out.println("解密命令:" + mingwen);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
输入密码加密:Kimi一路走好
Tiger
密文:????乲蹃跙姤
输入解密密码:
Tiger
解密命令:Kimi一路走好

对象流

ObjectInputStreamObjectOutputStream 类创建的对象称作对象输入流和对象输出流。
有涉及对象序列化

    FileOutputStream fileOut = new FileOutputStream(file);
    ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);

示例

TV.java

import java.io.Serializable;

public class TV implements Serializable{
    String name;
    int price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }

}

ObjectStream.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectStream {
    public static void main(String[] args) {
        TV TCL = new TV();
        TCL.setName("TCL电视");
        TCL.setPrice(5500);
        File file = new File("television.txt");
        try {
            FileOutputStream fileOut = new FileOutputStream(file);
            ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
            objectOut.writeObject(TCL);
            objectOut.close();

            FileInputStream fileIn = new FileInputStream(file);
            ObjectInputStream objectIn = new ObjectInputStream(fileIn);
            TV xiaomi = (TV) objectIn.readObject();
            objectIn.close();
            xiaomi.setName("小米电视");
            xiaomi.setPrice(2444);
            System.out.println("TCL的名字:" + TCL.getName());
            System.out.println("TCL的价格:" + TCL.getPrice());
            System.out.println("xiaomi的名字:" + xiaomi.getName());
            System.out.println("xiaomi的价格:" + xiaomi.getPrice());

        } catch (ClassNotFoundException e) {
            System.out.println("不能读出对象");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
TCL的名字:TCL电视
TCL的价格:5500
xiaomi的名字:小米电视
xiaomi的价格:2444

序列化与对象克隆

A one = new A();
A two = one;
..
two.x = 100;//则one.x的值也是100

有时想得到对象的一个”复制品”,复制品的实体的变化不会引起原对象实体发生变化,反之亦然。这样的复制品称为 原对象的一个克隆对象。上个例子中的xiaomi 就是TCL的一个克隆。

当程序想比较快的速度获取一个对象的克隆时,可以用对象流将对象的序列化信息写入内存中,而不是磁盘的文件中。

    FileOutputStream fileOut = new FileOutputStream(file);
    ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
    和
    FileInputStream fileIn = new FileInputStream(file);
    ObjectInputStream objectIn = new ObjectInputStream(fileIn);

    替换为
    ByteArrayOutputStrem outByte = new ByteArrayOutputStream();
    ObjectOutputStream objectOut = new ObjectOutputStream(outByte);
    和
    ByteArrayInputStrem inByte = new ByteArrayInputStream();
    ObjectInputStream objectInt= new ObjectInputStream(inByte);

文件锁

java.io.channels 包中的FileLockFileChannel 类的对象实现文件锁操作。

示例

书中的程序,多次查找后,会删除文件内容

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Scanner;
/**
 * 文件锁
 * @author Peng
 *
 */
public class MyFileLock {
    public static void main(String[] args) {
        File file = new File("FileStream2.java");//默认项目目录下要有文件
        Scanner scanner = new Scanner(System.in);
        try {
            RandomAccessFile input = new RandomAccessFile(file, "rw");
            FileChannel channel = input.getChannel();
            FileLock lock = channel.tryLock();// 加锁
            System.out.println("输入要读取的行数:");
            while(scanner.hasNextInt()){
                int m = scanner.nextInt();
                lock.release(); //解锁
                for(int i= 1;i<=m;i++){
                    String str = input.readLine();
                    System.out.println(str);
                }
                lock = channel.tryLock();   //加锁
                System.out.println("输入要读取的行数:");
            }
        } catch (IOException e) {

        }
    }
}
输入要读取的行数:
2
package com.file.????×????÷;

输入要读取的行数:
3
import java.io.*;

public class Fileinputstream2 {
输入要读取的行数:
4
    public static void main(String[] args) throws Exception {
        int n = -1;
        byte[] a = new byte[1000];//[100]or[1024]??????????????×??ó×?????
        File file = new File("FileStream2.java");// ??????????????????
输入要读取的行数:
5
        //File file = new File("D:\\eclipse\\workspace\\IO\\src\\com\\file\\FileStream2.java");

        FileInputStream in = new FileInputStream(file);
        while((n=in.read(a,0,1000))!=-1){
            String s = new String(a,0,n);
输入要读取的行数:
6
            System.out.println(s);
        }
        in.close(); 
    }
}
null
输入要读取的行数:

7
null
null
null
null
null
null
null
输入要读取的行数:

使用Scanner解析文件

这里只是要到File 类,可以解析文件,与之前解析字符串类似。

示例-默认分隔符

cost.txt

TV cost 876 dollar.Computer cost 2398 dollar.telephone cost 1278 dollar

MyScanner.java

import java.io.File;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class MyScanner {
    public static void main(String[] args) {
        File file = new File("cost.txt");
        Scanner scanner = null;
        try {
            scanner = new Scanner(file);
        double sum = 0;

        while(scanner.hasNext()){
            try {
                double price = scanner.nextDouble();
                sum = sum +price;
                System.out.println(price);
            } catch (InputMismatchException e) {
                String t =scanner.next();
            }   
        }
        System.out.println("总消费:"+sum+"元");

        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
    }
}
876.0
2398.0
1278.0
总消费:4552.0

示例-使用正则表达式分隔符

cost2.txt

话费清单:市话费32.32元,长途话费23.3元,短信费18元

MyScanner2.java

import java.io.File;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class MyScanner2 {
    public static void main(String[] args) {
        File file = new File("cost2.txt");
        String regex = "[^0123456789.]+";
        Scanner scanner;
        try {
            scanner = new Scanner(file);

        scanner.useDelimiter(regex);
        double sum = 0;
        while(scanner.hasNext()){
            try {
                double price = scanner.nextDouble();
                sum = sum +price;
                System.out.println(price);
            } catch (InputMismatchException e) {
                String t =scanner.next();
            }   
        }
        System.out.println("总通信费用:"+sum+"元");
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
    }
}
32.32
23.3
18.0
总通信费用:73.62

使用Console流读取密码

示例

这个程序在eclipse上运行不了,因为以Javaw所执行的应用程式(eclipse)没有主控制台(console),所以取不到console物件,System.console()只能是null了

import java.io.Console;

public class ConsolePw {
     public static void main(String[] args) {
        boolean success = false;
        int count = 0;
        Console cons;
        char [] passwd;
        cons = System.console();
        if(cons==null){
            System.out.println("cons为空");
        }
        while(true){
            System.out.println("输入密码:");
            passwd = cons.readPassword();
            count++;
            String password = new String(passwd);
            if(password.equals("Tiger123")){
                success = true;
                System.out.println("您第"+count+"次输入密码正确!");
                break;
            }else{
                System.out.println("您第"+count+"次输入密码"+password+"不正确!");
            }
            if(count ==3){
                System.out.println("您3次输入密码都不正确");
                System.exit(0);
            }
        }
        if(success){
            System.out.println("你好!欢迎你!");
        }
    }
}
cons为空
输入密码:
Exception in thread "main" java.lang.NullPointerException
    at com.console.ConsolePw.main(ConsolePw.java:17)

在cmd控制台可以运行

D:\javafile>javac ConsolePw.java
D:\javafile>java ConsolePw
输入密码:

您第1次输入密码jj不正确!
输入密码:

您第2次输入密码正确!
你好!欢迎你!
D:\javafile>

参考

博客http://www.cnblogs.com/kyxyes/archive/2013/02/16/2913424.html
《Java程序实用教程》










以上是关于Java笔记-输入输出流的主要内容,如果未能解决你的问题,请参考以下文章

Java学习笔记6.1.1 字节流 - 数据字节输入流与数据字节输出流

Java学习笔记6.1.2 字节流 - 文件字节输入流和文件字节输出流

Java学习笔记6.1.2 字节流 - 文件字节输入流和文件字节输出流

Java学习笔记6.2.1 字符流 - 文件字符流与缓冲字符流

Java学习笔记6.2.1 字符流 - 文件字符流与缓冲字符流

Java笔记:Java 流(Stream)文件(File)和IO