Java流分类
流按照操作数据分为两种:字节流(stream)和字符流
具体分类:
字节流的抽象基类:InputStream OutputStream
字符流的抽象基类:Reader Writer
输入流和输出流(InputStream OutPutStream):输入流只能进行读操作,输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
Java IO流的具体分类与实现
java文件操作
1、在D盘创建一个文件
2、定义读取流
3、将字符转化为字节,写入文件中
4、刷新输出流,关闭资源
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
public class FileIo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
File file = new File("D:/a.txt");
FileOutputStream fos = new FileOutputStream(file); //字节流操作 写入数据
byte[]b = "字符test".getBytes();
fos.write(b, 0,b.length);
fos.flush();
fos.close();
FileWriter fw = new FileWriter("D:/b.txt"); //字符流向文件中 写入数据
fw.write("字符test");//调用write方法,将字符串写入到流中
fw.flush();
fw.close();
}
}
File file = new File("D:/a.txt"); //新建一个文件 如果向原有文件中插入数据 File file = new File("D:/a.txt",true);
java IO编码问题
如果采用字节输出流把字节输出到某个文件,无法指定生成文件的编码的(假设文件以前不存在),那么生成的文件是什么编码?
经过测试发现,其实这取决于写入的字节编码格式。比如以下代码:
OutputStream out = new FileOutputStream("d:\\demo.txt");
out.write("我们".getBytes());
getBytes()会采用操作系统默认的字符集来编码字节,这是GBK,写入demo.txt文件的是GBK编码的字节。那么这个文件的编码就是GBK。
修改一下程序:out.write("我们".getBytes(“UTF-8”));若写入的字节就是UTF-8的,那么demo.txt文件编码就是UTF-8。
如果把“我们”换成123或abc之类的ascii码字符,那么无论是采用getBytes()或者getBytes(“UTF-8”)那么生成的文件都将是GBK编码的。
即,InputStream中的字节编码取决文件本身的编码,而OutputStream生成文件的编码取决于字节的编码。
字节流与字符流的转换
字节流转换成字符流可以用InputSteamReader、OutputStreamWriter转换成BufferdReader、 BufferedWriter具有缓冲区。
具体实现:
读取文件 从字节流输入到字符流输入定义一个字节流:
FileInputStream fileInputStream = new FileInputStream("d:\\text.txt"); // 定义一个指向D:/TEXT.TXT 的字节流
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); //字节流转换成InputStreamReader
BufferedReader bufferedReader = new BufferedReader(inputSteamReader); //InputStreamReader 转换成带缓存的bufferedReader
写入文件从字节流输出到字符流输出
FileOutputStream fileOutputStream = new FileOutputStream("d:/text.txt"); //定义一个指向D:/TEXT.TXT文件
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
bufferedWriter.write(s); //将字符s写入到文件中
bufferedWriter.close();
outputStreamWriter.close();
fileOutputStream.close();
PS:java跨平台行,而在windows和linux中的目录分隔符是不同的。windows是"\" 而linux是"/" 在Java程序涉及路径时(linux下 "\n" 表示换行,win下 "\n" 表示换行 "\r" 回车)
可采用File.separator作为文件夹分隔符,或者使用C:/text.txt (使用反斜杠 在windows中会自动转化)
RandomAccessFile类
RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。
该对象并不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组),通过内部的指针来操作字符数组中的数据特点:
该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。
该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r,rw)
注意:该对象在实例化时,如果要操作的文件不存在,会自动创建;如果文件存在,写数据未指定位置,会从头开始写,即覆盖原有的内容。 可以用于多线程下载或多个线程同时写数据到文件。
import java.io.IOException;
import java.io.RandomAccessFile;
public class TestRandomAccessFile {
public static void main(String[] args) throws IOException {
RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");
for (int i = 0; i < 10; i++) {
rf.writeDouble(i * 1.414); //写入基本类型double数据
}
rf.close();
rf = new RandomAccessFile("rtest.dat", "rw");
rf.seek(5 * 8); //直接将文件指针移到第5个double数据后面
rf.writeDouble(47.0001); //覆盖第6个double数据
rf.close();
rf = new RandomAccessFile("rtest.dat", "r");
for (int i = 0; i < 10; i++) {
System.out.println("Value " + i + ": " + rf.readDouble());
}
rf.close();
}
}