⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystemsourcefactory.java

📁 dm s preparing process. In this case we use O distance.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* created at 2005-12-24 */
package com.clustering.data;

import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Pattern;

/**
 * 通过该类来创建数据源
 * 
 * @author Avon
 * @version 0.9
 * @since 0.9
 */
public final class FileSystemSourceFactory {
	/**
	 * 使用location位置的记录,按照默认的格式创建数据源
	 * 
	 * @param location
	 *            数据源文件的位置
	 * @return
	 */
	public final static FileSystemSource createSimpleSource(String location) {
		return createSimpleSource(location, null, null, false);
	}

	/**
	 * 使用location位置的记录,按照formatter格式,以info为信息创建数据源.
	 * <p>
	 * 如果在创建数据源时要求把文件中的矩阵转置,那么创建的数据源的就是按照转置后的矩阵创建,并且这个数据源中的信息也是与按照转置矩阵创建的。
	 * 如果想为该方法提供{@link info}参数,那么这个{@link info}参数也是用来说明未转置的矩阵,而不是转置后的矩阵,觉得这样能方便
	 * 
	 * @param location
	 *            数据源文件的位置
	 * @param formatter
	 *            数据源文件的格式
	 * @param info
	 *            数据源文件的信息,如果是转置矩阵,那么也按照文件中的矩阵的形式设置数据源信息参数
	 * @param transposable
	 *            是否按照转置创建数据源
	 * @return
	 */
	public final static FileSystemSource createSimpleSource(String location, Formatter formatter, SourceInfo info,
			boolean transposable) {
		if (null == location)
			throw new IllegalArgumentException("The location of datasource file is missed.");
		else if (!new File(location).exists()) {
			throw new IllegalArgumentException("Data source file[" + location + "] does not exist.");
		}
		if (null == formatter) {
			formatter = new FileSystemFormatter();
		}
		// XXX 如果info为null,那么按照location文件的头初始化info,这里没有实现
		// 这里吧info的检查逻辑放到SimpleFileSystemSourceImpl中了
		SimpleFileSystemSourceImpl source = new SimpleFileSystemSourceImpl(location, formatter, info, transposable);
		return source;
	}

	public final static FileSystemSource createComplexSource(String location) {
		return createComplexSource(location, null, null, false);
	}

	public final static FileSystemSource createComplexSource(String location, Formatter formatter, SourceInfo info,
			boolean transposable) {
		throw new UnsupportedClassVersionError("Current release does not support complex file system source.");
	}

	/*
	 * 所谓Simple就是指把所有的记录都保存到内存中,而不考虑任何内存使用策略。 @author Avon
	 */
	private static class SimpleFileSystemSourceImpl extends FileSystemSource implements SimpleSource {
		// 这里的recordNum和colNum只是临时变量,这两个变量用来保存文件中实际的记录数和行数
		private int rowNum;

		private int colNum;

		private boolean isColNull;

		private boolean isRowNull;

		// 存储records的list,本质就是数组
		private ArrayList<Record> records;

