我正在创建一个安装程序,并且在安装过程中必须读取一些资源文件(.xmls,.zip文件,.jar文件等),但我想将它们打包到自定义文件中(即,一个.dat文件),以便在分发时,用户不会过多地使用它们。问题是安装程序必须用Java编写,我以前从未用任何编程语言做过这种事情。它甚至可能吗?如果是这样,我怎么能以之后可以被我的Java应用程序读取的方式打包它,如何让我的Java应用程序读取它?
答案 0 :(得分:5)
关于此文件类型的要求,您需要回答很多问题。是否需要压缩?加密?是否需要支持随机访问读取,或者流读取是否足够好?
我可能错了,但我不认为这就是你在这个问题上所要求的。如果我正确地读你,我想你会问“我怎么读和写任意文件数据?”
这就是我要回答的问题。更新您的问题,如果这不是您正在寻找的。 p>
可以使用DataInputStream和DataOutputStream类轻松实现自定义文件类型。这些将让你阅读&将原语(boolean,char,byte,int,long,float,double)写入流。阅读和阅读也有一些方便的方法。编写UTF-8编码的字符串,字节数组和其他一些好东西。
让我们开始吧。
为了论证,让我们假装我的所有数据元素都是字节数组。他们每个人都有一个名字。所以我的文件类型可以在逻辑上建模为Map<String, byte[]>
。我将实现我的自定义文件类型读取器/编写器类:
public class MyFileTypeCodec {
public static void writeToFile(File f, Map<String, byte[]> map)
throws IOException {
// Create an output stream
DataOutputStream stream = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(f))
);
// Delegate writing to the stream to a separate method
writeToStream(stream, map);
// Always be sure to flush & close the stream.
stream.flush();
stream.close();
}
public static Map<String, byte[]> readFromFile(File f)
throws IOException {
// Create an input stream
DataInputStream stream = new DataInputStream(
new BufferedInputStream(new FileInputStream(f))
);
// Delegate reading from the stream to a separate method
Map<String, byte[]> map = readFromStream(stream);
// Always be sure to close the stream.
stream.close();
return map;
}
public static void writeToStream(DataOutputStream stream, Map<String, byte[]> map)
throws IOException {
// First, write the number of entries in the map.
stream.writeInt(map.size());
// Next, iterate through all the entries in the map
for (Map.Entry<String, byte[]> entry : map.entrySet()) {
// Write the name of this piece of data.
stream.writeUTF(entry.getKey());
// Write the data represented by this name, making sure to
// prefix the data with an integer representing its length.
byte[] data = entry.getValue();
stream.writeInt(data.length);
stream.write(data);
}
}
public static Map<String, byte[]> readFromStream(DataInputStream stream)
throws IOException {
// Create the data structure to contain the data from my custom file
Map<String, byte[]> map = new HashMap<String, byte[]>();
// Read the number of entries in this file
int entryCount = stream.readInt();
// Iterate through all the entries in the file, and add them to the map
for (int i = 0; i < entryCount; i++) {
// Read the name of this entry
String name = stream.readUTF();
// Read the data associated with this name, remembering that the
// data has an integer prefix representing the array length.
int dataLength = stream.readInt();
byte[] data = new byte[dataLength];
stream.read(data, 0, dataLength);
// Add this entry to the map
map.put(name, data);
}
return map;
}
}
基本思想是,如果您可以将该数据表示为某些基元组合,则可以将任何数据写入输出流(并再次读回)。数组(或其他集合)可以加上它们的长度作为前缀,就像我在这里做的那样。或者,如果你在最后放置一个TERMINUS标记(类似于以空字符结尾的字符串),你可以避免写长度前缀。
当我实现自定义文件类型编解码器时,总是使用这种设置,文件IO方法委托给流IO方法。通常,我后来发现我正在阅读的对象&amp;从这个流写入可以很容易地写入一些更大的&amp;更复杂的文件。
所以我可能有一个SuperFancyCodec
用于读取/写入整个系统的数据,然后调用我的TinySpecialPurposeCodec
。只要流阅读&amp;写作方法是公开的,然后我可以使用面向组件的方法组装新的文件类型。
答案 1 :(得分:3)
扩展通常与解释文件的方式无关。
如果您只想config.dat
代替config.xml
,则只需重命名该文件即可。 (您通常会为xml-parser提供InputStream
或Reader
作为输入,可以读取任何文件,无论扩展名如何)
如果您所描述的问题是将将多个文件(.zip,.jar等)合并到一个.dat文件中,您可以将它们压缩在一起,并命名为扩展名为.dat的zip文件。 Java对zip文件有很好的支持,无论文件名/扩展名如何,都可以处理zip文件。
答案 2 :(得分:1)
在使用Java(或其他任何东西)创建/读取文件时,文件扩展名不会严格依赖于文件数据的实际结构。如果我想,我可以创建一个XML文件file.gweebz
。操作系统和应用程序不知道如何处理它,但一旦打开,很明显它是XML。
话虽这么说,遵循已经建立的约定通常是好的,通常.dat
文件是二进制格式的文件。您可以根据需要使用.dat,但要注意某些用户可能具有文件类型的操作系统绑定,并且单击您的文件可能会导致其系统上出现与预期不同的行为。
至于如何在Java中完成它。用Java抓取文件句柄很容易......
File myFile = new File("/dir/file.gweebz");
就这么简单,你可以随意命名。您将需要其他类来编写和读取文件或进行压缩,但我会假设您知道如何执行此操作。如果没有,这个网站将有答案。