文件基础操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) throws IOException {
//创建一个hello的目录
File dir = new File("hello");
if(!dir.exists()){
dir.mkdirs();
}
//在hello目录下创建一个hello.txt文件
File file = new File(dir+"/hello.txt");
if(!file.exists()){
file.createNewFile();
}
//得到文件名
System.out.println(file.getName());
//得到文件的绝对路径
System.out.println(file.getAbsolutePath());
//得到文件的规范路径,当路径不规范时,会进行优化(去掉.)
System.out.println(file.getCanonicalPath());
//得到父目录名
System.out.println(file.getParent());
}

具体详见:File (Java Platform SE 8 ) (oracle.com)

IO流

IO即输入和输出(Input、Output),输入就是将数据读入到内存,输出就是将数据输出到外部存储(如文件、数据库)。数据的输入输出就像水流一样,因此成为IO流。

IO流的处理方式可分为两种:字节流和字符流。Java中针对IO流的处理有很多类,但最基本的只有4个抽象类。InputStreamOutputStreamReaderWriter,前两个是对字节流的输入输出,后两个是对字符流的输入输出。下面我们拿普通文件的读写举例,介绍它们的基本操作。

字节流

InputStream

用于对文件进行读操作,构造方法内可以是一个文件类型的参数,也可以是一个文件路径(字符串)的参数。

常用方法:

read() :一次读取一字节,返回输入流中下一个字节的数据。返回的值介于 0 到 255 之间。返回 -1 ,表示读到文件的末尾,读取结束。

read(byte b[ ]) : 一次读取多个字节,将输入流字节存储到数组b,返回结果为读取字节长度。返回-1,表示读到文件的末尾,读取结束。

read(byte b[], int off, int len) :在read(byte b[ ]) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)。

close() :关闭输入流释放相关的系统资源。

  • 一次读取一字节
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private static void readOne(File file,FileInputStream fileInputStream) throws IOException {
try {
fileInputStream = new FileInputStream(file);
while(true){
int read = fileInputStream.read();
if(read==-1){
break;
}
System.out.print((char)read);
}

} catch (IOException e) {
e.printStackTrace();
} finally {
fileInputStream.close();
}
}
  • 一次读取多个字节
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static void readByte(File file,FileInputStream inputStream){
try {
inputStream = new FileInputStream(file);
while(true){
byte[] bytes = new byte[1024];
int read = inputStream.read(bytes);
if(read==-1){
break;
}
for (int i = 0; i < read; i++) {
System.out.print((char)bytes[i]);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
inputStream.close();
}
}
OutputStream

用于对文件进行写操作,构造方法内可以是一个文件类型的参数,也可以是一个文件路径(字符串)的参数,同时可以指定第二个参数表示是否追加写入(是否清空之前的内容),true表示追加写入,默认为false。

在写操作时数据暂时放在缓存区,只有缓存区满后才会真正写入到设备,所以别忘了调用fulsh(),防止数据没有写入设备。

常用方法:

write(int b) :将特定字节写入输出流。

write(byte b[ ]) : 将数组b 写入到输出流,等价于 write(b, 0, b.length)

write(byte[] b, int off, int len) : 在write(byte b[ ]) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)。

flush() :刷新此输出流并强制写出所有缓冲的输出字节。

close() :关闭输出流释放相关的系统资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void writeOne(File file, FileOutputStream outputStream) throws IOException {
try {
outputStream = new FileOutputStream(file);
outputStream.write(103);
outputStream.write(104);
outputStream.flush();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
outputStream.close();
}
}

字符流

字节是电脑中存储信息的基本单位,那为什么还需要字符流呢?

当存储信息中有中文时,以字节流来读取会出现乱码。字节流更适用于音频、图片等类型文件,当文件中涉及字符类型时,使用字符流更好。字符流默认编码是unicode

常见的字符编码:utf8 :英文占 1 字节,中文占 3 字节,unicode:任何字符都占 2 个字节,gbk:英文占 1 字节,中文占 2 字节。

Reader

常用方法:

read() : 从输入流读取一个字符。

read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中,等价于 read(cbuf, 0, cbuf.length)

read(char[] cbuf, int off, int len) :在read(char[] cbuf) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)。

close() : 关闭输入流并释放相关的系统资源。

  • 一次读取一个字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private static void readOne(File file,Reader reader){
try {
reader = new FileReader(file);
while(true){
int read = reader.read();
if(read==-1){
break;
}
System.out.print((char)read);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
reader.close();
}
}
  • 一次读取多个字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static void readCharacter(File file,Reader reader) throws IOException {
try {
reader = new FileReader(file);
char[] buffer = new char[1024];
while(true){
int read = reader.read(buffer);
if (read==-1){
break;
}
String s = new String(buffer,0,read);
System.out.println(s);
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
reader.close();
}
}
Writer

常用方法:

write(int c) : 写入单个字符。

write(char[] cbuf) :写入字符数组 cbuf,等价于write(cbuf, 0, cbuf.length)

write(char[] cbuf, int off, int len) :在write(char[] cbuf) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)。

write(String str) :写入字符串,等价于 write(str, 0, str.length())

write(String str, int off, int len) :在write(String str) 方法的基础上增加了 off 参数(偏移量)和 len 参数(要读取的最大字节数)。

append(CharSequence csq) :将指定的字符序列附加到指定的 Writer 对象并返回该 Writer 对象。

append(char c) :将指定的字符附加到指定的 Writer 对象并返回该 Writer 对象。

flush() :刷新此输出流并强制写出所有缓冲的输出字符。

close():关闭输出流释放相关的系统资源

1
2
3
4
5
6
7
8
9
10
private static void writeOne(File file,Writer writer) throws IOException {
try {
writer = new FileWriter(file);
writer.write("我是panghutx");
} catch (IOException e) {
e.printStackTrace();
}finally {
writer.close();
}
}