批量生成小说目录以及更改一些图片名称

    最近在做一款小说阅读的软件 ,需要嵌入很多小说,而且要生成相应的目录和更改图片名称,手动处理会很无聊,也很容易出

错。作为程序猿应该不会做这种无聊透顶的事。

遂就写了一个批量生成目录和更改图片名称的一个程序。

每一本小说文件都在其文件夹中。请见下图 


           

      上图是盗墓修仙记文件夹中的情况,每一本小说都是这样子,  两张图和一个txt文件放在一个文件夹中,每一本小说文件夹中

里面文件名都一样 都是三样名称ico conver main.txt,其中图片的后缀可以为其他,不一定非要跟上图一样。

然后下面是我截取其中一个处理后的小说文件夹的截图 多了一个文件 content.txt 这是程序生成的,另外图片的名称也改了


content.txt文件里面内容是这样   这只是content一部分

      本程序主要难点是怎么生成小说目录。

      本人在程序截取目录时毫无疑问用了正则表达式,因为小说的目录是不总是一样的,

好了 不罗嗦了额 下面是本次的代码,可能有些bug,但我在用的时候没什么问题,如你要用可以copy到eclipse建一个java项目直接

用,copy的同时,程序中程序可根据需要来修改其中部分(如路径,正则等等)。在此声明下,如用此代码给您文件造成损坏或错

乱,本人一概不负责,请谨慎使用,用的时候建议先测试一下。

下面是本次程序完整源代码 带注释

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.management.Descriptor;


/**
 * @author manymore13
 * 创建小说的目录和每一章节的位置(按字节定位) 并以txt文档的方式显示出结果
 * main.txt ico  conver 在同一个目录下con,conver分别是图片的前缀  main.txt是小说文件
 */
public class CreateContent {

	
	private String m_bookPath;
	private String m_bookName;
 	public static List<Long> positionList;
	public static List<String> titileList;
	String m_patternString;
	
	// 换行符占两个字节
	private int breakLineSize = 2;
	/**
	 * 
	 * @param path 书的路径
	 * @param pattern 章节的正则表达式
	 */
	public CreateContent(String path, String name, String pattern)
	{
		m_bookPath = path;
		m_bookName = name;
		m_patternString = pattern;
		positionList = new ArrayList<Long>();
		titileList   = new ArrayList<String>();
		
	}


	/**
	 * 写入文档中(txt文件),目录和位置以 字符串"/"隔开(目录和位置)
	 * @param filePath 写出目录的路径
	 * @param fileName 写出目录的名称
	 * @throws IOException
	 */
	public void writeContentToFile(String filePath, String fileName) throws IOException
	{
		
		
		File contentFile = new File(filePath+File.separator+fileName);
		
		if((contentFile!=null) && (!contentFile.exists()))
		{
 			contentFile.createNewFile();
		}
		PrintWriter pw = new PrintWriter(contentFile);
		for(int i=0; i<titileList.size(); i++)
		{
			pw.println(titileList.get(i)+"/"+positionList.get(i));
		}
		pw.flush();
		pw.close();
		
		if(titileList.size()>0)
		{
			System.out.println("目录生成成功");
		}else{
			System.out.println("目录生成失败");
		}
	}
	
