java-文件切割合并_对象的序列化
一 文件的操作
1.1 概况
1,切割文件的原理:一个源对应多个目的;切割文件的两种方式。
2,碎片文件的命名和编号。
3,程序代码体现。
4,如何记录源文件的类型以及碎片的个数(建立配置信息文件)(其实也可以将这些信息记录碎片文件中)
5,通过Properties属性集建立配置文件。
常见方法:load(InputStream) load(Reader)
store(OutputStream,conmments),store(Writer,conmments)
6,Properties的作为配置在应用程序很常见,主要用于将配置信息持久化。
建立的配置文件扩展名规范: .properties.
代码 SplitFileTest.java
public static void main(String[] args) throws IOException { /* * 练习:将一个媒体文件切割成多个文件 * 思路: * 1.读取源文件,将源文件的数据分别复制到多个文件中 * 2.切割方式有两种:按照碎片个数切.要么按照指定大小切 * 3.一个输入流对应多个输出流 * 4.每个碎片都需要编号,顺序不要错 * */ // 定义源文件 File srcFile = new File("tempFile//50.avi"); // 定义目标文件 File partDir = new File("tempFile//partFile"); // 切割方法 splitFile(srcFile,partDir); } public static void splitFile(File srcFile, File partDir) throws IOException { //如果提供的源文件不存在,则异常 if(!(srcFile.exists() && srcFile.isFile())){ throw new RuntimeException("源文件不是正确文件或者不存在"); } // 如果提供的目标文件不存在,则创建 if(!(partDir.exists())){ partDir.mkdir(); } // 定义文件编号 int count=; //源输入流 FileInputStream fis = new FileInputStream(srcFile); // 输出流,由于是多个输出流.因此要定义为空 FileOutputStream fos = null; // 缓存区,定义你要拿多少 byte [] buf = new byte [*]; int len = ; while((len=fis.read(buf)) != -){ // 输出流对象 fos = new FileOutputStream(new File(partDir,(count++)+".part")); //写入目标文件 fos.write(buf, , len); } }
1.2 加入配置文件
/* * 将源文件以及切割文件的一些信息也保存起来随着碎片文件一起发送 * 信息: * 1.源文件的名称 * 2.切割的碎片的个数 * 将这些信息单独封装到一个文件中 * 还要一个输出流完成此动作 * * */ String filename = srcFile.getName(); int partCount = count; fos = new FileOutputStream(new File(partDir,count+".partconfig")); fos.write(("filename="+filename+line_separator).getBytes() ); fos.write(("filecount="+Integer.toString(count)).getBytes());
1.3 分析配置文件
/* * 配置文件规律,只读一行文本,按照 = 对文本进行分割即可 * * */ BufferedReader buf = new BufferedReader(new FileReader(configFile)); String line = null; while((line = buf.readLine())!=null) { String [] arr = line.split("="); System.out.println(arr[]+"======"+arr[]); }
1.4 配置文件存储
Properties的使用 还有其他代码 /* * 将源文件以及切割文件的一些信息也保存起来随着碎片文件一起发送 * 信息: * 1.源文件的名称 * 2.切割的碎片的个数 * 将这些信息单独封装到一个文件中 * 还要一个输出流完成此动作 * * */ String filename = srcFile.getName(); int partCount = count; fos = new FileOutputStream(new File(partDir,count+".properties")); Properties prop = new Properties(); prop.setProperty("filename", srcFile.getName()); prop.setProperty("patcount", Integer.toString(partCount)); prop.store(fos, "part file info");
1.5 合并
恐怖方式
public static void main(String[] args) throws IOException { //合并碎片文件 // 多个源去的一个目的地 FileInputStream fis1 = new FileInputStream("tempFile//partFile//1.part"); FileInputStream fis2 = new FileInputStream("tempFile//partFile//2.part"); FileInputStream fis3 = new FileInputStream("tempFile//partFile//3.part"); FileInputStream fis4 = new FileInputStream("tempFile//partFile//4.part"); FileInputStream fis5 = new FileInputStream("tempFile//partFile//5.part"); FileOutputStream fos = new FileOutputStream("5.avi"); byte [] buf = new byte[*]; int len1 = fis1.read(buf); fos.write(buf, , len1); int len2 = fis2.read(buf); fos.write(buf, , len2); int len3 = fis3.read(buf); fos.write(buf, , len3); int len4 = fis4.read(buf); fos.write(buf, , len4); int len5 = fis5.read(buf); fos.write(buf, , len5); fos.close(); fis1.close(); fis2.close(); fis3.close(); fis4.close(); fis5.close(); }
序列流
/* * 如上代码的问题, * 当流对象多时,应该先存储起来,面的流对象的容器操作更容易 * 1.需要容器, * 2.将流对象和文件关联后存储到容器中 * 3.遍历容器获取其中的流对象,在进行频繁的读写操作 * 4.即使关流也是遍历容器对每个流对象进行close的调用 * */ List<FileInputStream> list = new ArrayList<FileInputStream>(); // 读 for (int i = ; i < ; i++) { list.add(new FileInputStream("tempFile//partFile//" + i + ".part")); } FileOutputStream fos = new FileOutputStream("5.avi"); // 缓存区 byte[] buf = new byte[ * ]; // 写入 for (FileInputStream fis : list) { int len = fis.read(buf); fos.write(buf,,len); } // 关闭流 for (FileInputStream fis : list) { fis.close(); } 对上面代码进行封装,序列流 public static void mergerFile(File partDir) throws IOException { List<FileInputStream> list = new ArrayList<FileInputStream>(); // 读 for (int i = ; i < ; i++) { list.add(new FileInputStream("tempFile//partFile//" + i + ".part")); } // 怎么获取枚举对象呢?考虑到collection里面去找找 Enumeration<FileInputStream> en = Collections.enumeration(list); // 序列流 SequenceInputStream sis = new SequenceInputStream(en); // 输出流 FileOutputStream fos = new FileOutputStream("5.avi"); // 缓存区 byte[] buf = new byte[]; int len= ; while((len = sis.read(buf))!=-){ fos.write(buf,,len); System.out.println(); } fos.close(); sis.close(); }
配置文件的读取
虽然合并成功.但是也有一些问题
- 如何明确碎片的个数,来确定循环的次数,以明确多少个输入流对象
- 如何知道合并的文件的类型,
解决的方案是:应该先读取配置文件.
public static void main(String[] args) throws IOException { File partDir = new File("tempFile//partFile"); // 1.获取配置文件 File configFile = getConfigFile(partDir); System.out.println(configFile); //2.先获取配置文件信息容器,获取配置文件信息的属性集 Properties prop = getProperties(configFile); System.out.println(prop); // 获取属性信息,并传到合并方法里面去 mergerFile(partDir, prop); } // 根据配置文件获取配置文件信息的属性集 private static Properties getProperties(File configFile) throws IOException { FileInputStream fis = null; Properties prop = new Properties(); try { // 读取流和配置文件相关联 fis = new FileInputStream(configFile); // 将流的数据加载到集合中去 prop.load(fis); } finally { if (fis != null) fis.close(); } // 将集合返回 return prop; } // 根据碎片目录获取配置文件对象 private static File getConfigFile(File partDir) { if (!(partDir.isDirectory() && partDir.exists())) { throw new RuntimeException("不是有效的目录"); } // 判断碎片文件目录中是否存在properties文件 // 过滤器 File[] files = partDir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().endsWith(".properties"); } }); if (files.length != ) { throw new RuntimeException("properties扩展名的文件不存在,或不唯一"); } File configFile = files[]; return configFile; } // 合并 public static void mergerFile(File partDir , Properties prop) throws IOException { // 获取属性集中的信息 String filename = prop.getProperty("filename"); int partCount = Integer.parseInt(prop.getProperty("patcount")); // 使用io包中的SeqenceInputStream 对碎片文件进行合并,将多个文件合并一个读取流 List<FileInputStream> list = new ArrayList<FileInputStream>(); // 读 for (int i = ; i < partCount; i++) { list.add(new FileInputStream("tempFile//partFile//" + i + ".part")); } // 怎么获取枚举对象呢?考虑到collection里面去找找 Enumeration<FileInputStream> en = Collections.enumeration(list); // 序列流 SequenceInputStream sis = new SequenceInputStream(en); // 输出流 FileOutputStream fos = new FileOutputStream(filename); // 缓存区 byte[] buf = new byte[]; int len = ; while ((len = sis.read(buf)) != -) { fos.write(buf, , len); } fos.close(); sis.close(); }
1.6 记录程序运行次数
public static void main(String[] args) throws IOException { /* * 练习:定义一个功能程序运行次数,满足试用次数后给出提示,试用次数到了 * 思路: * 1.需要计数器, * 2.需要一个拷久的计数器, * 3.并且给这个计数器取个名字 * 4.properties集合下好满足这个要求 * * */ if (isStop()){ System.out.println("试用次数到了.不能在用了"); return; } runcode(); } private static boolean isStop() throws IOException { // 配置文件 File configFile = new File("tempFile\\app.properties"); if (!(configFile.exists())){ configFile.createNewFile(); } int count = ; // 创建属性集 Properties prop = new Properties(); // 定义读取流和配置文件关联 FileInputStream fis = new FileInputStream(configFile); prop.load(fis); String value = prop.getProperty("count"); // 对value进行判断,如果存在就对其自增 if(value != null ){ count=Integer.parseInt(value); if(count>){ return true; } } count++;// 对其值进行自增 // 将处增后的值和指定的键重新存储到属性集中,键相同,值覆盖 prop.setProperty("count", Integer.toString(count)); FileOutputStream fos = new FileOutputStream(configFile); prop.store(fos, "app run count"); fos.close(); fis.close(); return false; } // 程序文体 public static void runcode() { System.out.println("程序运行了::::::play "); }
二 对象
序列化
写 ObjectOutputStream
// 应该先有对象,Person Person p1 = new Person("LISHI",); // FileOutputStream fos = new FileOutputStream("tempFile\\obj.object"); ObjectOutputStream obs = new ObjectOutputStream(fos); obs.writeObject(p1); obs.close();
反序列化
读 ObjectInputStream
//需求:读取已有的对象文件,并获取对象中的数据。 //通过阅读ObjectOutputStream对象的文档,发现有一个对应的对象ObjectInputStream可以用于读区存储对象的文件 //对象的反序列化。 FileInputStream fis = new FileInputStream("tempfile\\obj.object"); ObjectInputStream ois = new ObjectInputStream(fis); Object obj = ois.readObject(); System.out.println(obj.toString());
注意:
1.一定要在你的类里面加这个private static final long serialVersionUID = 1L
2.对于一个非静态的数据也不想序列化怎么办?需要一个关键字来修饰 transient
java-文件切割合并_对象的序列化的更多相关文章
- JAVA之旅(三十)——打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码
JAVA之旅(三十)--打印流PrintWriter,合并流,切割文件并且合并,对象的序列化Serializable,管道流,RandomAccessFile,IO其他类,字符编码 三十篇了,又是一个 ...
- java下io文件切割合并功能加配置文件
package cn.stat.p1.file; import java.io.File; import java.io.FileInputStream; import java.io.FileNot ...
- java下io文件切割合并功能
package cn.stat.p1.file; import java.io.File; import java.io.FileInputStream; import java.io.FileNot ...
- Java 文件切割工具类
Story: 发送MongoDB 管理软件到公司邮箱,工作使用. 1.由于公司邮箱限制附件大小,大文件无法发送,故做此程序用于切割大文件成多个小文件,然后逐个发送. 2.收到小文件之后,再重新组合成原 ...
- jni 文件切割合并
最近学习c++,看到很多常用的例子,比如文件切割,切割后后缀可以自定义,别人就无法从表面的一个文件看出是什么,也无法查看到原文件信息,只有合并后才能识别这庐山真面目 实现也比较粗暴,首先在应用层定义好 ...
- 四、java基础-面向过程_对象_类中可出现的因素
1.面向过程和面向对象区别: 1)面向过程:开发一个应用程序.一个项目,必须先了解整个过程,了解各个步骤.模块间的因果关系,使的面向过程方式去开发程序时,代码和代码之间的关联程度是非常强.所以其中任何 ...
- IO流_文件切割与合并(带配置信息)
在切割文件的时候应该生成一个记录文件信息的文件,以便在以后合并文件的时候知道这个文件原来的文件名和记录文件切割完后生成了多少个切割文件 import java.io.File; import java ...
- Java对象序列化文件追加对象的问题,以及Java的读取多个对象的问题解决方法。
这几天做一个小的聊天项目用到对象序列化的知识,发现对象序列化不能像普通文件一样直接追加对象.每次写入对象都会被覆盖.弄了2个多小时终于解决了.Java默认的对象序列化是每次写入对象都会写入一点头ace ...
- Java---练习:文件切割与合并(1)
实现对大文件的切割与合并. 按指定个数切(如把一个文件切成10份)或按指定大小切(如每份最大不超过10M),这两种方式都可以. 示例程序说明: 文件切割:把一个文件切割成多个碎片,每个碎片的大小不超过 ...
随机推荐
- LUOGU P1654 OSU! (概率期望)
传送门 解题思路 首先考虑对于一个点来说,如果这个点是1的话,那么对于答案来说 $(ans+1)^3=ans^3+3*ans^2+3*ans+1$,这对于上一个答案来说其实贡献了 $3*ans^2+3 ...
- python网络框架Twisted
什么是Twisted Twisted是一个用python语言写的事件驱动网络框架,它支持很多种协议,包括UDP,TCP,TLS和其他应用层协议,比如HTTP,SMTP,NNTM,IRC,XMPP/Ja ...
- JS 计算时间范围,最近一周、一个月
//最近一周 getDay(-7) 返回的是距离当前日期的一周后的时间//一月 getDay(-30)//一年 getDay(-365) function getDay(day){ var today ...
- centos7中给Elasticsearch5 安装bigdesk
系统:centos7 elasticsearch:5.2.2 安装步骤 步骤 由于elasticsearch不再建议支持插件的安装方式.建议作为独立的程序来安装类似于bigdesk.head. 以前都 ...
- 使用xshell远程连接到linux
1.检查是否安装ssh rpm -qa | grep ssh 已安装是这样 如果没有安装,则 yum install openssh* #命令安装 2.开启ssh服务 [root@localhos ...
- Python学习day42-数据库的基本操作(1)
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- Java基础知识(数据类型和集合)
一.数据类型 包装类型 包装类型是对基本数据类型不足之处的补充. 基本数据类型的传递方式是值传递,而包装类型是引用传递,同时提供了很多数据类型间转换的方法. Java1.5 以后可以自动装箱和拆箱 二 ...
- (补充)10.Hibernate框架的查询方式
技术分析之Hibernate框架的查询方式 1. 唯一标识OID的检索方式 * session.get(对象.class,OID) 2. 对象的导航的方式 3. HQL的检索方式 * Hibernat ...
- 全面解决Html页面缓存的问题
页面缓存的问题可能大家都遇到过,很多功能做完没起效果,那么怎么解决这个问题呢?这里给出我的使用的解决方法 对于一个html页面,缓存分3部分,一个是页面内容,一个是css样式,一个是JS文件1.页面内 ...
- PAT甲级——A1062 Talent and Virtue
About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about ...