2017-10-11 13 views
0

ピクセル配列をディスクに書き込んで、そのファイルを同じアプリケーションで読み込む必要があります。何らかの理由で、アプリケーションが終了するまで、ファイルはディスクに書き込まれません。 (それだけが、保存されているディレクトリに表示されます)。私はIntelliJ IDEAにこのアプリケーションを書いています。アプリケーションが終了する前にイメージをディスクに保存する方法は?

ファイルがすぐにディスクに書き込まれるようにするにはどうすればよいですか?私のコードは次のとおりです。

protected void savePixelstoPNG(int[] pixels, String fileName) { 
    BufferedImage image = new BufferedImage(getMapWidth(), getMapHeight(), BufferedImage.TYPE_INT_RGB); 
    Graphics graphics = image.getGraphics(); 

    for(int y = 0; y < getMapHeight(); y++) { 
     for(int x = 0; x < getMapWidth(); x++) { 
      graphics.setColor(new Color(pixels[x + y * getMapWidth()])); 
      graphics.fillRect(x, y, 1, 1); 
     } 
    } 

    try { 
     File file = new File(fileName); 
     ImageIO.write(image, "PNG", file); 
    } catch(IOException e) { 
     e.printStackTrace(); 
    } 
} 

EDIT:私はフォルダを調べて、実際にはすぐにディスクに書き込んでいます。ただし、これらの変更は、アプリケーションが終了するまで、プロジェクトディレクトリに反映されません(ファイルはJavaパッケージに保存されます)。だから、私はそれらを保存した後(同じアプリケーションの寿命内に)それらのファイルを読むために行くとき、アプリケーションはディスク上に存在するにもかかわらず、ファイルを見つけることができません。

EDIT 2:ここでは、クラスパスから相対ディレクトリパスを使用してファイルを読み込むコードを示します。初期リソースはクラスパスから読み込まれます。それらが更新されると、元のリソースが上書きされないように、元のリソースが最初にアプリケーションが新たに実行されるたびに読まれることになっていることから、それらは、クラスパスに別のディレクトリに書き込まれます。

void myLoadMethod() { 
     loadMapTiles("resource/tilemap_1-1.png"); 
     loadTriggerTiles("resource/triggermap_1-1.png"); 
} 


protected void loadMapTiles(@NotNull String path) { 
     URL url = getClass().getClassLoader().getResource(path); 
     loadTiles(url, mapTiles); 
} 

protected void loadTriggerTiles(@NotNull String path) { 
     URL url = getClaass().getClassLoader().getResource(path); 
     loadTiles(url, triggerTiles); 
} 

protected void loadTiles(@NotNull URL url, @Nullable int[] dest) { 
     try { 
      System.out.println("Trying to load: " + url.toString() + "..."); 
      BufferedImage map = ImageIO.read(url); 
      int[] pixels = new int[mapWidth * mapHeight]; 
      map.getRGB(0, 0, mapWidth, mapHeight, pixels, 0, mapWidth); 
      System.arraycopy(pixels, 0, dest, 0, dest.length); 
      System.out.println("Success!"); 
     } catch (IOException e) { 
      System.out.println("failed..."); 
      e.printStackTrace(); 
     } 
    } 
} 

mapTilesをそのtriggerTilesは、保持するクラスに含まれるフィールドです。loadMapTilesloadTriggerTilesおよびloadTiles

+0

私の知る限りではなく、 'ImageIOでの#のwrite'への静的呼び出しを自動的 – DayTripperID

+0

がどのようにそれらを読んしようかということを行います。あなたは、絶対URLが必要な場合には、このようにそれを行うことができますか?あなたはファイルがクラスパスにあると仮定しますか、または外部からですか? "ファイルはjavaパッケージに保存されている"ため、(source)ディレクトリに書き込むことができますが、クラスパスから読み込もうとすると、IntelliJで新しい実行を開始するとクラスパスにコピーされます。 – cello

+0

はい!私はクラスパスから相対ディレクトリでインスタンス化されたURLを使用して読み込みます。相対ディレクトリに書き込む方法がわからないので、絶対ディレクトリに書きました。私はそれが相対ディレクトリを認識することができませんでした(ディレクトリが見つかりませんでした)ので、私はどのように相対ディレクトリに書き込むかを理解する必要がありますか? – DayTripperID

答えて

1

ソースファイルとクラスパスを区別する必要があります。

ソースは通常、何らかの種類のsrcディレクトリにあります。例えば。 Mavenプロジェクトのための標準は、他のリソースのsrc/main/java*.java用のファイルとsrc/main/resources*.propertiesなど

あるしかし、その後のJavaファイルがコンパイルされ、*.classファイルは、いくつかの出力ディレクトリにコピーされます。例えば。 Mavenの場合はtarget/...、その他のツールの多くはbinまたはoutputです。リソースは同じ場所に保存されます。

ファイルをsrcに書き込み、他の場所から読み込もうとしているようです(例:Class#getResourceAsStream(path)はクラスパスからデータを読み込みます)。あなたが次のアプリケーションの実行ファイルを読むことができるという事実は、次のビルドでは、出力ディレクトリにコピーされ、あなたのアプリケーションに「可視」になると思います。あなたのコード

URL url = getClass().getClassLoader().getResource(path); 

は(${projectRoot}/target/classes/${path}でおそらく)それはクラスパス上にあると期待されているファイルへのURLを構築します。

File file = new File(fileName); 

は(おそらく相対${projectRoot}に)実行ディレクトリからの相対パスでファイルを作成しますが。

一般に、ClassLoader#getResource(path)は、クラスパス上の静的リソースを取得するためにのみ使用してください。ディスク使用Paths#get(path)にパスを構築するための

Paths.get(path).toURI().toURL(); 
+0

元の質問のEDIT2の下でファイルを読むために使用したコードを追加しました。書かれたコードは元の質問に含まれていますので、うまくいけばそれはすべてです。 – DayTripperID

+0

あなたの相対的な場所の基点には注意が必要です。絶対使えますか?または、ベースディレクトリをパラメータとして渡しますか? –

+0

私は絶対的な使用に問題はありません。しかし、私が絶対的に実行している問題は、プロジェクトルート全体ではなく、ファイルシステム全体のルートディレクトリにディレクトリを指定する必要があることです。例えば ​​'/ home/user/IdeaProjects/MyProject/src/my_image.png'のように、どこかで正しく設定されていないものがあります。あなたの説明が理にかなっているので、私はあなたの答えをマークしています。 – DayTripperID

関連する問題