	/**
	 * 解析小说文件
	 */
	public void parseBookFile() throws RuntimeException
	{
		BufferedReader br = null;
		
		File bookFile = new File(m_bookPath+File.separator+m_bookName);
		
		if(!bookFile.exists())
		{
			 throw new RuntimeException(m_bookPath+"小说文件不存在");
		}
		
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(bookFile)));
		} catch (FileNotFoundException e) {
 			e.printStackTrace();
		}
	
		long preByte=0L;
		
		Pattern pattern = Pattern.compile(m_patternString);
		String line;
	
		try {
			while((line = br.readLine())!=null)
			{
				
				Matcher matcher = pattern.matcher(line);
				while(matcher.find())
				{
					int start = matcher.start();
					int end   = matcher.end();
					String title = line.substring(start, end);
					int currentSize = line.substring(0, start).getBytes("GBK").length;
					positionList.add(preByte+currentSize+1);
					titileList.add(title);
					
					
				}
				preByte+=line.getBytes("GBK").length+breakLineSize;
			}
		} catch (IOException e) {
 			e.printStackTrace();
		}finally{
			try {
				br.close();
			} catch (IOException e) {
 				e.printStackTrace();
			}
		}
		System.out.println("一共有多少字节:"+(preByte));
 	}
	
	/**
	 * 获取小说文件有效行数
	 * @return
	 */
	public int getCountLines()
	{
		int lineSum = 0;
		
		File bookFile = new File(m_bookPath+File.separator+m_bookName);
		
		if(!bookFile.exists())
		{
			System.out.println("小说文件不存在");
			System.exit(0);
		}
		
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(new FileInputStream(bookFile)));
		} catch (FileNotFoundException e) {
 			e.printStackTrace();
		}
		
		try {
			while(br.readLine()!=null)
			{
				lineSum++;
			}
		} catch (IOException e) {
 			e.printStackTrace();
		}finally{
			try {
				br.close();
			} catch (IOException e) {
 				e.printStackTrace();
			}
		}
		return lineSum;
		
	}
	//^第.+章.+$
	//第[\d一二三四五六七八九十]+章\\s*.{0,20}
	public static void main(String[] args) {
		
		// 正则表达式   按自己需要来更改
		String pattern = "第[\\d一二三四五六七八九十百千]+[章节集]\\s*.{0,20}";
		
		// 小说主名字  我这里面都是固定的
		String bookName = "main.txt";
		
		// 要批量处理的小说根路径 
		String bookNamePath = "C:\\小说\\50本小说";
		
		// 所生成的目录文件的名称 你可以更改其他的
		String contentFileName = "content.txt";
		
		File[] bookNameFiles = new File(bookNamePath).listFiles();
				
		for(File f:bookNameFiles)
		{
			if(f.isDirectory())
			{
				bookNamePath = f.getAbsolutePath();
			}else{
				continue;
			}
			startProcess(bookNamePath, bookName, contentFileName, pattern);
			System.out.println();

			
		}
		
		System.out.println("一共"+bookNameFiles.length+"本小说");
		
				
	}
	
	public static void startProcess(String bookNamePath,String bookName,String contentFileName,String pattern)
	{
		System.out.println("正在处理"+bookNamePath+"路径下"+"小说");
		
		CreateContent createContent = new CreateContent(bookNamePath,bookName,pattern);
		
		createContent.initContainer();
		
		try{
			createContent.parseBookFile();
		}catch(RuntimeException r){
			System.out.println(r.getMessage());
			return;
		}

		/*生成小说目录*/
		try {
			createContent.writeContentToFile(bookNamePath, contentFileName);
		} catch (IOException e) {
 			e.printStackTrace();
		}
		
		/*更改图片名字*/
		int i = createContent.changeImageName();
		
		System.out.println("改变了"+i+"张图片");
		
	}

	/**
	 *  初始化容器
	 */
	private void initContainer()
	{
		titileList.clear();
		positionList.clear();
	}
	
	/**
	 * 修改图片文件名字前缀 icon start
	 */
	public int changeImageName()
	{
		File rootfile = new File(m_bookPath);
		String prefix = null; // 前缀
		String postfix = null;// 后缀
		int count = 0;
		File imageFile;
		File newImageFile;
		if(!rootfile.isDirectory())
		{
			return 0;
		}
		/*获取该目录下图片名字*/
		String[] imageNames = rootfile.list(new FileFilter());
		
		for(String name:imageNames)
		{
			postfix = name.split("\\.")[1];
						
			imageFile = new File(m_bookPath + File.separator + name);
			
			if(name.equals("ico"+"."+postfix))
			{
				prefix = "icon";
			}else if(name.equals("conver"+"."+postfix)){
				prefix = "start"; 
			}else{
				continue;
			}
			
			newImageFile = new File(m_bookPath+File.separator+prefix+"."+postfix);
			imageFile.renameTo(newImageFile);
			count++;
		}
		return count;
	}
	
	/**
	 * 
	 * @author manymore13
	 * 文件过滤器 过滤以后缀.png, .jpg的文件
	 */
	class FileFilter implements FilenameFilter
	{

		@Override
		public boolean accept(File dir, String name) {
  			return ((name.endsWith(".png"))||(name.endsWith(".jpg")))&&
 					(new File(dir.getAbsoluteFile()+File.separator+name).isFile());
		}
		
	}
}

       我所看到小说目录有是 有的是 第一章,有是 第一节,第1章,第1节......不管它们怎么变,你正则在你解析小说时匹配就OK,