		public SimpleFileSystemSourceImpl(String location, Formatter formatter, SourceInfo sourceInfo,
				boolean transposable) {
			super(location, formatter, sourceInfo, transposable);

			/*
			 * 默认情况下,假设没有指定数据源信息
			 * 对于非转置阵,isColNull用来说明用户是否设置了列数,isRowNull用来说明用户是否设置了行数
			 * 对于转置阵,isColNumm用来说明用户是否设置了行数,isRowNull用来说明用户是否设置了列数
			 */
			isColNull = isRowNull = true;

			if (null != sourceInfo) {
				// 列信息保存的不是有效的信息
				if (sourceInfo.getColumnNum() < 0) {
					if (-1 != sourceInfo.getColumnNum())
						log.warn("If u r not sure about source info's column number, set it to -1.[position:"
								+ new Exception().getStackTrace()[0].getLineNumber() + "].");
					// 默认情况下假设没有指定数据源信息
				}
				// 如果数据源信息中保存的是有效的列信息
				else {
					if (sourceInfo.getColumnNum() > Integer.MAX_VALUE) {
						throw new RuntimeException(
								"SimpleFileSystemSource is not suitable for current source, there are too many columns in data source file "
										.concat(location));
					}
					if (!transposable) {
						colNum = (int) sourceInfo.getColumnNum();
						isColNull = false;
					} else {
						rowNum = (int) sourceInfo.getColumnNum();
						isRowNull = false;
					}
				}

				// 行信息保存的不是有效的信息
				if (sourceInfo.getRecordNum() < 0) {
					if (-1 != sourceInfo.getRecordNum())
						log.warn("If u r not sure about source info's record number, set it to -1.[position:"
								+ new Exception().getStackTrace()[0].getLineNumber() + "].");
					// 默认情况下假设没有指定数据源信息
				}
				// 行信息保存的是有效的信息
				else {
					if (sourceInfo.getRecordNum() > Integer.MAX_VALUE) {
						throw new RuntimeException(
								"SimpleFileSystemSource is not suitable for current source, there are too many records in data source file "
										.concat(location));
					}
					// 不需要转置时
					if (!transposable) {
						// 读取文件时计算行数
						isRowNull = false;
					}
					// 需要转置时
					else {
						// 读取文件时计算列数
						isColNull = false;
					}
				}
			} // 没有设置数据源信息,那么isColNull = isRowNull = true;

			if (!transposable && !isRowNull)
				records = new ArrayList<Record>(rowNum);
			else if (transposable && !isColNull) {
				records = new ArrayList<Record>(rowNum);
			} else {
				// 没有给数据源信息,无法优化
				records = new ArrayList<Record>();
			}

			/*
			 * 本来不打算使用BufferedReader,但是没有数据源的格式,所以这里使用了reader,如果以后规定了
			 * 数据源的格式,就需要重新写FileSystemSource的readLine函数了
			 */
			BufferedReader reader = null;
			try {
				reader = new BufferedReader(new FileReader(location));
			} catch (FileNotFoundException e) {
			}
			// 认为很难把转置的情况和不转置的情况合并到一个init中
			if (!transposable)
				init1(reader);
			else
				init2(reader);

			if (null == sourceInfo) {
				sourceInfo = new SourceInfo();
			}
			sourceInfo.setColumnNum(colNum);
			sourceInfo.setRecordNum(rowNum);
			// 这里并没有具体严格的设置列类型
			if (null == sourceInfo.getColumnTypes()) {
				Class[] clazzs = new Class[colNum];
				for (int i = 0; i < clazzs.length; i++) {
					clazzs[i] = Double.class;
				}
			}
			this.sourceInfo = sourceInfo;
		}

		/*
		 * 把文件中的内容直接转化为数据源,不考虑转置问题。
		 * 如果指定了数据源信息,那么就存在信息校验的问题,如果指定的数据源信息与文件实际的信息不一致,那么将按照文件中的情况修改数据源信息
		 */
		private void init1(BufferedReader reader) {
			while (true) {
				String s = readLine(reader);
				// #作为注释
				if (null == s) {
					break;
				} else if (s.startsWith("#") || s.equals("")) {
					continue;
				}
				records.add(new RecordImpl(s));
				// 记录太多,无法用SimpleSystemSource来表示
				if (rowNum == Integer.MAX_VALUE) {
					throw new RuntimeException(
							"SimpleFileSystemSource is not suitable for current source, there are too many records in data source file "
									.concat(location));
				}
				rowNum++;
			}
			if (!isColNull) {
				if (colNum > sourceInfo.getColumnNum()) {
					log.warn("Threr are " + colNum + " columns in " + location
							+ " which is more than the column number[" + sourceInfo.getColumnNum()
							+ "] u predict in Method createSource or source file. "
							+ "Here, the program simply set the column number to " + colNum + ".[position:"
							+ new Exception().getStackTrace()[0].getLineNumber() + "].");
				}
				// 如果指定的属性个数>实际的属性个数,即使数据源文件中没有这些属性的值,也要创建这些属性,认为可能这些属性都是0而被省略了
			}
			if (!isRowNull) {
				if (rowNum > sourceInfo.getRecordNum()) {
					log.warn("There are " + rowNum + " records in " + location
							+ " which is more than the record number[" + sourceInfo.getRecordNum()
							+ "] u predict in Method createSource or source file."
							+ "Here, the program simply set the record number to " + rowNum + ".[position:"
							+ new Exception().getStackTrace()[0].getLineNumber() + "].");
				} else if (sourceInfo.getRecordNum() > rowNum) {
					log.warn("File[" + location + "] does not contains enough records. u predicted "
							+ sourceInfo.getRecordNum() + ", but actually there is only " + rowNum
							+ ". Here, program simply set the record number to " + rowNum + "[position:"
							+ new Exception().getStackTrace()[0].getLineNumber() + "].");
				}
			}

		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -