Ok, trying to transfer a specified directory of files over a socket, remove the directory objects from the arraylist, so only files are left, and transfer them 1 by 1 over the same socket. The arraylist here is filled with ONLY files, no directories. Heres the receive and send code for the client and server respectively . The code runs fine without errors, except for ALL the data is being written to the first file. The subsequent files are created in the server folder, but they are 0 bytes. Any input would be greatly appreciated.
THIS IS THE SERVER CODE FOR RECEIVING THE FILES
public void receive(){
try {
DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
//read the number of files from the client
int number = dis.readInt();
ArrayList<File>files = new ArrayList<File>(number);
System.out.println("Number of Files to be received: " +number);
//read file names, add files to arraylist
for(int i = 0; i< number;i++){
File file = new File(dis.readUTF());
files.add(file);
}
int n = 0;
byte[]buf = new byte[4092];
//outer loop, executes one for each file
for(int i = 0; i < files.size();i++){
System.out.println("Receiving file: " + files.get(i).getName());
//create a new fileoutputstream for each new file
FileOutputStream fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" +files.get(i).getName());
//read file
while((n = dis.read(buf)) != -1){
fos.write(buf,0,n);
fos.flush();
}
fos.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
THIS IS THE CLIENT CODE FOR SENDING THE FILES
public void send(ArrayList<File>files){
try {
DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
System.out.println(files.size());
//write the number of files to the server
dos.writeInt(files.size());
dos.flush();
//write file names
for(int i = 0 ; i < files.size();i++){
dos.writeUTF(files.get(i).getName());
dos.flush();
}
//buffer for file writing, to declare inside or outside loop?
int n = 0;
byte[]buf = new byte[4092];
//outer loop, executes one for each file
for(int i =0; i < files.size(); i++){
System.out.println(files.get(i).getName());
//create new fileinputstream for each file
FileInputStream fis = new FileInputStream(files.get(i));
//write file to dos
while((n =fis.read(buf)) != -1){
dos.write(buf,0,n);
dos.flush();
}
//should i close the dataoutputstream here and make a new one each time?
}
//or is this good?
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You are reading the socket until read() returns -1. This is the end-of-stream condition (EOS). EOS happens when the peer closes the connection. Not when it finishes writing one file.
You need to send the file size ahead of each file. You're already doing a similar thing with the file count. Then make sure you read exactly that many bytes for that file:
String filename = dis.readUTF();
long fileSize = dis.readLong();
FileOutputStream fos = new FileOutputStream(filename);
while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1)
{
fos.write(buf,0,n);
fileSize -= n;
}
fos.close();
You can enclose all this in a loop that terminates when readUTF() throws EOFException. Conversely of course you have to call writeUTF(filename) and writeLong(filesize) at the sender, before sending the data.
I did it like this, it is working perfectly, you can take a look:
Send
byte[] done = new byte[3];
String str = "done"; //randomly anything
done = str.getBytes();
for (int i = 0; i < files.size(); i++) {
System.out.println(files.get(i).getName());
FileInputStream fis = new FileInputStream(files.get(i));
while ((n = fis.read(buf)) != -1) {
dos.write(buf, 0, n);
System.out.println(n);
dos.flush();
}
//should i close the dataoutputstream here and make a new one each time?
dos.write(done, 0, 3);
dos.flush();
}
//or is this good?
dos.close();
Receive
for (int i = 0; i < files.size(); i++) {
System.out.println("Receiving file: " + files.get(i).getName());
//create a new fileoutputstream for each new file
fos = new FileOutputStream("C:\\users\\tom5\\desktop\\salestools\\" + files.get(i).getName());
//read file
while ((n = dis.read(buf)) != -1 && n != 3) {
fos.write(buf, 0, n);
fos.flush();
}
fos.close();
}
I have created a server and client. They are establishing connection and after that server is sending 1MB text file in every second. Server and client code is below. I have tested long duration and saw that there is no data lost. I have modified the above answered little bit.
SERVER CODE:
package com.dd.server;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
public class Server {
public static void main(String[] args) throws InterruptedException {
try {
byte[] done = new byte[3];
String str = "done"; //randomly anything
done = str.getBytes();
ServerSocket ss = new ServerSocket(5000);
Socket socket = ss.accept();
byte[] mybytearray = new byte[4096];
OutputStream os = socket.getOutputStream();
TimeUnit.SECONDS.sleep(5);
while(true) {
DataOutputStream dos = new DataOutputStream(os);
File myFile= new File("I:\\MY-LEARNINGS\\JAVA\\Workspace\\server\\src\\com\\dd\\server\\gistfile1.txt");
dos.writeUTF(myFile.getName());
dos.writeLong(myFile.length());
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int read;
System.out.println("---------File Writing started----------");
int count = 0;
while((read = dis.read(mybytearray)) != -1){
dos.write(mybytearray, 0, read);
dos.flush();
++count;
System.out.println("Writing sub component of file. Step : "+count);
}
System.out.println("---------File Writing ended----------");
System.out.println("Flushing data DONE command sent.");
dis.close();
bis.close();
fis.close();
TimeUnit.SECONDS.sleep(1);
System.out.println("File transfer has been completed.");
dos.write(done, 0, 3);
dos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
CLIENT CODE:
package clientcom.dd.clent;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 5000);
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
while(true) {
FileOutputStream fos =
new FileOutputStream("I:\\MY-LEARNINGS\\JAVA\\Workspace\\client\\"+System.currentTimeMillis()+"-data.txt");
int read = 0;
byte[] mybytearray = new byte[4096];
while ((read = dis.read(mybytearray)) != -1 && read != 3) {
fos.write(mybytearray, 0, read);
fos.flush();
}
fos.close();
//System.out.println("The value of read : "+read);
// System.out.println("File has been received successfully.");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Related
I'm trying to send multiple files from client to server using socket but when I click upload button it adds only one file second
Your copyFile() is not suitable for network transmissions.
You need to get rid of the two close() calls inside of copyFile(). On the client side, out.close() is closing the socket after the 1st file has been sent. On the server side, InputStream.close() is closing the socket after the 1st file has been received. It is the caller's responsibility to close the streams it passes to copyFile(), it is not copyFile()'s responsibility.
More importantly, for each file the client wants to send, copyFile() is not sending the file's byte count before sending the file's actual bytes, to indicate where each file ends and the next begins. So, on the server side, copyFile() does not know when to stop reading from the inputStream and will just keep reading endlessly until the connection is closed/broken.
As-is, copyFile() may work for copying files from one folder to another on the local system, but it is not suitable for copying files over a TCP network.
Try this instead:
Client side:
try {
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.d(TAG, "Client socket - " + socket.isConnected());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(fileUri.size());
for(String file : fileUri)
{
//long length = file.length();
//dos.writeLong(length);
String name = file;
dos.writeUTF(name);
File f = new File(file);
sendFile(f, dos);
}
dos.close();
Log.d(TAG, "Client: Data written");
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
}
catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
void sendFile(File in, DataOutputStream out) throws IOException {
long fileLength = in.length();
out.writeLong(fileLength);
FileInputStream fis = new FileInputStream(in);
BufferedInputStream bis = new BufferedInputStream(fis);
byte buf[] = new byte[1024];
int len;
while (fileLength > 0) {
len = bis.read(buf);
if (len == -1) throw new IOException();
out.write(buf, 0, len);
fileLength -= len;
}
}
Server side:
try {
ServerSocket serverSocket = new ServerSocket(8988);
Socket client = serverSocket.accept();
BufferedInputStream bis = new BufferedInputStream(client.getInputStream());
DataInputStream dis = new DataInputStream(bis);
int filesCount = dis.readInt();
File[] files = new File[filesCount];
for(int i = 0; i < filesCount; i++)
{
Log.d(TAG, "doInBackground: " + filesCount);
//long fileLength = dis.readLong();
String fileName = dis.readUTF();
files[i] = new File(context.getExternalFilesDir("received"), Long.toString(System.currentTimeMillis()) + ".mp4" );
Log.d(TAG, "doInBackground: 1" );
File dirs = new File(context.getPackageName() + files[i].getParent());
Log.d(TAG, "doInBackground: 2" );
if (!dirs.exists()) dirs.mkdirs();
files[i].createNewFile();
Log.d(TAG, "server: copying files " + files[i].toString());
receiveFile(dis, files[i]);
}
serverSocket.close();
return "done";
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
return null;
}
void receiveFile(DataInputStream in, File out) throws IOException {
long fileLength = in.readLong();
FileOutputStream fos = new FileOutputStream(out);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
int len;
while (fileLength > 0) {
len = (fileLength >= 1024) ? 1024 : (int) fileLength;
len = in.read(buf, 0, len);
if (len == -1) throw new IOException();
bos.write(buf, 0, len);
fileLength -= len;
}
}
I'm a newbie in android development and encounter this problem my client wish to stream video files from his camera storage to his android phone using only LAN connection.. is this possible? for now the only thing that i can do is play a video from the storage of the phone and stream http or RTSP streams video but is it possible to stream a video file while sending it through LAN? thank you.
#Androider-I apologize for not commenting because i can't anyway this is my code for now and any kind of help will be appreciated thank you.
Edited:
Client Side
`
public class Client extends Activi
ty {
private Socket client;
private FileInputStream fileInputStream;
private BufferedInputStream bufferedInputStream;
private OutputStream outputStream;
private Button button;
private TextView text;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button1);
text = (TextView) findViewById(R.id.textView1);
//Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
File file = new File("/storage/emulated/BaseAhri.jpg");
try {
client = new Socket("10.0.2.2", 4444);
byte[] mybytearray = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(mybytearray, 0, mybytearray.length);
outputStream = client.getOutputStream();
outputStream.write(mybytearray, 0, mybytearray.length);
outputStream.flush();
bufferedInputStream.close();
outputStream.close();
client.close();
text.setText("File Sent");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Server Side
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStream inputStream;
private static FileOutputStream fileOutputStream;
private static BufferedOutputStream bufferedOutputStream;
private static int filesize = 10000000;
private static int bytesRead;
private static int current = 0;
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(4444);
System.out.println("Server started. Listening to the port 4444");
clientSocket = serverSocket.accept();
byte[] mybytearray = new byte[filesize];
inputStream = clientSocket.getInputStream();
fileOutputStream = new FileOutputStream("/sdcard/DCIM/Camera/BaseAhri.jpg");
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);});
System.out.println("Receiving...");
bytesRead = inputStream.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
do {
bytesRead = inputStream.read(mybytearray, current, (mybytearray.length - current));
if (bytesRead >= 0) {
current += bytesRead;
}
} while (bytesRead > -1);
bufferedOutputStream.write(mybytearray, 0, current);
bufferedOutputStream.flush();
bufferedOutputStream.close();
inputStream.close();
clientSocket.close();
serverSocket.close();
System.out.println("Sever recieved the file");
}
Error Server Side
[2014-01-22 15:20:15 - AndroidSocketSERVER] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.javacodegeeks.android.androidsocketserver/.Server }
[2014-01-22 15:20:15 - AndroidSocketSERVER] ActivityManager: Error type 3
[2014-01-22 15:20:15 - AndroidSocketSERVER] ActivityManager: Error: Activity class {com.javacodegeeks.android.androidsocketserver/com.javacodegeeks.android.androidsocketserver.Server} does not exist.
And in the client side it crashes after i send.not sure if this is an error since my server have a problem....
#Androider -Sorry for late update,Here is my resulting code where i am now able to pass the video file and control it by bits but the problem is my data are always corrupted because of a missing byte or something like that and now how do i stream it? i am not able to play the file because it is not complete? if that's the case then what is the purpose of byte controll? i hope you can help me again thx.
COde Client and Server:
serverTransmitButton = (Button) findViewById(R.id.button_TCP_server);
serverTransmitButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.i("Start Server Button Clicked", "yipee");
try {
// create socket
// TODO: the port should match the one in Client
ServerSocket servsock = new ServerSocket(5005);
while (true) {
Log.i("************", "Waiting...");
Socket sock = servsock.accept(); // blocks until connection opened
Log.i("************", "Accepted connection : " + sock);
// sendfile
// TODO: put the source of the file
int filesize=8192;
File myFile = new File ("/sdcard/DCIM/Camera/test.mp4");
byte [] mybytearray = new byte [filesize];
Log.i("####### file length = ", String.valueOf(myFile.length()) );
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
Log.i("************", "Sending...");
int read;
while((read = fis.read(mybytearray)) != -1){
os.write(mybytearray,0,read);
}
os.flush();
os.close();
fis.close();
bis.close();
}
} catch (IOException e) {
Log.i("Io execption ", "e: " + e);
}
Log.i("=============== the end of start ==============", "==");
}
});
clientReceiveButton = (Button) findViewById(R.id.button_TCP_client);
clientReceiveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.i("Read Button Clicked", "yipee");
try {
int bufferSize;// filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current;
// localhost for testing
// TODO: server's IP address. Socket should match one above in server
Socket sock = new Socket("192.168.123.186",5005);
Log.i("************", "Connecting...");
// receive file
bufferSize=sock.getReceiveBufferSize();
byte [] mybytearray = new byte [bufferSize];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("/storage/emulated/0/testinggo.mp4");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
while((current = is.read(mybytearray)) >0){
bos.write(mybytearray, 0 , current);
}
bos.flush();
bos.close();
is.close();
sock.close
} catch ( UnknownHostException e ) {
Log.i("******* :( ", "UnknownHostException");
} catch (IOException e){
Log.i("Read has IOException", "e: " + e);
}
Log.i("=============== the end of read ===============", "==");
}
});
}
}
Actually it is. You will need to build your own socket server in app and play video from it. Then you will have control over byte input stream and save dowloaded part to file while same part will go to mediaplayer
i m writing .json file and i want to read that file,
but the problem is, when i try to read whole file as string it adds the space before and after every character and just because of extra chars it couldn't read json.
the Json format is
[{"description1":"The ThinkerA bronze sculpture by Auguste Rodin. It depicts a man in sober\nmeditation battling with a powerful internal struggle.","description2":"Steve JobsFounder of Apple, he is widely recognized as a charismatic pioneer of\nthe personal computer revolution.","description3":"Justin BieberBorn in 1994, the latest sensation in music industry with numerous\nawards in recent years."}]
but it gives weired response like:
[ { " d e s c r i p t i o n 1 " : " T h e .....
to trim extra spaces i refered to this, but stil didnt work:
Java how to replace 2 or more spaces with single space in string and delete leading spaces only
i m using this code
File folderPath = Environment.getExternalStorageDirectory();
File mypath=new File(folderPath, "description.json");
StringBuffer fileData = new StringBuffer(1000);
BufferedReader reader = null;
reader = new BufferedReader(new FileReader(mypath));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1)
{
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
String response = fileData.toString();
the "response" string contains weird response
so can anyone help me ?
for writing into file ,i m using :
FileOutputStream fos = new FileOutputStream(mypath);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeChars(response);
Write below method for Write Json File, Here params is a File Name and mJsonResponse is a Server Response.
For Create Files into Internal Memory of Application
public void mCreateAndSaveFile(String params, String mJsonResponse) {
try {
FileWriter file = new FileWriter("/data/data/" + getApplicationContext().getPackageName() + "/" + params);
file.write(mJsonResponse);
file.flush();
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
For Read Data From Json File, Here params is File Name.
public void mReadJsonData(String params) {
try {
File f = new File("/data/data/" + getPackageName() + "/" + params);
FileInputStream is = new FileInputStream(f);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String mResponse = new String(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I like above answer and edited: I just love to share so i have shared that may be useful to others.
Copy and Paste following class in your package and use like:
Save: MyJSON.saveData(context, jsonData);
Read: String json = MyJSON.getData(context);
import android.content.Context;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
/**
* Created by Pratik.
*/
public class MyJSON {
static String fileName = "myBlog.json";
public static void saveData(Context context, String mJsonResponse) {
try {
FileWriter file = new FileWriter(context.getFilesDir().getPath() + "/" + fileName);
file.write(mJsonResponse);
file.flush();
file.close();
} catch (IOException e) {
Log.e("TAG", "Error in Writing: " + e.getLocalizedMessage());
}
}
public static String getData(Context context) {
try {
File f = new File(context.getFilesDir().getPath() + "/" + fileName);
//check whether file exists
FileInputStream is = new FileInputStream(f);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
return new String(buffer);
} catch (IOException e) {
Log.e("TAG", "Error in Reading: " + e.getLocalizedMessage());
return null;
}
}
}
writeChars writes each character as two bytes.
http://docs.oracle.com/javase/6/docs/api/java/io/DataOutputStream.html#writeChars(java.lang.String)
http://docs.oracle.com/javase/6/docs/api/java/io/DataOutputStream.html#writeChar(int)
Writes a char to the underlying output stream as a 2-byte value, high byte first. If no exception is thrown, the counter written is incremented by 2.
Your writing code is the problem. Just use
FileWriter fos = new FileWriter(mypath);
fos.write(response);
Hi have create from window 7 and put that in server.Now i am downloading the file from server into my SD card.but when i start to unzip it show the error,
java.util.zip.ZipException: EOCD not found; not a Zip archive?
the code i have use for unzip is
private void unzipEntry(ZipFile zipfile, ZipEntry entry,
String outputDir) throws IOException {
if (entry.isDirectory()) {
createDir(new File(outputDir, entry.getName()));
return;
}
File outputFile = new File(outputDir, entry.getName());
if (!outputFile.getParentFile().exists()) {
createDir(outputFile.getParentFile());
}
log("Extracting: " + entry);
BufferedInputStream inputStream = new BufferedInputStream(
zipfile.getInputStream(entry));
BufferedOutputStream outputStream = new BufferedOutputStream(
new FileOutputStream(outputFile));
try {
IOUtils.copy(inputStream, outputStream);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
outputStream.close();
inputStream.close();
}
}
But when i directly import the file into ddms it work file.
Can anyone know how to resolve the issue then please help me out.
Thank you.
FileInputStream fin = new FileInputStream(
zipfile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
FileOutputStream fout = new FileOutputStream(
unzippath
+ ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
zin.close();
Try this .. This will solve your problem i guess.
Check the ZipInputStream example given in the doc here.
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipUtil {
public static void unzip(File archive, File path) throws IOException{
ZipInputStream zip = null;
String fileName = null;
try{
if(!path.exists()){
path.mkdirs();
}
zip = new ZipInputStream(new FileInputStream(archive));
ZipEntry zipEntry;
while((zipEntry=zip.getNextEntry()) != null) {
fileName = zipEntry.getName();
final File outputFile = new File(path, fileName);
writeToStream(new BufferedInputStream(zip), new FileOutputStream(outputFile), false);
zip.closeEntry();
}
zip.close();
zip = null;
}finally{
if(zip != null){
try{ zip.close(); } catch(Exception e){}
}
}
}
public static void writeToStream(InputStream in , OutputStream out, boolean closeOnExit) throws IOException
{
byte[] bytes = new byte[2048];
for (int c = in.read(bytes); c != -1; c = in.read(bytes)) {
out.write(bytes,0, c);
}
if(closeOnExit){
in.close();
out.close();
}
}
public static String writeToString(InputStream stream) throws java.io.IOException{
StringBuffer fileData = new StringBuffer(1000);
BufferedReader reader = new BufferedReader(new InputStreamReader(stream,"utf-8"));
char[] buf = new char[1024];
int numRead=0;
while((numRead=reader.read(buf)) != -1){
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
return fileData.toString();
}
}
How to create a file, write data into it and read data from it on Android? If possible provide a code snippet.
I used the following code to create a temporary file for writing bytes. And its working fine.
File file = new File(Environment.getExternalStorageDirectory() + "/" + File.separator + "test.txt");
file.createNewFile();
byte[] data1={1,1,0,0};
//write the bytes in file
if(file.exists())
{
OutputStream fo = new FileOutputStream(file);
fo.write(data1);
fo.close();
System.out.println("file created: "+file);
}
//deleting the file
file.delete();
System.out.println("file deleted");
From here: http://www.anddev.org/working_with_files-t115.html
//Writing a file...
try {
// catches IOException below
final String TESTSTRING = new String("Hello Android");
/* We have to use the openFileOutput()-method
* the ActivityContext provides, to
* protect your file from others and
* This is done for security-reasons.
* We chose MODE_WORLD_READABLE, because
* we have nothing to hide in our file */
FileOutputStream fOut = openFileOutput("samplefile.txt",
MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
// Write the string to the file
osw.write(TESTSTRING);
/* ensure that everything is
* really written out and close */
osw.flush();
osw.close();
//Reading the file back...
/* We have to use the openFileInput()-method
* the ActivityContext provides.
* Again for security reasons with
* openFileInput(...) */
FileInputStream fIn = openFileInput("samplefile.txt");
InputStreamReader isr = new InputStreamReader(fIn);
/* Prepare a char-Array that will
* hold the chars we read back in. */
char[] inputBuffer = new char[TESTSTRING.length()];
// Fill the Buffer with data from the file
isr.read(inputBuffer);
// Transform the chars to a String
String readString = new String(inputBuffer);
// Check if we read back the same chars that we had written out
boolean isTheSame = TESTSTRING.equals(readString);
Log.i("File Reading stuff", "success = " + isTheSame);
} catch (IOException ioe)
{ioe.printStackTrace();}
I decided to write a class from this thread that may be helpful to others. Note that this is currently intended to write in the "files" directory only (e.g. does not write to "sdcard" paths).
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import android.content.Context;
public class AndroidFileFunctions {
public static String getFileValue(String fileName, Context context) {
try {
StringBuffer outStringBuf = new StringBuffer();
String inputLine = "";
/*
* We have to use the openFileInput()-method the ActivityContext
* provides. Again for security reasons with openFileInput(...)
*/
FileInputStream fIn = context.openFileInput(fileName);
InputStreamReader isr = new InputStreamReader(fIn);
BufferedReader inBuff = new BufferedReader(isr);
while ((inputLine = inBuff.readLine()) != null) {
outStringBuf.append(inputLine);
outStringBuf.append("\n");
}
inBuff.close();
return outStringBuf.toString();
} catch (IOException e) {
return null;
}
}
public static boolean appendFileValue(String fileName, String value,
Context context) {
return writeToFile(fileName, value, context, Context.MODE_APPEND);
}
public static boolean setFileValue(String fileName, String value,
Context context) {
return writeToFile(fileName, value, context,
Context.MODE_WORLD_READABLE);
}
public static boolean writeToFile(String fileName, String value,
Context context, int writeOrAppendMode) {
// just make sure it's one of the modes we support
if (writeOrAppendMode != Context.MODE_WORLD_READABLE
&& writeOrAppendMode != Context.MODE_WORLD_WRITEABLE
&& writeOrAppendMode != Context.MODE_APPEND) {
return false;
}
try {
/*
* We have to use the openFileOutput()-method the ActivityContext
* provides, to protect your file from others and This is done for
* security-reasons. We chose MODE_WORLD_READABLE, because we have
* nothing to hide in our file
*/
FileOutputStream fOut = context.openFileOutput(fileName,
writeOrAppendMode);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
// Write the string to the file
osw.write(value);
// save and close
osw.flush();
osw.close();
} catch (IOException e) {
return false;
}
return true;
}
public static void deleteFile(String fileName, Context context) {
context.deleteFile(fileName);
}
}
Write to a file test.txt:
String filepath ="/mnt/sdcard/test.txt";
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filepath);
byte[] buffer = "This will be writtent in test.txt".getBytes();
fos.write(buffer, 0, buffer.length);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fos != null)
fos.close();
}
Read from file test.txt:
String filepath ="/mnt/sdcard/test.txt";
FileInputStream fis = null;
try {
fis = new FileInputStream(filepath);
int length = (int) new File(filepath).length();
byte[] buffer = new byte[length];
fis.read(buffer, 0, length);
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fis != null)
fis.close();
}
Note: don't forget to add these two permission in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />