Java的IO技术初窥
1. File类 :
java.io包中封装了用于输入/输出的类。File类是I/O包中唯一代表磁盘本身的。
例子1.:
public static void main(String[] args) {
File file = new File("E://text//word.txt"); //创建文件对象
if (file.exists()) { //判断该文件是否存在
String name = file.getName(); //获取文件名称
String parent = file.getParent(); //获取文件父路径
long leng = file.length(); //获取文件长度
boolean bool = file.canWrite(); /判断该文件是否可改写
System.out.println("文件名称为:" + name); //输出信息
System.out.println("文件目录为:" + parent);
System.out.println("文件大小为:" + leng + " bytes");
System.out.println("是否为可改写文件:" + bool);
}
}
public static void main(String[] args) {
File dir = new File("E://text"); // 根据指定的文件路径,创建文件对象
if (dir.isDirectory()) { // 如果该文件对象指定的是一个目录
File[] files = dir.listFiles(); // 获取该目录下的抽象路径名数组
for (int i = 0; i < files.length; i++) { // 循环遍历该数组
File file = files[i]; // 获取数据中的元素
System.out.println("第" + (i + 1) + "个文件的名称是:"
+ file.getAbsolutePath());
}
}
}
2. 字节输出和输入流 :
字节流用于处理二进制数据的读取与写入,以字节为单位。InputStream类和OutputStream类是字节流的抽象类,它们定义了数据流读取和写入的基本方法。
1.InputStream类(读取)
InputStream类是字节输入流的抽象类,是所有字节输入流 的父类。它定义了操作输入流的各种方法。
public static void main(String[] args) {
InputStream is = System.in; // 定义InputStream对象
try {
byte[] bs = new byte[1024]; // 创建数组
int len = is.read(bs); // 从输入流中读取数据
System.out.println("控制台输入的内容:" + new String(bs).trim());
// 将读取内容在控制台上输出
is.close(); // 关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
read public int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个字节数组中。在某些输入可用之前,此方法将阻塞。
public static void main(String[] args) {
OutputStream out = System.out; // 实例化OutputStream类
try {
byte[] bs = "本实例使用OutputStream输出流,在控制台输出字符串\n".getBytes();
// 创建byte数组
out.write(bs); // 向流中写数据
bs = "输出内容:\n".getBytes();
out.write(bs);
bs = " 《Java从基础到项目实战》学好Java的必备书".getBytes();
out.write(bs);
out.close(); // 关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
3.FileInputStream类
代码如下:
public static void main(String[] args) {
File file = new File("E:\\text\\word.txt"); // 创建文件对象
try {
FileInputStream fis = new FileInputStream(file); // 创建FileInputStream类对象
int lenght;
byte by[] = new byte[1024]; // 创建byte对象
while ((lenght = fis.read(by)) != -1) { // 循环读取文件中数据
String str = new String(by, 0, lenght); // 根据读取信息创建字符串对象
System.out.println("从文件中读取出的数据是: " + str); // 输出信息
}
} catch (Exception e) {
e.printStackTrace();
}
}
代码如下:
public static void main(String[] args) {
try {
File file = new File("E://text//writeFile.txt"); // 创建文件对象
if (!file.exists()) { // 如果该文件不存在
file.createNewFile(); // 新建文件
}
FileOutputStream fos = new FileOutputStream(file); // 创建FileOutputStream实例
byte[] bytes = "Java 编程词典软件,学Java必备。".getBytes(); // 创建字节数组
fos.write(bytes); // 向文件中写数据
} catch (Exception e) {
e.printStackTrace();
}
}
代码:
public static void main(String[] args) {
try {
File file = new File("E://text//writeFile.txt"); // 创建文件对象
FileInputStream fin = new FileInputStream(file); // 创建FileInputStream对象
BufferedInputStream bip = new BufferedInputStream(fin); // 创建BufferedInputStream对象
int count = 0;
bip.mark(50); // 在输入流中定义指标记位置
for (int i = 0; i < 10; i++) { // 在循环中读取文件内容
count++;
int read = bip.read(); // 读取文件内容
if (count % 5 == 0)
bip.reset(); // 将流定位到最后一次调用mark()方法事的位置
System.out.print((char) read + " "); // 将读取的内容输出
}
bip.close(); // 关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
File file = new File("F://Getif.txt"); // 创建文件对象
if (!file.exists()) { // 如果该对象不存在
file.createNewFile(); // 新建文件
}
FileOutputStream fos = new FileOutputStream(file); // 创建FileOutputStream对象
BufferedOutputStream bus = new BufferedOutputStream(fos); // 创建BufferedOutputStream对象
byte[] by = "香蕉 ".getBytes(); // 创建字节数组
bus.write(by); // 向流中写数据
byte[] by2 = "苹果 ".getBytes();
bus.write(by2);
byte[] by3 = "橘子 ".getBytes();
bus.write(by3);
bus.flush(); // 刷新缓存输入流
bus.close(); // 关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
数据输入流允许应用程序以与机器无关方式从底层输入流中读取其中的java数据类型。
8.DataInputStream类
数据输出流允许应用程序以适当的方式将基本Java类型写入输出流。
public static void main(String[] args) {
try {
File file = new File("E:\\word.txt");
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fs = new FileOutputStream(file); // 创建FileOutputStream对象
DataOutputStream ds = new DataOutputStream(fs); // 创建DataOutputStream对象
ds.writeUTF("使用writeUTF()方法写入数据;" + " "); // 写入磁盘文件数据
ds.writeChars("使用writeChars()方法写入数据;" + " ");
ds.writeBytes("使用writeBytes()方法写入数据.");
fs.close(); // 将流关闭
FileInputStream fis = new FileInputStream("E:\\word.txt"); // 创建FileInputStream对象
DataInputStream dis = new DataInputStream(fis); // 创建DataInputStream对象
System.out.print(dis.readUTF()); // 将文件数据输出
fis.close();
} catch (Exception e) {
e.printStackTrace(); // 输出异常信息
}
}
3. 字符输出和输入流 :
使用字节流读取和写入数据时,由于汉字在文件中占有两个字节,可能会出现乱码的现象。使用字符输入输出可以避免这个现象。
字符流与字节流的区别是:字节流以字节为单位传送数据,可以说是任何类型的数据。而字符流以字符为单位传送数据,只能传送文本类型的数据。
1.Reader类
例子:
public static void main(String[] args) {
InputStreamReader rin = new InputStreamReader(System.in); // 创建Reader子类InputStreamReader实例
try {
char[] cs = new char[100]; // 创建字符数组
rin.read(cs); // 向流中读取数据
String str = new String(cs); // 根据读取内容创建字符串
System.out.println("输入的字符串内容:\n" + str.trim()); // 控制台上输出内容
rin.close(); // 关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
2.Writer类
public static void main(String[] args) {
try {
Writer out = new PrintWriter(System.out); // 创建PrintWriter实例
char[] cs = "本实例使用字符输出流,在控制台输出字符串".toCharArray(); // 创建字符数组
out.write(cs); // 向流中写数据
out.close(); // 将流关闭
} catch (IOException e) {
e.printStackTrace();
}
}
3.FileReader类
代码如下:
public static void main(String[] args) {
File file = new File("E://word.txt");// 创建文件对象
try {
FileReader fReader = new FileReader(file); // 创建FileReader实例
int length;
while ((length = fReader.read()) != -1) { // 循环读取指定文件内容
System.out.print((char) length);
}
fReader.close(); // 关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
4.FileWriter类
public static void main(String[] args) {
char chars[] = "登录密码是:mrsoft".toCharArray();// 定义写入文件的字符数组
int n = 0, m = 0;
File file = new File("E://word.txt"); // 写入信息的文件
for (int i = 0; i < chars.length; i++) { // 将信息加密后写入文件
chars[i] = (char) (chars[i] ^ 'A');
}
try {
FileWriter fileWriter = new FileWriter(file); // 创建FileWriter对象
fileWriter.write(chars, 0, chars.length); // 向文件写数据
fileWriter.close(); // 将流关闭
FileReader fileReader = new FileReader(file); // 创建FileReader对象
char tom[] = new char[1024];
while ((n = fileReader.read(tom)) != -1) { // 循环读取指定文件中内容
String str = new String(tom, 0, n); // 创建字符串对象
m = n;
System.out.println("密文:" + str); // 将加密后的文件输出
}
fileReader.close(); // 将流关闭
for (int j = 0; j < m; j++) {
tom[j] = (char) (tom[j] ^ 'A'); // 获取解密后数据
}
String ss = new String(tom, 0, m);
System.out.println("明文:" + ss);
} catch (Exception e) {
e.printStackTrace();
}
}
5.Scanner类
public static void main(String[] args) {
String input = "1 and 2 and yellow and blue and"; // 定义要进行扫描的字符串
Scanner scanner = new Scanner(input); // 创建Scanner实例
scanner.findInLine("(\\d+) and (\\d+) and (\\w+) and (\\w+)"); // 查找指定字符串
MatchResult result = scanner.match(); // 执行扫描操作,返回匹配结果
for (int i = 1; i <= result.groupCount(); i++)
// 循环遍历扫描后的结果
System.out.println(result.group(i)); // 将扫描后的结果输出
scanner.close(); // 关闭扫描器,释放资源
}
6.PrintWriter类
Sysetm.out是PrintWriter类的一个实例对象,提供了一系列的print(),prntln()方法。
4. Java IO 的一般使用原则 :
一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
二、按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter
三、按是否要缓冲分:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )
四、按数据格式分:
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类
五、按输入输出分:
1 、输入: Reader, InputStream 类型的子类
2 、输出: Writer, OutputStream 类型的子类
六、特殊需要:
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
2 、对象输入输出: ObjectInputStream, ObjectOutputStream
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合并输入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要) :
首先,考虑最原始的数据格式是什么: 原则四
第二,是输入还是输出:原则五
第三,是否需要转换流:原则六第 1 点
第四,数据来源(去向)是什么:原则一
第五,是否要缓冲:原则三 (特别注明:一定要注意的是 readLine() 是否有定义,有什么比 read, write 更特殊的输入或输出方法)
第六,是否要格式化输出:原则二