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),这两种方式都可以. 示例程序说明: 文件切割:把一个文件切割成多个碎片,每个碎片的大小不超过 ...
随机推荐
- 项目接入即时聊天客服系统(环信系统)PHP后端操作
环信工作原理: 一.由于环信没有直接的接口来主动调取本项目中的用户数据,所有用户信息必须在环信服务器上注册对应信息成为环信的用户:(这样才能当用户进入聊天时显示其基本信息,如:名称.昵称.电话.邮箱等 ...
- 最棒的7种R语言数据可视化
最棒的7种R语言数据可视化 随着数据量不断增加,抛开可视化技术讲故事是不可能的.数据可视化是一门将数字转化为有用知识的艺术. R语言编程提供一套建立可视化和展现数据的内置函数和库,让你学习这门艺术.在 ...
- 黑裙辉DS918+安装错误码21,安装教程 重装需要重新制作启动盘
不然报错误码21
- xml中的<if>和截取字符串
<#if (envPollute=='1')>√</#if><#if (envPollute=='0')>√</#if>${as_title?subst ...
- js for in 和 for of 的区别
引自:http://es6.ruanyifeng.com/#docs/iterator for...of循环可以代替数组实例的forEach方法. const arr = ['red', 'green ...
- 编程之法:面试和算法心得(字符串包含java实现)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都 ...
- dom4j处理带命名空间的XML-使用XPath(转)
dom4j处理带命名空间的XML-使用XPath 博客分类: XML XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历. XPath 使 ...
- Ubuntu 卸载nvidia驱动
1.切换为集成显卡 如果没有,那么先切换到字符界面 2.卸载驱动 sudo apt-get --purge remove nvidia* sudo apt autoremove To remove C ...
- 4、uboot对设备树的支持
第01节_传递dtb给内核 : r2 a. u-boot中内核启动命令: bootm <uImage_addr> // 无设备树,bootm 0x30007FC0 bootm <uI ...
- iTerm2配色和去掉profile提示框
效果: 配色方案代码地址: https://github.com/mbadolato/iTerm2-Color-Schemes 点击最右边的绿色区域,再点击 “import”, 打开刚下载解压好的文 ...