因此,在使用Java制作RPG的过程中,我发现制作一个程序可以让我创建一个地图并保存它而不必编辑字节数组的数字会很好。我需要能够将地图保存到文本文件中,以便可以在RPG中读取和重新创建它。但是我无法弄清楚如何将2D字节数组写入文件。
例如:
byte[][] map = new byte[][]{ {0,0,0,0,0}, {1,1,1,0,0} };
我希望文本文件能够输出如下内容:
0 0 0 0 0
1 1 1 0 0
我将如何将2d字节数组的内容写入文本文件?
答案 0 :(得分:2)
IMO最简单的方式:
// create your output stream. Use the current running directory for your project
FileOutputStream fout = new FileOutputStream(new File(System.getProperty("user.dir"), "test.txt"));
// print it out so you know where it is... maybe?
System.out.println(new File(System.getProperty("user.dir"), "test.txt"));
byte[][] map = new byte[][] { { 0, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0 } };
// loop through your map, 2d style
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
// get the string value of your byte and print it out
fout.write(String.valueOf(map[i][j]).getBytes());
}
// write out a new line. For different systems the character changes
fout.write(System.getProperty("line.separator").getBytes());
}
// close the output stream
fout.close();
答案 1 :(得分:2)
你可以使用MappedByteBuffer,它可以有效/快速地进行IO操作:
//Bytes
byte[][] map = new byte[][]{ {0,0,0,0,0}, {1,1,1,0,0} };
//Path to Desktop in this case
Path pathway = Paths.get(System.getProperty("user.home")).resolve("Desktop").resolve("MyNewFile.txt");
//Get size of file we will need, this is the size of each array (5 bytes) * num of arrays
// + line separator space * number of arrays as is one for each line separation
int size = ((map[0].length * map.length)) + System.lineSeparator().getBytes().length * map.length;
//Random access file for MappedByteBuffer. Put in try() for autoclose
try(RandomAccessFile raf = new RandomAccessFile(pathway.toFile(), "rw")){
//MappedByteBuffer for speed
MappedByteBuffer mBuff = raf.getChannel().map(MapMode.READ_WRITE, 0, size);
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
mBuff.put(String.valueOf(map[i][j]).getBytes()); //Write value
}
mBuff.put(System.lineSeparator().getBytes()); //Write line break
}
} catch (IOException io) {
System.out.println("IO Error: " + io.getMessage());
}
答案 2 :(得分:1)
您可以使用ObjectOutputStream
包裹FileOutputStream
将2D数组写入文件,然后使用ObjectInputStream
包裹FileInputStream
再次读取它。 注意:这不会为您提供一个纯文本文件,您可以手动打开它来阅读和修改,如果这是你需要的,那么这不适合你。
以下是如何操作的示例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Serialization {
public static void main(String[] args) {
byte[][] toSerialize = new byte[][] {{0,0,0,0,0}, {1,1,1,0,0}};
byte[][] readArray;
try {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("my_file.dat"));
oos.writeObject(toSerialize);
oos.close();
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("my_file.dat"));
readArray = (byte[][]) ois.readObject();
for (int i = 0; i < readArray.length; i++) {
for (int j = 0; j < readArray[i].length; j++) {
System.out.print(readArray[i][j] + " ");
}
System.out.println();
}
ois.close();
} catch (Exception e) {}
}
}
在实践中,您希望将阅读和写作分开到单独的方法中,可能是save()
和load()
。我也强烈建议你像我一样不 catch (Exception e)
。
您可能还希望考虑使用种子来生成地图并存储地图,而不是将整个地图写入文件,但实现这完全是另一回事。
答案 3 :(得分:1)
这是一个非常乐观的实现,不检查可能发生错误的任何情况。这只是使用字节数组流而不是文件的示例。但它应该像使用文件输入和输出流替换字节数组流一样工作。通过检查格式错误的文件格式使其更加健壮。
这个想法是在每行之前加上它的长度,然后是行的字节。您的地图确实具有统一的列大小,因此您可以只保存每列的长度一次。根据自己的喜好调整它。玩得开心:
public static void main(String[] args) throws Exception {
byte[][] dungeon = new byte[][] {
{0,0,0,0,0},
{1,1,1,0,0}
};
ByteArrayOutputStream os = new ByteArrayOutputStream();
saveMap(os, dungeon);
ByteArrayInputStream in = new ByteArrayInputStream(os.toByteArray());
byte[][] maze = loadMap(in);
}
private static void saveMap(OutputStream saveStream, byte[][] dungeon) throws Exception {
try (BufferedOutputStream os = new BufferedOutputStream(saveStream)) {
for (int row=0; row<dungeon.length; row++) {
os.write(toBytes(dungeon[row].length));
os.write(dungeon[row]);
}
}
}
private static byte[][] loadMap(InputStream saveStream) throws Exception {
List<byte[]> rows = new ArrayList<>();
try (BufferedInputStream in = new BufferedInputStream(saveStream)) {
while (in.available() != 0) {
byte[] column = new byte[toInt(in.read(), in.read())];
for (int idx = 0; idx < column.length; idx++) {
column[idx] = (byte) in.read();
}
rows.add(column);
}
}
return rows.toArray(new byte[rows.size()][]);
}
private static byte[] toBytes(int value) {
return new byte[] { (byte) (value >>> 8), (byte) value };
}
private static int toInt(int high, int low) {
return (high << 8) | (0x00FF & low);
}
答案 4 :(得分:0)
制作一个嵌套for循环。
例如:
for(int i = 0; i < array.length; i++) { // first dimension (x)
for(int v = 0; v < array2.length; v++) { // second dimension (y)
array[i][v]....
}
}
答案 5 :(得分:0)
final PrintWriter writer = new PrintWriter("your-file-name.txt", "UTF-8");
final StringBuilder arrayContent = new StringBuilder();
for(byte outer[] : map) {
for(byte inner : outer) {
arrayContent.append(inner);
}
arrayContent.append("\n");
}
writer.write(arrayContent.toString());
writer.close();
你也必须处理来自PrintWriter的异常,但这取决于你是想要抛出它们还是在你的方法中捕获它们。