3 Ekim 2012 Çarşamba

Java JFileChooser dosya açma ve kaydetme mantığı.

http://yazilimsozluk.com/Default.aspx?KonuId=1674 da bir soruya cevap olarak benim tarafımdan yazılmıştır.


Dostum şimdi o olay şöyle. Şimdi adam menübar ı açtı. Aç a bastı. Bir path e ilerledi bir dosya seçti ve open a bastı. Sen burada getSelectedFile diyip adamın seçtiği dosyayının referansını alman lazım.
Bu dosya ne dosyası ise istersen bu dosyayı okuyup adama içeriğini gösterip üstünde değişiklik te yaptırabilirsin, neyse.
Şimdi bu dosyayı başka bir yere kayıt ediceksin diyelim. Senin yine filechooser ın showSaveDialog unu kullanman lazım. Onu açıcaksın adam bir path seçicek, aşağıdan dosyanın ismini girecek ve kaydet e basıcak.
Kaydet e bastığında senin daha önce açılmış dosyayı byte byte okuyup adamın seçtiği yere yazman lazım.
Okuyup yazarken fileinputstream,fileoutputstream kullanabilirsin. Ya da fileutils gibi bir kütüphane nin copy metodunu da kulanabilirsin ya da channel acıp yollayabilirsin.
Biraz da kodda anlatmaya çalışayım.

Şimdi adam menübar dan aç a bastığında

//frmDosyaAcKaydet JFileChooser tipinde.
frmDosyaAcKaydet.showSOpenDialog(anaFrame);

diyip açtın dosya açma kısmını. Adam seçti dosyayı. Dosyayı seçtiği anda senin şöyle bir kod çalıştırman lazım.

//Kullanıcının seçtiği dosya. io kütüphanesinin File tipinde dönen bir değer
//frmDosyaAcKaydet JFileChooser tipinde.
acilanDosya = frmDosyaAcKaydet.getSelectedFile();

şimdi bu değeri bir yerde tuttun. Adamın seçtiği dosyaya bir referansın var artık.

Daha sonra adam menubar dan kaydet e bastığında senin

//frmDosyaAcKaydet JFileChooser tipinde.
frmDosyaAcKaydet.showSaveDialog(anaFrame);

gibi bir kod çalıştırman lazım. Bu şekilde istediğin gibi bir kaydetme frame i açılmış olacak. Adam sonra gitti bir path e dosya adını girdi ve kaydet butonuna bastı. Çalışacak kod şöyle birşey olmalı.

