I want to send some data from the database. Currently our SFTP is set up like so (using the apache commons vsf2 library).
try(StandardFileSystemManager manager = new StandardFileSystemManager())
File file = generateFileFromDatabase();
manager.init();
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
// Create localfile object
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
// Create remote file object
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
// Copy local file to sftp server
remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
} catch (Exception ex) {
ex.printStackTrace();
}
However, generateFileFromDatabase() works by invoking the new keyword, as in
return new File();
I don't want this, because this saves a new file in the file system every time generateFileFromDatabase() is called. Is there a way to generate a File() without saving it to the file directory?
Just use
OutputStream os = remoteFile.getContent().getOutputStream();
and then write In a loop to it, just like you would with a local file.
This might be a problem for slow reading/large transfers with long open connections. In that case you might need to pre-produce chunks and write them in multiple appends.
Related
I've been trying to save text to a file in the documents folder in internal storage to be accessed by file manager so i can read it, I've tried several methods including using a writer, but I can't seem to get it to work, I'm not trying to save to external storage, I don't have external storage, only internal, and that's where my documents folder is, so I'm assuming I don't have to bother with the permissions in manifest, I threw in the setReadable just in case but I still can't find it in the documents folder, this is where I'm currently at.
public void writeToFile(String string){
try {
File file = new File(Environment.DIRECTORY_DOCUMENTS, "myFile.txt");
file.setReadable(true);
FileOutputStream stream = new FileOutputStream(file);
stream.write(string.getBytes(string));
stream.flush();
stream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
File file = new File(Environment.DIRECTORY_DOCUMENTS, "myFile.txt");
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "myFile.txt");
I am trying to store key and value pair in properties during server load. After saving, when i checked the .properties file, changes are not there. I am not sure what i missed out.
Not getting any exception or error. updated property changes is not reflected in my .properties file.
My resource file is in "src\main\resources\logintokencache.properties".
Properties prop = new Properties();
InputStream in = getClass().getClassLoader().getResourceAsStream("logintokencache.properties");
try {
prop.load(in);
prop.setProperty("key","value"); // Setting the property
// Tried using Filewriter to store the properties, not worked
File configFile = new File("logintokencache.properties");
FileWriter writer = new FileWriter(configFile);
prop.store(writer, null);
writer.close();
// Tried using FileOutputStream to store the properties, not worked
FileOutputStream output = new FileOutputStream("logintokencache.properties");
prop.store(output, "This is overwrite file");
// Reloaded the properties and also checked, not worked
prop.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logintokencache.properties is stored at your working dir while the file you load is located somewhere at your classpath. So you are loading one file and store it to a different place.
If you are sure that the resource is writeable (that is not always be the case e.g. if it is insight a jar) you can access via
File f = new File(getClass().getClassLoader().getResource("logintokencache.properties").getFile());
FileOutputStream out = new FileOutputStream(f);
prop.store(out, "");
I'm starting to use ttorrent (Turn's BitTorrent Java library) to create a local network synchronized folder.
My goal is to use the torrent protocol do sync large files in nodes hard drives.
But I can't see how to create a new torrent file using ttorrent.
I need to:
1) A new file is added to one node.
2) Other nodes receive the torent file and start do download this file from the first node or pieces from other nodes that already downloaded that file part, speeding the downloading time. This way I can avoid each node to download gigabytes from a server (and wait all day).
I can't go ahead without knowing how to create a torrent file for that new added file (or if a better and smart way exists).
I can have a central point to serve as tracker.
Thanks.
Thanks to fujohnwang
public class Main {
public static void main(String[] args) {
// File parent = new File("d:/echo-insurance.backup");
String sharedFile = "d:/echo-insurance.backup";
try {
Tracker tracker = new Tracker( InetAddress.getLocalHost() );
tracker.start();
System.out.println("Tracker running.");
System.out.println( "create new .torrent metainfo file..." );
Torrent torrent = Torrent.create(new File(sharedFile), tracker.getAnnounceUrl().toURI(), "createdByDarren");
System.out.println("save .torrent to file...");
FileOutputStream fos = new FileOutputStream("d:/seed.torrent");
torrent.save( fos );
fos.close();
} catch ( Exception e ) {
e.printStackTrace();
}
}
}
I want to set data from configures.properties via servlet. configures.properties is locating in WEB-INF/classes. This is how I'm getting data:
public static String getDbPassword() {
Properties prop = new Properties();
try {
// load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
// get the property value
return prop.getProperty("dbPassword");
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
But how to set? This is how I did:
public static void setDbPassword(String str) {
Properties prop = new Properties();
try {
//load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
prop.setProperty("dbPassword", str);
prop.store(new FileOutputStream(INPUT_FILE), null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
But I'm catching java.io.FileNotFoundException after this. I think it happens after prop.store(new FileOutputStream(INPUT_FILE), null);. How should I modify OutputStream?
UPD:
This is how INPUT_FILE looks:
private static final String INPUT_FILE = "/config.properties";
Your INPUT_FILE is a resource path which getResourceAsStream will resolve relative to the classpath, but you're then trying to pass the same string to the FileOutputStream constructor which will try and treat it as an absolute path relative to the root of the filesystem. These are two different locations.
You could use ServletContext.getRealPath("WEB-INF/classes" + INPUT_FILE) to get the path you need for the FileOutputStream.
But the higher level issue here is that you shouldn't assume that your web application will have write access to its WEB-INF, or even that the directory exists on disk at all (e.g. if the app is running directly from a WAR rather than a directory unpacked on disk). If you want to store configuration data that can change then it should go in a file at a known location outside the web app (the location of this file could be an init parameter) where you know you will have read and write permission. This also stops your changes being overwritten when you deploy a new version of the app.
URL url = Configures.class.getResource(INPUT_FILE);
File file = new File(url.toURI());
OutputStream outputStream = new FileOutputStream(file);
...
prop.store(outputStream, null);
Try a FileWriter instead:
Writer writer = new FileWriter(INPUT_FILE);
...
prop.store(writer, null);
Can you try the following:
While reading the file
URL url = classLoader.getResource(INPUT_FILE);
InputStream in = url.openStream();
While writing :
new FileOutputStream(url.toURI().getPath())
Any files in your webapp should be considered read only. If you want mutable data you should use a database or some other data store.
J2EE advises against manipulating local files as it raises issues of clustering, transactions and security among other things.
I'm developing, in Java, an application that has to download from a server to client some very large files. So far I'm using the apache commons-net:
FileOutputStream out = new FileOutputStream(file);
client.retrieveFile(filename, out);
The connection commonly fails before the client finishes downloading the file. I need a way to resume the download of the file from the point where the connection failed, without downloading the whole file again, is it possible?
Things to know:
FileOutputStream has an append parameter, from doc;
#param append if true, then bytes will be written
to the end of the file rather than the beginning
FileClient has setRestartOffset which takes offset as parameter, from doc;
#param offset The offset into the remote file at which to start the
next file transfer. This must be a value greater than or
equal to zero.
We need to combine these two;
boolean downloadFile(String remoteFilePath, String localFilePath) {
try {
File localFile = new File(localFilePath);
if (localFile.exists()) {
// If file exist set append=true, set ofset localFile size and resume
OutputStream fos = new FileOutputStream(localFile, true);
ftp.setRestartOffset(localFile.length());
ftp.retrieveFile(remoteFilePath, fos);
} else {
// Create file with directories if necessary(safer) and start download
localFile.getParentFile().mkdirs();
localFile.createNewFile();
val fos = new FileOutputStream(localFile);
ftp.retrieveFile(remoteFilePath, fos);
}
} catch (Exception ex) {
System.out.println("Could not download file " + ex.getMessage());
return false;
}
}
Commons-net FTPClient supports restarting transfers from a specific offset. You'll have to keep track of what you've successfully retrieved, send the correct offset, and manage appending to the existing file. Assuming, of course, that the FTP server you're connecting to supports the REST (restart) command.