按操作数据分为字节流和字符流;
按流向分为输入流和输出流;
字符流基类:
字符输入流(Reader):读取数据
int read(); 读取一个字符
int read(char[] buffer) 读取字符数组
字节输出流(Writer):写出数据
void write(int ch) 写入一个字符
void write(char[] buffer) 写入一个字符数组
void write(char[] buffer, int startIndex, int len) 写入字符数组的一部分
void write(String str) 写入一个字符串
void write(String str, int startIndex, int len) 写入字符串的一部分
字节流基类:
字节输入流(InputStream):读取数据
int read() 读取一个字节
int read(byte[] buffer) 读取字节数组
字节输出流(OutputStream):写出数据
void write(int ch) 写入一个字节
void write(byte[] buffer) 写入一个字节数组
void write(byte[] buffer, int startIndex, int len) 写入字节数组的一部分
字符输出流演示:
需求:把文字存入硬盘中
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个FileWriter对象,该对象一初始化就必须明确被操作的文件
//而且该文件会创建在指定目录下,如果该目录中有同名的文件,则文件会被覆盖
//该步就是明确数据需要存放的目的地
FileWriter fw = new FileWriter("12358.txt");
//调用write方法,把字符串存入流中,而非直接存入目的地
fw.write("你好!!");
//刷新流对象中缓存的数据,将数据刷到目的地中
fw.flush();
//关闭流,先刷新一次
fw.close();
//关闭后无法向流中继续存入数据会报出流关闭异常
//fw.write("asdd");
}
}
IO异常的处理方式,为防止代码异常导致流无法关闭,所以必须使用finally关闭流。
FileWriter文件的续写:
示例:
import java.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
//演示对已有文件的续写
FileWriter fw = null;
try
{
fw= new FileWriter("demo1.txt",true);//后面加true表示对文件续写
fw.write("ssssss\r\nnihao");
}
catch(IOException e)
{
System.out.println(e);
}
finally//关闭流
{
try//可能会遇到异常
{
if(fw!=null)
fw.close();
}
catch(IOException e)
{
System.out.println(e);
}
}
}
}
字符读取流演示:
需求:把硬盘中的文字读到控制台,
可以用字符数组来提高效率,使用read(char[])方法,
如果使用read()方法读取单个字符效率低
演示:read(char[])
import java.io.*;
class FileReaderTest
{
public static void main(String[] args)
{
FileReader fr = null;//定义一个空的读取类
try
{
fr = new FileReader("12358.java");//初始化读取类
char[] arr = new char[1024];//定义一个数组
int num = 0;
while((num=fr.read(arr))!=-1)//把文件读到字符数组中,判断文件中是否还有字符
{
System.out.println(new String(arr,0,num));//返回字符串
}
}
catch (IOException e)
{
System.out.println(e);
}
finally//关闭流
{
try//可能会遇到异常,所以继续try
{
if(fr!=null)
fr.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
演示:read()
import java.io.*;
class FileReaderTest
{
public static void main(String[] args)
{
FileReader fr = null;//定义一个空的读取类
try
{
fr = new FileReader("12358.java");//初始化读取类
int ch = 0;
while((ch=fr.read())!=-1)//判断文件中是否还有字符
{
System.out.println((char)ch);//返回字符串
}
}
catch (IOException e)
{
System.out.println(e);
}
finally//关闭流
{
try//可能会遇到异常,所以继续try
{
if(fr!=null)
fr.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
字符流缓冲区 目的:缓冲区是为了提高流的读取效率,所以没有空参数的构造函数。而且创建缓冲区前必须要先有流对象。
原理:使用了读取缓冲区的read方法,将读取到的字符进行缓冲并判断换行标记,将标记前的缓冲数据变成字符串返回。
写入换行使用BufferedWriter类中的newLine()方法。
读取一行数据使用BufferedReader类中的readLine()方法。
br.read():这个read方法是从缓冲区中读取字符数据,所以覆盖了父类中的read方法。
br.readLine():另外开辟了一个缓冲区,存储的是原缓冲区一行的数据,不包含换行符。
BufferedReader,BufferedWriter提高文本操作效率,添加缓冲区
BufferedReader:
String readLine()读一行的方法
BufferedWriter:
void newLine()写入一个行分隔符
需求:对文件进行复制,要求高效
示例:
import java.io.*;
class CopyTextByBuf
{
public static void main(String[] args) throws IOException
{
//通过缓冲区复制文本文件
BufferedReader br = null;//定义一个空的缓冲区
BufferedWriter bw = null;//定义一个空的缓冲区
try
{
br = new BufferedReader(new FileReader("ReadIn.java"););//定义一个读累缓冲区,传入匿名文件读取类
bw = new BufferedWriter(new FileWriter("1.txt"));//定义一个写类缓冲区,传入匿名文件写出类
String line = null;//定义一个字符串记录读取到的一行
while((line=br.readLine())!=null)//判断数据是否为空,使用缓冲区读一行的方法
{
bw.write(line);
bw.newLine();//记得换行
bw.flush();//一定要记得刷新,用到缓冲区都要刷新
}
}
catch (IOException e)
{
throw new RuntimeException("复制失败");
}
finally
{
if(br!=null)
{
try
{
fls.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
}
if(bw!=null)
{
try
{
fos.close();
}
catch (IOException e)
{
throw new RuntimeException("写出关闭失败");
}
}
}
}
}
装饰设计模式和继承:
都是对功能进行扩展和增强。
装饰比继承灵活,装饰类和被装饰类都要属于同一个接口或者父类
LineNumberReader
跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。
示例:
import java.io.*;
class LineNumberReaderDemo
{
public static void main(String[] args)throws IOException
{
//定义一个读取文件流
FileReader fr = new FileReader("HashMap.java");
//定义一个行号的缓冲字符输入流
LineNumberReader lnr = new LineNumberReader(fr);
//设置起始行号为1000
lnr.setLineNumber(1000);
//定义一个空字符串,来接收读取的一行数据
String line = null;
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+":::"+line);
//得到行号和该文件的数据
}
}
}
字节流基本操作和字符流相同,但是字节流还可以操作其他媒体文件
字节流的两种读取方式
演示:
import java.io.*;
class ReadIn
{
public static void main(String[] args) throws IOException
{
InputRead1();
System.out.println("---------------------");
InputRead2();
}
public static void InputRead1()throws IOException
{
//这种方式效率比较高 建议使用
FileInputStream fis = new FileInputStream("1.txt");//定义一个字节输出流
byte[] buf = new byte[1024];//定义一个字节数组,来当容器
int len = 0;//定义一个数,用来记住存入字节数组中的个数
while((len=fis.read(buf))!=-1)//判断是否读到结束标记
{
System.out.println(new String(buf,0,len));
}
fis.close();//关闭读取流
}
public static void InputRead2()throws IOException
{
FileInputStream fis = new FileInputStream("1.txt");//定义一个字节输出流
int ch = 0;//定义一个数,接收读取到的字节数
while((ch=fis.read())!=-1)//判断是否读到结束标记
{
System.out.print((char)ch);
}
fis.close();//关闭读取流
}
}
出现?号的原因是read一次读取一个字节,直接打印到控制台,而默认的GBK码表一个中文是两个字节。
字节流的缓冲区
BufferedInputStream,BufferedOutputStream;提高文本操作效率,添加缓冲区,凡是用到缓冲区,都要记得刷新。
示例:复制图片,需要缓冲区
import java.io.*;
class Copypic
{
public static void main(String[] args)
{
//复制图片
BufferedInputStream bls = null;
BufferedOutputStream bos = null;
try
{
bls=new BufferedInputStream(new FileInputStream("2.png"));
bos=new BufferedOutputStream(new FileOutputStream("3.png"));
int ch = 0;
while((ch=bls.read())!=-1)
{
bos.write(ch);
}
}
catch (IOException e)
{
throw new RuntimeException("复制失败");
}
finally
{
try
{
if(bls!=null)
bls.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
try
{
if(bos!=null)
bos.close();
}
catch (IOException e)
{
throw new RuntimeException("写出关闭失败");
}
}
}
}
转换流:
InputStreamReader,字节流对象转换成字符流对象,解码
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream));
OutputStreamWriter,字符流对象转换成字节流对象,编码
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream));
疑问:有这么多流我们应该使用那些流呢?
通过三个明确来完成对流的操作
1.明确源和目的
源:输入流 InputStream,Reader
目的:输出流 OutputStream,Writer
2.操作的数据是否纯文本
是:字符流
不是:字节流
3.当体系明确后,在明确使用哪个具体的对象
通过设备来区分:
源设备:内存,硬盘,键盘
目的设备:内存,硬盘,键盘
例如:读取键盘录入,显示在控制台上,
1、明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、是否是纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备。
源:
键盘:System.in
目的:
硬盘:System.out
InputStream in = System.in;
OutputStream out = System.out;
4、需要额外功能么?
需要转换流。因为都是字节流,但是操作的却是文本数据。所以使用字节流操作起来更为便捷。
InputSreamReader isr = new InputStreamReader(System.in);
OutputStreamWriter osw = new OutputStreamWriter(System.out);
需要,高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
题目:读取键盘录入信息,并大写入到一个文件中
1、明确源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、是否是纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备。
源:
键盘:System.in
目的:
硬盘:File
FileReader fr = new System.in;
FileWriter fw = new FileWriter("b.txt");
这样做可以完成,但是麻烦。将读取的字节数据转成字符串,再由字符流操作。
4、需要额外功能吗?
需要,转换。将字节流转成字符流,因为明确的源是Reader,这样操作文本数据更快捷。
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter("2.txt");
还需要功能吗?
需要,高效。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("2.txt"));
示例:
import java.io.*;
class covStream
{
public static void main(String[] args) throws IOException
{
//因为是文本为提高效率使用字节转换流接收键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//提高效率使用缓冲流写到硬盘上
BufferedWriter bw = new BufferedWriter(new FileWriter("2.txt"));
String line=null;
while((line=br.readLine())!=null)
{
if("over".equals(line))
break;
bw.write(line.toUpperCase());
bw.newLine();
bw.flush();
}
br.close();
}
}
通过System类的setIn,setOut方法可以对默认设备进行改变。
示例:
import java.io.*;
class covStream
{
public static void main(String[] args) throws IOException
{
//改变输入对象值
System.setIn(new FileInputStream("Copypic.java"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//改变输出对象值
System.setOut(new PrintStream(new FileOutputStream("3.txt")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( System.out));
String line=null;
while((line=br.readLine())!=null)
{
if("over".equals(line))
break;
bw.write(line.toUpperCase());
bw.newLine();
bw.flush();
}
br.close();
}
编码表:
任何Java识别的字符数据使用的都是Unicode码表,但是FileWriter写入本地文件使用的是本地编码,也就是GBK码表。
而OutputStreamWriter可以只用指定的编码把写入流中的字符编成字节
当使用UTF-8编码时。用GBK码表是解不出来的,因为UTF-8码表一个中文3个字节,而GBK是2个字节,如果是”你好”用UTF-8编码,使用GBK解码会显示三个GBK中两个字节对应的字符,相反如果用GBK给“你好”编码,用UTF-8解码,会显示两个??。
示例:
mport java.io.*;
class UnicodeDemo
{
public static void main(String[] args) throws IOException
{
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("1.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
}
import java.io.*;
class UnicodeDemo1
{
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new FileReader("1.txt"));
String line = br.readLine();
System.out.println(line);
br.close();
}
}
原因:因为1.txt文件中是UTF-8编码的“你好”,有6个字节。
而FileReader类是用GBK编码进行读取,6个字节代表3个字符,按照GBK进行解码,因此才出现如上结果。
示例2:
import java.io.*;
class UnicodeDemo2
{
public static void main(String[] args) throws IOException
{
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("2.txt"),"GBK");
osw.write("你好");
osw.close();
}
}
import java.io.*;
class UnicodeDemo
{
public static void main(String[] args) throws IOException
{
InputStreamReader isr = new InputStreamReader(new FileInputStream("2.txt"),"UTF-8");
char[] buf = new char[10];
int len = isr.read(buf);
System.out.println(new String(buf,0,len));
}
}
原因:由于2.txt文件中是GBK编码的“你好”,4个字节。
使用InputStreamReader类是用UTF-8编码进行读取,由于GBK编码的字节使用UTF-8没有对应的字符,因此使用“?”进行代替。
File类
File类是用来操作文件与文件夹的属性信息,把文件或者文件夹封装成了对象,File对象可以作为参数传递给流的构造函数。
构造方法:
File f = new File(“f:\\abc\\a.txt”)
File f2 = new File(“f:\\abc\\”,”b.txt”)
File d = new File(“f:\\abc”)
File f3 = new File(d,“c.txt”)
File文件中有个特殊的分隔符字段separator
File f4 = new
File(“f:”+File.separator+”abc”+File.separator+”a.txt”)
上面这种方法可跨平台使用
File类的常见方法
1.创建
boolean createNewFile:在指定位置创建文件,如果文件已 经存在,则不创建,返回false。和输出流不一样,输出流对 象一旦建立,就会创建文件,若文件已存在,则覆盖。
boolean mkdir():创建文件夹,只创建一级文件夹。
boolean mkdirs():创建多级文件夹。
2.删除
boolean delete():删除文件,删除成功,返回true,删除失败返回false,如:正在使用文件就无法删除。
void deleteOnExit():在程序退出时删除文件。
3.判断
判断文件对象是文件还是目录时,必须先判断该文件封装的内容是否存在,通过exists判断。
boolean exists():文件是否存在。
boolean isFile():是否是文件。
boolean isDirectory():是否是目录。
boolean isHidden():是否是隐藏文件。
boolean isAbsolute():是否为绝对路径名。
4.获取信息
String getName();返回名称。
String getPath();返回路径名字,如果是相对路径则返回名 字,如果是绝对路径则返回其路径。
String getParent();返回绝对路径中的父目录,如果是相对 路径,则返回null。如果相对路径中有上一层目录则返回该 目录。
String getAbsolutePath():无论绝对还是相对路径,都返 回绝对路径。
long lastModified():上一次修改时间。
long length();返回长度。
static File[] listRoot:获取盘符;
String[] list:返回目录中的文件和文件夹,包括隐藏文件
使用list必须要求File对象封装的是一个目录,而且其目 录必须存在。
示例:
import java.io.*;
class FileDemo
{
public static void main(String[] args) throws IOException
{
File file1 = new File("1.txt");//新建一个文件类
File file2 = new File("f:\\2.txt");//新建一个文件类
//if(file1.exists())//判断是否存在
boolean b1 = file1.createNewFile();//创建文件,如果已存在则不创建
//if(file2.exists())//判断是否存在
boolean b2 = file2.createNewFile();//创建文件,如果已存在则不创建
String name = file1.getName();//得到名字
String path1 = file1.getPath();//返回路径名字,如果是相对路径则返回名 字,如果是绝对路径则返回其路径。
String path2 = file1.getPath();//返回路径名字,如果是相对路径则返回名 字,如果是绝对路径则返回其路径。
String absPath1 = file1.getAbsolutePath();//无论绝对还是相对路径,都返 回绝对路径。
String absPath2 = file2.getAbsolutePath();//无论绝对还是相对路径,都返 回绝对路径。
long len1 = file1.length();//得到长度
long len2 = file2.length();//得到长度
long time1 = file1.lastModified();//上一次修改时间。
long time2 = file2.lastModified();//上一次修改时间。
String parentName1 = file1.getParent();//返回绝对路径中的父目录,如果是相对 路径,则返回null。如果相对路径中有上一层目录则返回该 目录。
String parentName2 = file2.getParent();//返回绝对路径中的父目录,如果是相对 路径,则返回null。如果相对路径中有上一层目录则返回该 目录。
System.out.println(b1);
System.out.println(b2);
System.out.println(name);
System.out.println(path1);
System.out.println(path2);
System.out.println(absPath1);
System.out.println(absPath2);
System.out.println(len1);
System.out.println(len2);
System.out.println(time1);
System.out.println(time2);
System.out.println(parentName1);
System.out.println(parentName1);
}
}
重命名示例:
import java.io.*;
class FileDemo1
{
public static void main(String[] args)
{
File file1 = new File("f:\\1.txt"); //定义一个file文件类
File file2 = new File("f:\\GG.txt");//定义一个file文件类
boolean b = file1.renameTo(file2);//修改file1的名字为file2中的名字和路径
System.out.println(b);//输出是否修改成功
}
}
获取目录下的文件和文件夹:
示例:
import java.io.*;
class FileDemo2
{
public static void main(String[] args)
{
//需求读取C盘下的目录和文件
File file = new File("c:\\");
String [] names = file.list();//把目录和文件名存入字符串数组中
for(String name : names)//通过高级for循环迭代取出
{
System.out.println(name);
}
}
}
递归:
函数自身调用了自身称之为递归;
使用场景:
一个功能被重复使用,而每一次使用都和上次的调用有关,这时候就可以用递归来解决问题。
注意:
1.条件一定要明确,不然栈内存溢出
2.一定要注意递归的次数,不要太多次
示例:
列出目录中的所有文件,即文件夹中的文件也要列出
import java.io.*;
class getAllListFiles
{
public static void main(String[] args)
{
File f = new File("F:\\javadm");
getAll(f,0);
}
public static String getLevel(int level)
{
//获得等级
StringBuilder sb = new StringBuilder();//定义一个容器
sb.append("|--");
for(int i=0;i<level;i++)
{
sb.insert(0,"| ");
//sb.append("|--");
}
return sb.toString();
}
public static void getAll(File f,int level)
{
//获取目录下所有文件夹和文件
System.out.println(getLevel(level)+f);
level++;
File[] f1 = f.listFiles();
for(File fs : f1)
{
if(fs.isDirectory())//判断是否为目录
{
getAll(fs,level);//递归
}
else
System.out.println(getLevel(level)+fs);
}
}
}
Properties:
示例:
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args) throws IOException
{
setProp();
}
public static void setProp()throws IOException
{
//要求:把文本上的信息用setProperties修改后保存起来。
FileInputStream fis = new FileInputStream("2.txt");
Properties p = new Properties();
p.load(fis);//从输出流中读取属性列表
FileOutputStream fos = new FileOutputStream("2.txt");
p.setProperty("wangwu","GG");//设置键值对
p.store(fos,"信息名");//把读取到的属性列表写入输出流
System.out.println(p);
Set<String> st = p.stringPropertyNames();//返回列表中的键集,
for(String s : st)
{
System.out.println(s+"::"+p.getProperty(s));//通过键得到值
}
}
}
PrintStream:字节打印流
构造函数可以接收的类型。
1.file对象.File
2.字符串路径。String
3.字节输出流。OutputStream
import java.io.*;
class Demo
{
public static void main(String[] args)throws Exception
{
PrintStream ps = new PrintStream("demo.txt");
//打印转换后的字符
ps.write(100);
//打印原字符
ps.print(100);
}
}
PrintWriter:,字符打印流
构造函数可以接收的类型。
1.file对象.File
2.字符串路径。String
3.字节输出流。OutputStream,在后面添加true表示自动刷新
4.字符输出流,Writer,在后面添加true表示自动刷新
示例:
mport java.io.*;
class Demo
{
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//键盘录入
PrintWriter pw = new PrintWriter(new FileOutputStream("fls.txt"),true);//定义一个自动刷新的打印流
String line = null;
while((line=br.readLine())!=null)
{
if(line.equals("over"))//结束标记
break;
pw.println(line.toUpperCase());//字符串大写
}
pw.close();
br.close();
}
}
SequenceInputStream:表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
即对多个文件进行合并
示例:
import java.util.*;
import java.io.*;
class SequenceDemo
{
public static void main(String[] args) throws IOException
{
//把多个文件写入一个文件
Vector<InputStream> v = new Vector<InputStream>();
//把流存入集合
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
//得到枚举对象
Enumeration<InputStream> en = v.elements();
//建立合并流
SequenceInputStream sis = new SequenceInputStream(en);
//确认输出目的
FileOutputStream fos = new FileOutputStream(new File("4.txt"));
byte[] b = new byte[1024];
int ch =0;
while((ch=sis.read(b))!=-1)
{
fos.write(b,0,ch);
}
fos.close();
sis.close();
}
}
对象的序列化:即对象的持久存储:想要序列化必须要实现序列化接口:Serializable
没有方法的接口称为标记接口
public static final long serialVersionUID = 42L;
使用上面的代码,可以定义一个固定标记,而不会因为对象类,有些小改动,就无法识别。
注意:静态无法被序列化,因为序列化是在堆内存中,而静态在方法区
前面加transient也不会被序列化,保证其值在堆内存中,也不会被序列化
示例:
mport java.io.*;
class ObjectStreamDemo
{
public static void main(String[] args) throws Exception
{
//writeObject();
readObject();
}
//把对象序列化,即持久化
public static void writeObject()throws Exception
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("per.person"));
oos.writeObject(new person("zhangsan",18));
oos.close();
}
//把序列化对象读取
public static void readObject()throws Exception
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("per.person"));
person p = (person)ois.readObject();
System.out.println(p);
ois.close();
}
}
//对象想要序列化必须实现Serializable接口
class person implements Serializable
{
public static final long serialVersionUID = 42L;
private String name ;
private int age;
person(String name,int age)
{
this.name=name;
this.age=age;
}
public String toString()
{
return name+":::::"+age;
}
}
文件切割与合并:
示例:
import java.io.*;
import java.util.*;
class SplitFileDemo
{
public static void main(String[] args) throws IOException
{
split();
fuhe();
}
//把多个文件合成一个文件
public static void fuhe() throws IOException
{
//使用ArrayList效率高
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int i=1;i<=5;i++)
{
al.add(new FileInputStream(i+".part"));
}
final Iterator<FileInputStream> it = al.iterator();//因为是局部变量若想让匿名内部类使用必须final修饰
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()//覆盖枚举接口方法
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis =new SequenceInputStream(en);//定义合并流
FileOutputStream fos = new FileOutputStream(new File("0.mp3"));
byte[] b = new byte[1024];
int ch =0;
while((ch=sis.read(b))!=-1)
{
fos.write(b,0,ch);
}
fos.close();
sis.close();
}
//把文件切割成1M大小的若干文件
public static void split()throws IOException
{
FileInputStream fis = new FileInputStream("1.mp3");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];//切成1M大小
int len = 0;
int count=1;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream((count++)+".part");//定义文件名字
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
RandomAccessFile:
随机访问文件,自身具备读写方法
该类不算是IO体系中子类,而是直接继承自Object.
但是它是IO包中成员,因为其具备读和写的功能,
内部封装了一个数组,而且通过指针对数组的元素进行操作
可以通过getFilePointer获取指针位置
同时可以通过seek改变指针位置
其实完成读写的原理就是内部封装了字节输入流和输出流
通过构造函数看出该类只能操作文件
如果要操作文件不存在,就会创建,如果存在,不会覆盖。
因为有seek改变指针位置所以可以取该数组中的任意位置的值
同时可以改变任意位置的值,在任意位置进行操作。