java io 基础使用
Posted mlover
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java io 基础使用相关的知识,希望对你有一定的参考价值。
记录一下 java io 基本的使用 以及 编码相关的知识
不得不说,java io 相关的类好多呀,每次看都感觉有些乱,暂时也不打算了解太多,先学习一部分,能够进行基本操作,能用就行。
图片来源 https://www.codercto.com/courses/d/1491.html
java io 别人写的一系列教程
java io 相关的类主要可以区分为 字符型 和 字节型
这方面我也是在别的博客上学习的,就是上面的图片描述的,感觉按照这两种方式区分的话就比较容易理解
在 io 方面,我还是比较喜欢 c/c++ 语言的处理方式,用一个 char 型就可以解决所有问题,虽然这种方式可能没有 java io 使用方便
下面还是简要说一下 字符型和字节型 io 的区别
字节型 io,就是读写时以字节为基本单位。计算机中的一切,在本质上,都是 2 进制表示的
对于基础的 ascii 码,需要使用一个字节(8位2进制)直接来表示,我们从文件中能读取的基本单位就是字节。
这里我们或许可以考虑一下为什么不是 bit,而是 byte,(个人理解,使用 bit 的话,只有两种状态,不足以区分基础的可显示字符,也就是 ascii 码,使用字节的话就比较方便,一次取出 8 bit,这就很容易地通过值区分不同的字符,还有一个原因,应该和计算机内存的最小单位也是字节有关系)字符型 io,相比于 字节型,可以认为是编程语言帮你多做了一步,它会依次读取字节,根据编码表,如果判断不是一个有效字符的话,就会继续读,直到形成一个有效的字符。这和编码方式有关系。举个将常见的例子,汉字在不同的编码中占用的字节数目是不同的,汉字 以
GBK
方式编码时,占用 2 个字节,以utf-8
编码时,占用 3 个字节。所以在这两种情形下,我们就可以描述一下 java 的 字符型 io 的工作,当java 读取汉
的第一个字节时,在GBK
的编码表中找不到这个字节对应的字符,那它就还要再向后读,又会读出一个字节,和前一个字节合并再去查编码表,找到对应的字符是汉
字,其实到这里并没有结束,因为 java 的 char 使用 2字节表示一个字符,所以 java内部 还需要根据汉
字找到其对应的 char 值(个人理解,感觉越说越麻烦)。其他编码也是相同。
为了说明一下 二者的关系,用一个简短 c 语言程序说明一下,这里会看到 控制台就类似 java 进行 字符 io 时的解码操作
#include <stdio.h>
#include <string.h>
int main()
{
const char* str = "汉字";
int len = strlen(str);
printf("len is %d
", len);
// 以 char 形式 逐个输出
for (int i = 0; i < len; i++) {
printf("%c", str[i]);
}
puts("");
return 0;
}
- 新建一个 test.c,设置编码格式为
GBK
, 正常情形下,在 windows 控制台上的输出结果是len = 4
,然后输出汉字
如果我们把 在控制台 输入chcp 65001
, 将控制台的活动代码页修改为 utf-8,即让控制台以 utf-8 解码输出的字节流,可以观察到输出了len = 4
,汉字
没有输出或者输出是乱码符号。(请注意程序应该在当前修改过活动页的窗口中运行,因为我们的修改只是单次有效) - 同上,这次我们将文本的编码格式 设置为
utf-8
,同样测试,可以发现,当控制台将活动代码页修改为utf-8
使,才能正常输出结果,同时能够看到len = 6
还是给自己记录一下,如果可以使用 linux 的 xxd 工具的话,可以使用这个工具查看不同编码下字符的二进制表示,首先,我们可以确定,对于 GBK
和 utf8
,汉字在文本中的表示是不同的,对于 c 语言,它并不关心文本的编码方式,所以它会将所有二进制读取,进行编译,输出时也是将文本中对应的二进制输出来,显示结果不同的原因在于控制台的解码方式。java 字符 io 也是如此。
记录一下学习的 io 操作
- 字符 io 读写文件
package Learn.Io;
import java.io.*;
public class DemoFirst {
/**
* 按字符依次读取
*/
void readForeach() throws IOException {
final int MAX_SIZE = 1024; // 如果不能估计 文件字符个数,最好不要使用常量
char[] save = new char[MAX_SIZE];
FileReader in = new FileReader("./File/test.txt");
int charValue, count = 0;
while (-1 != (charValue = in.read())) {
save[count++] = (char) charValue;
}
in.close();
System.out.println(String.valueOf(save, 0, count));
}
/**
* 一次性读取到 char 数组中
* @throws IOException
*/
void readOnce() throws IOException {
final int MAX_SIZE = 1024;
FileReader in = new FileReader("./File/test.txt");
char[] data = new char[MAX_SIZE];
int num = in.read(data);
in.close();
System.out.println(String.valueOf(data, 0, num));
}
/**
* 字符方式写入文件
* @throws IOException
*/
void write() throws IOException {
// 文件内容会被清除
FileWriter out = new FileWriter("./File/test.txt");
String str = "待写入字符";
char[] s = {'测', '试', '一', '下'};
out.write(str);
out.write(s, 0, 2);
out.flush();
out.close(); // 关闭时会进行一次 flush 不过还是显式写一下比较好
}
public static void main(String[] args) throws IOException{
DemoFirst test = new DemoFirst();
test.readForeach();
test.readOnce();
test.write();
}
}
- 字节方式 读写文件
package Learn.Io;
import java.io.*;
public class ioByChar {
File file = new File("./File/test.txt");
/**
* 循环处理文本
* @throws IOException
*/
void readForeach() throws IOException {
InputStream read = new FileInputStream(file);
int byteValue, count = 0;
byte[] data = new byte[1024];
while (-1 != (byteValue = read.read())) {
data[count++] = (byte) byteValue;
}
System.out.println(new String(data, 0, count));
}
/**
* 一次将文本全部加载到 内存
* @throws IOException
*/
void readOnce() throws IOException {
InputStream in = new FileInputStream(file);
byte[] data = in.readAllBytes();
System.out.println(new String(data, 0, data.length));
}
/**
* 按字节写入
* @throws IOException
*/
void write() throws IOException {
OutputStream out = new FileOutputStream(file);
String str = "写入文本";
byte[] data = str.getBytes();
out.write(data, 0, data.length);
out.flush();
out.close();
}
/**
* 复制文件 //
* @param src 源文件
* @param dst 目的文件
* @throws IOException
*/
void copy(File src, File dst) throws IOException {
InputStream a = new FileInputStream(src);
OutputStream b = new FileOutputStream(dst, true);
a.transferTo(b);
a.close();
b.close();
}
public static void main(String[] args) throws IOException {
ioByChar test = new ioByChar();
test.readForeach();
test.readOnce();
test.write();
test.copy(new File("./File/src.txt"), new File("./File/dst.txt"));
}
}
- buffered io
buffer io 相对于 普通 io 相当于加了一层包装,使用缓冲区避免多次访问文件,方法基本和非缓存一样
package Learn.Io;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 这里只写了 BufferedReader BufferedWriter
* 还有 BufferedInputStream 和 BufferedOutputStream
*/
public class bufferIo {
static final String filePath = "./File/test.txt";
/**
* 按行处理
* @throws IOException
*/
void lineRead() throws IOException {
// BufferedInputStream 不能按行处理
BufferedReader charRead = new BufferedReader(new FileReader(filePath));
String read;
List<String> data = new ArrayList<>();
while (null != (read = charRead.readLine())) {
data.add(read);
}
System.out.println(data.toString());
charRead.close();
// 使用 Stream 处理
// BufferedReader ano = new BufferedReader(new FileReader(filePath));
// ano.lines().map((e) -> e + '|' + e.length()).forEach(System.out::println);
// ano.close();
}
/**
*
* @throws IOException
*/
void Write() throws IOException {
BufferedWriter out = new BufferedWriter(new FileWriter(filePath));
out.write("line 1");
out.newLine();
out.write("line 2");
out.flush();
out.close();
}
public static void main(String[] args) throws IOException {
bufferIo s = new bufferIo();
s.lineRead();
s.Write();
}
}
- 根据指定编码读写文件
package Learn.Io;
import java.io.*;
public class fileIo {
/**
* 读取指定编码的文件
* 这里关心文件的编码 所以使用 Reader 和 Writer
* @param filePath 文件路径
* @param encoding 文件编码
*/
void read(String filePath, String encoding) throws IOException {
File file = new File(filePath);
InputStreamReader in = new InputStreamReader(new FileInputStream(file), encoding);
char[] data = new char[1024];
in.read(data);
in.close();
System.out.println(data);
}
/**
* 使用 bufferIo 读取
* @param filePath
* @param encoding
* @throws IOException
*/
void bufferRead(String filePath, String encoding) throws IOException {
File file = new File(filePath);
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
// Stream 很方便
in.lines().forEach(System.out::println);
in.close();
}
/**
* 字节流读取,使用 String 解码
* 这种方式没有 字符流安全,按字节读取有可能读取到某个字符的一部分就终止了
* 这时如果使用 字符集去解码,就会造成问题
* 如果是要将文件整体读入,作为一个字符串处理,则可以用这种方式
* @param filePath
* @param encoding
*/
void byteRead(String filePath, String encoding) throws IOException {
File file = new File(filePath);
InputStream in = new FileInputStream(file);
byte[] data = in.readAllBytes();
System.out.println(new String(data, encoding));
}
/**
* 输出与上述相反,Reader <=> Writer Input <=> Output 就不写了
*/
void write() {
}
public static void main(String[] args) throws IOException {
fileIo rw = new fileIo();
rw.read("./File/test.txt", "gbk");
rw.read("./File/test.txt", "gbk");
}
}
- 格式化数据
package Learn.Io;
import java.io.*;
import java.util.stream.IntStream;
public class formatIo {
/**
* 利用 printf 格式化数据写入文件
* @throws FileNotFoundException
*/
void writeFormatDataToFile() throws FileNotFoundException {
PrintWriter out = new PrintWriter("./File/test.txt");
IntStream.range(0, 10).forEach(e -> out.printf("number of this line is %3d
", e));
out.flush();
out.close();
}
/**
* 格式化数据输入 字符串
* @throws IOException
*/
void formatDataToString() throws IOException {
StringWriter str = new StringWriter();
PrintWriter w = new PrintWriter(str);
w.printf("10 的 16进制表示 : %#06x", 10);
w.flush();
w.close();
str.close();
System.out.println(str);
}
public static void main(String[] args) throws IOException {
formatIo rw = new formatIo();
rw.writeFormatDataToFile();
rw.formatDataToString();
}
}
- 其他一些
package Learn.Io;
import java.io.*;
public class vector {
/**
* 感觉 java 中的 ByteArrayOutputStream CharArrayWriter 实现的功能类似 c++ 中的 vector
* @throws IOException
*/
void readIntoByteArray() throws IOException {
InputStream in = new FileInputStream("./File/test.txt");
ByteArrayOutputStream data = new ByteArrayOutputStream();
int num;
while (-1 != (num = in.read())) {
data.write(num);
}
in.close();
System.out.println(data);
}
/**
* 使用 StringReader 和 StringWriter
* @throws IOException
*/
void rwString() throws IOException {
String str = "this is a string";
StringReader in = new StringReader(str);
StringWriter out = new StringWriter();
PrintWriter w = new PrintWriter(out);
w.println("first line");
in.transferTo(out); // 输入流传送到输出流
in.close();
out.close();
System.out.println(str);
System.out.println("---------------");
System.out.println(out);
}
public static void main(String[] args) throws IOException {
vector s = new vector();
s.readIntoByteArray();
s.rwString();
}
}
还有一些还没学...
以上是关于java io 基础使用的主要内容,如果未能解决你的问题,请参考以下文章
iOS开发CGRectGetMidX. CGRectGetMidY.CGRectGetMinY. CGRectGetMaxY. CGRectGetMinX. CGRectGetMaxX的使用(代码片段
iOS开发CGRectGetMidX. CGRectGetMidY.CGRectGetMinY. CGRectGetMaxY. CGRectGetMinX. CGRectGetMaxX的使用(代码片段