//frmDosyaAcKaydet JFileChooser tipinde.
//Kullanıcının kaydetmek için seçtiği path ve dosya adı. io kütüphanesinin File tipinde dönen bir değer
File kaydedilecekDosya = frmDosyaAcKaydet.getSelectedFile();
  //Dosya yazmak için output stream açıyoruz
  OutputStream st = null;
  try {
   st = new FileOutputStream(kaydedilecekDosya);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }
  //Byte array tanımlıyoruz. Buradan dosyayı okuyup outputstream vasıtasıyla yeni yere yazıcaz.
  byte[] buffer=new byte[1024];
  int okunanByte=0;
  //Dosyayı burada 1024 lük bloklar halinde okuyup yeni
  //path ine yazıyoruz.
  try {
   while ((okunanByte=acilanDosya.read(buffer))>0){
    try {
     st.write(buffer,0,okunanByte);
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  } catch (IOException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }
  try {
   st.flush();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  try {
   acilanDosya.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  try {
   st.close();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

  Böylece dosyayı yeni yerine yazmış oluruz. Bu okuma ile yazma arasında geçen sürede dosya üzerinde istediğin
  değişiklikleri yapıp o şekilde de yazabilirsin. Mesela bir text dosyasıysa dosyayı açarsın stringbuffer a alıp
  kullanıcıya gösterirsin üstünde değişiklikler yapar kullanıcı daha sonra da değişiklikyapılandosya.getBytes();
  ı alıp fileoutputstream in write metodunu kullanarak yeni yerine yazabilirsin.

  Benden bu kadar :-) . Umarım işine yarar dostum. Takıldığın ya da anlamadığın birşey olursa
  yardımcı olmaya çalışırım yine. Kolay gelsin.

22 Eylül 2012 Cumartesi

Hudson ve Sonar (Continuous Integration Softwares)

http://yazilimsozluk.com/Default.aspx?KonuId=1579 da bir soruya cevap olarak benim tarafımdan yazılmıştır.


•Bir senaryo üzerinden açıklamaya çalışayım.
Hudson ile başlayayım. Mesela ortada bir tane web projesi var. Büyük bir proje yaklaşık 9 kişi gerçekliyor olsun. Proje elemanları arasındaki hiyerarşik düzen de 1 üst yönetici, 1 takım lideri, onun altında 2 tane tecrübeli eleman, bunun altında da 5 tane junior çalışan olsun. Bunlardan 3 ü client side ta 2 si de server side da çalışıyor olsun. Proje için bir ant task hazırlanmış olsun ve herkes kendi serverına ayrı ayrı deploy ederek çalıştırıyor olsun. Bir tane de test server ı olsun ara ara projenin son halinin buraya deploy edilmesi şart olsun. Şimdi hudson dediğimiz amcaya bir ant task vasıtasıyla bu projenin kurulumunu yaparsın. Projede çalışan elemanları tanıtırsın. Hudson amcam senin belirlediğin zamanlarda(svn e her committe,günlük,haftalık,aylık istediğin periodlarda) bu projeyi svn den çeker, kullandığın ant task ı çalıştırır, projeyi derler, testleri çalıştırır, war haline getirir,server a deploy eder ve kodları sonar a atar(sonar ı aşağıda açıklayacağım). Böylece kodun istediğin zamanlarda en güncel hali server da bulunmuş olur. Diyelim ki birisinin commit tinden sonra kod düzgün çalışmamaya başladı, server a deploy edilemedi ya da testlerden biri patladı. Hudson amcam gider bu developer arkadaşa mail atar. Der ki bak senin şu commmit tinden sonra şu kodlar patladı ya da şu test patladı diye. Ne olur başka birinin ruhu bile duymadan developer o hatayı düzeltebilir. Hatta bir ws aracılığıyla cep telefonuna mesaj bile attırtabilirsin(Henüz denemedim). Ayrıca durumdan yöneticiyi takım liderini ya da her kimi istiyorsan onları da haberdar edebilir. Herşey configurasyona kalmış. Bence yazılım geliştirmede inanılmaz faydalar sağlayan bir amcamızdır.

Gelelim sonar a. Yukarıda bir bölümde dedik ki hudson herşeyi yapar kodları sonar a paslar. Sonar ne yapar? Sonar da alır bu kodları analiz eder. Der ki arkadaş bak senin projende 60000 satır kod var bu kodun şu kadarında comment var, bu kadarında yalnış yazımlar var ,şuralarda türkçe karakter kullanmışsın, buralarda treadsafe olmayan bir operasyon var , bak şu metodunun complexity si fazla bak bu metodda çok fazla satır var, bak arkadaş sen if açmışsın ama içini doldurmamışsın bunu niye açtın, bak burda bir for var boşu boşuna dönüyor bu nedir, arkadaş şu metoda niye bu kadar az comment yazdın ve daha sayamıycağım bir çok noktada developerları uyarıyor ve kod kalitesini inanılmaz ölçüde arttırıyor.
Yani bu 2 yazılımı kullanarak verdiği uyarıları kulak arkası yapmayıp uygun şekilde şekillenirse proje, ileriki zamanlarda bakım işleri de çok kolaylaşıyor ve sağlam bir proje olmak için bir adam öne çıkıyor.

Elimden geldiğince anlatmaya çalıştım. Herkese kolay gelsin..

16 Eylül 2012 Pazar

StringBuilder vs String +=


package deneme;

import java.util.Calendar;

package deneme;

import java.util.Calendar;



/**
 *
 *
 *
 * @author Murat Güzel
 *
 * StringBuilder vs String += operand
 *
 */
public class Deneme {

public static void main(String[] args) {
Calendar calendar1 = Calendar.getInstance();    //1
String s = "";
for (int i = 0; i < 50000; i++) {
s += "asdasd";
}
Calendar calendar2 = Calendar.getInstance();    //2
System.out.println("String += : " + (calendar2.getTimeInMillis()
- calendar1.getTimeInMillis()));

Calendar calendar3 = Calendar.getInstance();
StringBuilder ss = new StringBuilder();
for (int i = 0; i < 50000; i++) {
ss.append("asdase");
}
Calendar calendar4 = Calendar.getInstance();    //3
System.out.println("StringBuilder.append : " + (calendar4.getTimeInMillis()
- calendar3.getTimeInMillis()));
}

}


Output :

String += : 4454
StringBuilder.append : 1

MemoryKullanımı : 
//1 de ki konumlandırılan breakpointte jawaw.exe memory kullanımı 6000K
//2 de ki konumlandırılan breakpointte jawaw.exe memory kullanımı 22576K
//3 de ki konumlandırılan breakpointte jawaw.exe memory kullanımı 22900K


Görüldüğü gibi bu işlem StringBuilder ile çok kısa bir zamanda ve çok daha az memory kullanılarak yapılmaktadır. Bu da bir projede çokça yapılan string operasyonlarında 2 teknik arasında büyük bir fark açığa çıkmasına neden olur.

Web projelerinde string operasyonları

     Mesela diyelim ki bir web projeniz var ve proje bolca string operasyonu yapıyor. Bazı veriler alıyor onları birleştiriyor, parçalıyor ve output olarak ta bir text file oluşturuyor.

     String operasyonları yaparken += operatörünü kullanmaktan kaçınmamız gerekiyor elden geldiğince. Özellikle de döngülerin içinde. Çünkü bu işlem inanılmaz memory yiyor ve cpu yu çok yoruyor. Bunun yerine StringBuilder vb birşey kullanmamız gerekiyor.

     Javadan örnek vermek gerekirse bu yapıya alternatif olarak StringBuilder ve StringBuffer ımız var. Bunların birbirlerinden farkı StringBuilder ın synchronized metodu yoktur yani ThreadSafe değildir. StringBuffer ın ise hemen bütün metodları synchronized tır.Diyelim ki global bir string üzerinde değişiklikler yapıcaksınız, sessionların verileri birbirine karışmaması için StringBuffer kullanmalısınız. Eğer metod içi işlemler varsa StringBuilder işinizi görücektir.Gereksiz yerde StringBuffer kullanımı sistemi inanılmaz yavaşlatır.Tüm metodları synchronized olduğu için bir nevi lock unlock mekanızması vardır ve metodlar üzerinden tek threadden fazlası dolaşamaz.

 Yani kısaca ;

 String s = "";
 for(int i=0;i<100;i++){
    s+="asdasdasd";
}

yerine ;


StringBuilder s = new StringBuilder();
 for(int i=0;i<100;i++){
    s.append("asdasdasd");
}

kullanılmalıdır. Eger bu işlemi bir test ortamında 1000000 kere döndürüp memory ve zaman sonuçlarını karşılaştırırsanız farkı kolaylıkla görebilirsiniz.



8 Ağustos 2012 Çarşamba

mysql tekrarlı kayıtları silme

ben bu şekilde yapıyorum tabloda çok fazla data yoksa. 
CREATE TABLE tekrarlıKayıtlarıSilinmisTablo AS SELECT DISTINCT * FROM asilTablo
verilerin düzgünlüğünden emin isen asilTabloyu silip , tekrarlıKayıtlarıSilinmisTablo adını istediğin gibi değiştirebilirsin.

Yeni tablo create etmek istemiyorsanız

delete from asilTablo where id in (select    geciciTablo .id  from (select asilTablo .id  from asilTablo   where asilTablo .id not in (select asilTablo .id  from asilTablo  group by asilTablo .id  )) as geciciTablo);

gibi birşey işinizi görebilir sanırsam.

5 Ağustos 2012 Pazar

Java email gönderme



package main;

/**
 * @author Murat GUZEL
 * Java ile email yollamaya yarayan classtır.
 * mail.jar ve activation.jar a bağımlılığı vardır.
 *
 */
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Sender {
public static void main(String [] args)
{
/**
* Oncelikle email in yollanacağı adresin
* bilgilerini giriyoruz.
*
*/
String hostAdresi = "smtp.gmail.com";
String gonderimAdresi = "abcdef@gmail.com";
String gonderimAdresiSifresi = "abcdef";
Properties sistemProp = System.getProperties();
sistemProp.put("mail.smtp.starttls.enable", "true");
sistemProp.put("mail.smtp.host", hostAdresi);
sistemProp.put("mail.smtp.user", gonderimAdresi);
sistemProp.put("mail.smtp.password", gonderimAdresiSifresi);
sistemProp.put("mail.smtp.port", "587");
sistemProp.put("mail.smtp.auth", "true");

/**
* Gonderilecek adresileri set ediyoruz.
*
*/
String[] gonderilecekAdresler = {"abcdeff@hotmail.com","defghs@gmail.com"};

Session session = Session.getDefaultInstance(sistemProp, null);
MimeMessage gonderilecekMesaj = new MimeMessage(session);
/**
* yollayıcı adresimize bağlantı tanımlıyoruz.
*
*/
try {
gonderilecekMesaj.setFrom(new InternetAddress(gonderimAdresi));
} catch (AddressException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
} catch (MessagingException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}

InternetAddress[] gonderilecekEmailAdresleri = new InternetAddress[gonderilecekAdresler.length];

/**
* Gonderilecek adresleri string array den
* internet adreslerine dönüştürüyoruz.
*
*/
for( int i=0; i < gonderilecekAdresler.length; i++ ) { // changed from a while loop
try {
gonderilecekEmailAdresleri[i] = new InternetAddress(gonderilecekAdresler[i]);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* tanımladığımız bağlantıya gönderilecek adresleri
* ekliyoruz.
*
*/
for( int i=0; i < gonderilecekEmailAdresleri.length; i++) { // changed from a while loop
try {
gonderilecekMesaj.addRecipient(Message.RecipientType.TO, gonderilecekEmailAdresleri[i]);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
gonderilecekMesaj.setSubject("E-mail deneme.");
} catch (MessagingException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
/**
* Mesajı set ediyoruz.
*
*/
try {
gonderilecekMesaj.setText("Burası mesaj bölümüdür.");
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Transport transport = null;
try {
transport = session.getTransport("smtp");
} catch (NoSuchProviderException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
/**
* connection açıyoruz.
*
*/
try {
transport.connect(hostAdresi, gonderimAdresi, gonderimAdresiSifresi);
} catch (MessagingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
/**
* mesajı yolluyoruz.
*
*/
try {
transport.sendMessage(gonderilecekMesaj, gonderilecekMesaj.getAllRecipients());
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

/**
*
* connection kapatıyoruz.
*/
try {
transport.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}