本人在用正则解析小说文件出现OOM内存溢出的问题,正则额是解析字符串的,所以本人刚刚开始的思路是把其中一本小说一次全

部读入内存当做字符串,然后用正则扫描生成目录,结果爆OOM,StringBuilder.toString的问题 可能有大小限制。

后来果断换了一种方式,也就是现在程序中的采取的按行读取,读一行扫描一行。用这种方式也需要考虑到一个问题,一个目录只

能占一行。若占两行的话,会给目录位置上和正则匹配造成不必要的麻烦。

好像一般的小说也没有一个目录占两行的呀!我在这里只是提一提这个问题而已。

下面发一张运用本次目录的效果图


好了 本次博客就到此为止。



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统适用行业: 视频拍摄制作(微电影、广告片、宣传片) 、商品展示短视频(食品/鞋服/美妆/母婴等) 、创意广告片(剧情大片/宣传片)、视频拍摄(企业宣传片、广告片、创意视频) 、美食加工过程短视频、商品展示短视频、商品展示短视频(食品/鞋服/美妆/母婴等) TVC广告、影视剧制作、创意TVC广告片、视频制作拍摄(宣传片、产品视频、TVC、广告、动画课程)等 功能简介:  站群 一个后台管理N个网站数据互通,每个网站可以单独绑定域,单独设置SEO信息,单独设置LOGO,单独广告等   视频打赏 用户可以对视频上传作者进行各种礼物打赏,打赏所得金额作者可拿到对应的提成收入,所得收入可人民币提现   三级分销 三级分销商可以拥有独立的分销商网站独立的管理后台,并且可以自定义绑定域,可统计每天收益基本设置等   多线路播放 支持多服务器线路播放视频,不同的会员级别可指定观看不同的播放线路解决宽带负荷,从而提高会员的积极消费   视频上传提成 用户在线上传的视频,如该视频被其他用户比如10个金币消费了,发布视频者可得到如3个金币的奖励   视频试看限制 PC端可自定义设置视频试看时间超出时间提示购买VIP,手机采取每天试看次数超出次数提示购买VIP   自动转码 结合云转码软件实现站长/用户上传视频支持任意格式转码,生成视频图片名称、播放地址、完全自动   每天签到 用户每天签到可得到系统自动奖励的金币,24小时允许签到一次,从而提高用户对网站的黏贴度哦   分享奖励 用户登陆会员中心获取宣传地址分享到QQ、论坛、微信等,不同IP被点击一次奖励指定的消费金币   卡密充值 用户可凭卡密在会员中心进行充值获取金币,后台可生成卡密的金币数直接到发卡平台销售   播放器广告 整合Ckplay播放器,后台可控制加入播放前载入广告,暂停播放广告可开启/关闭广告   支付体系 整合流行支付接口,比如微信支付,支付宝支付等以及第三方支付平台   APP应用 封装安卓APP应用以及苹果APP应用,封装手机端数据同步自动更新   会员在线上传 用户可通过电脑、手机端在线上传视频以及发布图片小说等,实时分享到网站   上传视频奖励 用户上传视频一经站长后台审核通过,该用于将得到系统奖励的金币   防盗链加密 结合云转码可现实防盗链,从而不用担心自己视频资源被盗链,除此之外播放地址我们还做了加密使资源更安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值