2015-01-24 5 views
0

저는 현재 게임이 시작될 때 임의의 세계 Gen을 가진 Java로 게임을 만들고 있습니다. 타일 ID, X 위치 및 Y 위치를 저장하여 게임을 다시로드하면 게임을 다시 생성 할 수 있습니다.FileWriter를 사용한 Java UTF-8 인코딩

내 파일을 쓸 때 모두 작동하지만 한 가지 문제가 있습니다. 파일 출력은 이상한 문자 조합입니다.

코드 : 파일에

import java.io.*; 

public class FileWrite {  
    public static FileWriter writeFile; 
    public static BufferedWriter write; 

    public static void recordItem(int blockID, int blockX, int blockY, String filePath, String fileName) throws Exception { 
     writeFile = new FileWriter("res/save/" + filePath+ fileName, true); 
     write = new BufferedWriter(writeFile); 

     write.write(blockID); 
     write.write(blockX); 
     write.write(blockY); 
     write.newLine(); 
     write.flush(); 
    } 
} 

출력 :

@ 
` 
? 
  
? 
? 
? 
? 
? 
? 
? 
? 

가 어떻게 UTF-8로 내 FileWriter를 인코딩 할은 그래서 번호를 표시? 도와 주셔서 감사합니다. :)

답변

0

write 메서드는 단일 문자를 작성하므로 블록 식별자 유니 코드 코드 포인트 (blockX, blockX, blockY)를 사용하여 문자를 쓰고 있습니다.

Writer가 UTF-8로 인코딩되었는지 여부는 여기에서 그다지 중요하지 않습니다. 파일을 컴퓨터간에 이식 할 수 있도록하려면 인코딩에 대해 명시 적으로 명시하는 것이 좋지만 직접 FileWriter를 만드는 대신 new OutputStreamWriter(new FileOutputStream("res/save/" + filePath+ fileName, true), "UTF-8");을 사용해보십시오. 직접 생성하면 인코딩을 지정할 수 없습니다.

는 대신 같은 것을 할 :

writer.write(String.format("%d %d %d\n", blockID, blockX, blockY)); 

이 파일로 전송하기 전에 한 줄에 하나의 문자열로 세 개의 숫자를 포맷합니다.

줄을 쓸 때마다 새 Writer/BufferedWriter를 만들지 마십시오. 학생들을 수업장에두고 동일한 작가를 다시 사용해야합니다. 또한 운영 체제에서 동시에 열어 본 파일 수에 제한이 있기 때문에 파일을 닫은 후에 닫아야합니다. 그러면 현재 코드로 해당 번호가 빠져 나올 수 있습니다.

+0

대단히 감사합니다. 나는 네가 제안한 것을 했어. 나는 또한 당신이 진술 한 다른 것들을하기 위해 노력할 것입니다, 대단히 감사합니다. :) – FireRaven

1

좀 더 강력한 형식의 영구 정보를 만들고 싶다면 객체 직렬화를 고려해보십시오. 그것은 소리보다 쉽습니다. 파일 이름 지정,

static class JunkRec implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 
    final int _blockID, _blockX, _blockY; 
    final String _filePath, _fileName; 
    public JunkRec(int blockID, int blockX, int blockY, 
        String filePath, String fileName) 
    { 
     _blockID = blockID; 
     _blockX = blockX; 
     _blockY = blockY; 
     _filePath = filePath; 
     _fileName = fileName; 
    } 
    @Override 
    public String toString() { 
     return String.format("id=%08d x=%04d y=%04d fp=%s fn=%s", 
       _blockID, _blockX, _blockY, _filePath, _fileName); 
    } 
} 

지금, 하나의 방법은 JunkRec를 저장하는 ...

public static void storeJunk(JunkRec jr) 
{ 
    try (
     FileOutputStream fos = new FileOutputStream(
       jr._filePath + jr._fileName + ".ser"); 
     ObjectOutputStream oos = new ObjectOutputStream(fos);) { 
     oos.writeObject(jr); 
    } catch (IOException ioe) { 
     ioe.printStackTrace(); 
    } 
} 

JunkRec를 복원하는 또 다른 방법 : 그냥이 같은 정적 내부 Serializable를 구현 클래스, 뭔가가있다.

public static JunkRec retrieveJunk(String filePath, String fileName) 
{ 
    try (
     FileInputStream fis = new FileInputStream(
       filePath + fileName + ".ser"); 
     ObjectInputStream ois = new ObjectInputStream(fis);) { 
     return (JunkRec) ois.readObject(); 
    } catch (IOException | ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

그리고) (주에서 마지막으로 약간의 테스트 드라이버

은 ...

public static void main(String[] args) 
{ 
    // generate and restore 10 records 
    Random r = new Random(); 
    List<String> names = new ArrayList<>(); 
    /* do a few in two ways */ 
    for (int i = 0; i < 5; ++i) { 
     int blk = r.nextInt(10000); 
     String fname = String.format("BLKID_%02d", i); 
     if (names.add(fname)) { 
      JunkRec jr = new JunkRec(
        r.nextInt(10000), 
        r.nextInt(50), 
        r.nextInt(50), 
        "/tmp/", 
        fname); 
      storeJunk(jr); 
      System.out.println("Wrote: "+jr); 
     } 
    } 

    /* read them all back */ 
    for (String fname : names) { 
     JunkRec jr = retrieveJunk("/tmp/", fname); 
     System.out.println("Retrieved: " + jr + " from " + fname); 
    } 

    /* clean up */ 
    for (String fname : names) { 
     ((File) new File("/tmp/" + fname + ".ser")).delete(); 
    } 
} 

이없는 생산 품질의 코드는하지만 쉽게 직렬화 될 수있는 방법을 보여줍니다. 문제가 있지만 일반적으로 직렬화는 파일 기반 지속성을위한 견고한 솔루션입니다.

그냥 제안. 재미있게 보내세요!

+0

제안 해 주셔서 감사합니다. :) – FireRaven